VirtualBox

Changeset 56454 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jun 16, 2015 1:57:21 PM (9 years ago)
Author:
vboxsync
Message:

Commit r100743 and r100913 to trunk which should improve pass through of USB sound devices

Location:
trunk/src/VBox/Devices/USB
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/VBox/Devices/USB/DevOHCI.cpp

    r56292 r56454  
    375375
    376376    /** The framer thread. */
    377     R3PTRTYPE(PPDMTHREAD) hThreadFrame;
     377    R3PTRTYPE(PPDMTHREAD)      hThreadFrame;
    378378    /** Event semaphore to interact with the framer thread. */
    379     R3PTRTYPE(RTSEMEVENT) hSemEventFrame;
     379    R3PTRTYPE(RTSEMEVENTMULTI) hSemEventFrame;
    380380    /** Event semaphore to release the thread waiting for the framer thread to stop. */
    381381    R3PTRTYPE(RTSEMEVENTMULTI) hSemEventFrameStopped;
    382382    /** Flag whether the framer thread should processing frames. */
    383     volatile bool         fBusStarted;
     383    volatile bool              fBusStarted;
    384384    /** Alignment. */
    385     uint32_t              Alignment5;
     385    uint32_t                   Alignment5;
    386386    /** How long to wait until the next frame. */
    387     uint64_t              nsWait;
     387    uint64_t                   nsWait;
    388388    /** Critical section to synchronize the framer and URB completion handler. */
    389     RTCRITSECT            CritSect;
     389    RTCRITSECT                 CritSect;
    390390
    391391} OHCI;
     
    22142214    }
    22152215    if (uNewFrameRate != pThis->uFrameRate)
     2216    {
     2217        LogFlow(("Frame rate changed from %u to %u\n", pThis->uFrameRate, uNewFrameRate));
    22162218        ohciCalcTimerIntervals(pThis, uNewFrameRate);
     2219    }
    22172220}
    22182221
     
    26062609    /* Calculate new frame rate and wakeup the . */
    26072610    ohciFramerateCalcNew(pThis);
    2608     RTSemEventSignal(pThis->hSemEventFrame);
     2611    RTSemEventMultiSignal(pThis->hSemEventFrame);
    26092612    RTCritSectLeave(&pThis->CritSect);
    26102613}
     
    29802983    {
    29812984        /* Get validate the previous TD */
    2982         int iInFlightPrev = ohci_in_flight_find(pThis, ITdAddr);
    2983         AssertMsgReturn(iInFlightPrev >= 0, ("ITdAddr=%#RX32\n", ITdAddr), false);
     2985        int iInFlightPrev = ohci_in_flight_find(pThis, ITdAddrPrev);
     2986        AssertMsgReturn(iInFlightPrev >= 0, ("ITdAddr=%#RX32\n", ITdAddrPrev), false);
    29842987        PVUSBURB pUrbPrev = pThis->aInFlight[iInFlightPrev].pUrb;
    29852988        if (ohciHasUrbBeenCanceled(pThis, pUrbPrev, pEd)) /* ensures the copy is correct. */
     
    38703873static DECLCALLBACK(int) ohciR3ThreadFrame(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
    38713874{
    3872     int rc = VINF_SUCCESS;
    38733875    POHCI pThis = (POHCI)pThread->pvUser;
    3874     uint64_t tsNanoStart = 0;
     3876    uint64_t tsBeginServicing = 0;
     3877    uint64_t cFramesProcessed = 0;
    38753878
    38763879    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
    38773880        return VINF_SUCCESS;
    38783881
     3882    tsBeginServicing = RTTimeNanoTS();
     3883    cFramesProcessed = 0;
     3884
    38793885    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    38803886    {
    38813887        while (   !ASMAtomicReadBool(&pThis->fBusStarted)
    3882                && pThread->enmState == PDMTHREADSTATE_RUNNING
    3883                && RT_SUCCESS(rc))
     3888               && pThread->enmState == PDMTHREADSTATE_RUNNING)
    38843889        {
    38853890            /* Signal the waiter that we are stopped now. */
    3886             rc = RTSemEventMultiSignal(pThis->hSemEventFrameStopped);
     3891            int rc = RTSemEventMultiSignal(pThis->hSemEventFrameStopped);
    38873892            AssertRC(rc);
    3888             rc = RTSemEventWait(pThis->hSemEventFrame, RT_INDEFINITE_WAIT);
     3893            rc = RTSemEventMultiReset(pThis->hSemEventFrame);
     3894            AssertRC(rc);
     3895
     3896            /*
     3897             * We have to check that the Bus was not started and the thread state
     3898             * did not change or otherwise we risk hanging here indefinitely
     3899             * if the signaller set the event semaphore before we reset it.
     3900             */
     3901            if (ASMAtomicReadBool(&pThis->fBusStarted) || pThread->enmState != PDMTHREADSTATE_RUNNING)
     3902                break;
     3903
     3904            rc = RTSemEventMultiWait(pThis->hSemEventFrame, RT_INDEFINITE_WAIT);
     3905            AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc), rc);
     3906            tsBeginServicing = RTTimeNanoTS();
     3907            cFramesProcessed = 0;
    38893908        }
    38903909
    3891         AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc), rc);
    38923910        if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING))
    38933911            break;
    38943912
    3895         tsNanoStart = RTTimeNanoTS();
    3896 
    38973913        RTCritSectEnter(&pThis->CritSect);
    38983914
     
    39003916        pThis->fIdle = true;
    39013917
    3902         /* Frame boundary, so do EOF stuff here. */
    3903         bump_frame_number(pThis);
    3904         if ( (pThis->dqic != 0x7) && (pThis->dqic != 0))
    3905             pThis->dqic--;
    3906 
    3907         /* Clean up any URBs that have been removed. */
    3908         ohciCancelOrphanedURBs(pThis);
    3909 
    3910         /* Start the next frame. */
    3911         ohciStartOfFrame(pThis);
     3918        /*
     3919         * Process new frames until we reached the required amount of
     3920         * frames for this service period. We might need to catch up
     3921         * here and process multiple frames at once due to scheduling
     3922         * preempting us. This is required because isochronous transfers
     3923         * have a tight timing requirement.
     3924         */
     3925        uint64_t tsNow = RTTimeNanoTS();
     3926        uint64_t nsWait = 0;
     3927        while (tsBeginServicing + (cFramesProcessed * RT_NS_1MS) < tsNow)
     3928        {
     3929            uint64_t tsNanoStart = RTTimeNanoTS();
     3930            LogFlowFunc(("Starting new frame at ts %llu\n", tsNanoStart));
     3931
     3932            /* Frame boundary, so do EOF stuff here. */
     3933            bump_frame_number(pThis);
     3934            if ( (pThis->dqic != 0x7) && (pThis->dqic != 0))
     3935                pThis->dqic--;
     3936
     3937            /* Clean up any URBs that have been removed. */
     3938            ohciCancelOrphanedURBs(pThis);
     3939
     3940            /* Start the next frame. */
     3941            ohciStartOfFrame(pThis);
     3942            cFramesProcessed++;
     3943
     3944            tsNow = RTTimeNanoTS();
     3945            uint64_t tsFrameNext = tsNanoStart + pThis->nsWait;
     3946
     3947            if (tsFrameNext > tsNow)
     3948            {
     3949                nsWait = tsFrameNext - tsNow;
     3950                LogFlowFunc(("Current frame took %llu nano seconds to finish, we can wait %llu ns for the next frame\n", tsNow - tsNanoStart, nsWait));
     3951                break;
     3952            }
     3953            else if (tsBeginServicing + (cFramesProcessed + 100) * RT_NS_1MS < tsNow)
     3954            {
     3955                /* If we lag to far behind stop trying to catch up. */
     3956                LogRel(("OHCI#%u: Lagging too far behind, not trying to catch up anymore. Expect glitches with USB devices\n",
     3957                        pThis->pDevInsR3->iInstance));
     3958                tsBeginServicing = tsNow;
     3959                cFramesProcessed = 0;
     3960            }
     3961        }
    39123962
    39133963        RTCritSectLeave(&pThis->CritSect);
    39143964
    39153965        /* Wait for the next round. */
    3916         RTMSINTERVAL msWait = (RTMSINTERVAL)(((RTTimeNanoTS() + pThis->nsWait) - tsNanoStart) / 1000000);
    3917         rc = RTSemEventWait(pThis->hSemEventFrame, msWait);
     3966        if (nsWait >= 500 * RT_NS_1US)
     3967        {
     3968            LogFlowFunc(("Going to sleep for at least %llu ns\n", nsWait));
     3969            int rc = RTSemEventMultiWaitEx(pThis->hSemEventFrame, RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_UNINTERRUPTIBLE,
     3970                                           nsWait);
     3971            AssertLogRelMsg(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc));
     3972            RTSemEventMultiReset(pThis->hSemEventFrame);
     3973        }
    39183974    }
    39193975
     
    39313987{
    39323988    POHCI pThis = PDMINS_2_DATA(pDevIns, POHCI);
    3933     return RTSemEventSignal(pThis->hSemEventFrame);
     3989    return RTSemEventMultiSignal(pThis->hSemEventFrame);
    39343990}
    39353991
     
    39373993 * Do frame processing on frame boundary
    39383994 */
    3939 static void ohciFrameBoundaryTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    3940 {
    3941     POHCI pThis = (POHCI)pvUser;
    3942     STAM_PROFILE_START(&pThis->StatTimer, a);
    3943     STAM_PROFILE_STOP(&pThis->StatTimer, a);
     3995static DECLCALLBACK(void) ohciFrameBoundaryTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     3996{
    39443997}
    39453998
     
    39584011    bool fBusActive = ASMAtomicXchgBool(&pThis->fBusStarted, true);
    39594012    if (!fBusActive)
    3960         RTSemEventSignal(pThis->hSemEventFrame);
     4013        RTSemEventMultiSignal(pThis->hSemEventFrame);
    39614014}
    39624015
     
    39734026
    39744027        /* Signal the frame thread to stop. */
    3975         RTSemEventSignal(pThis->hSemEventFrame);
     4028        RTSemEventMultiSignal(pThis->hSemEventFrame);
    39764029
    39774030        /* Wait for signal from the thrad that it stopped. */
     
    56095662        LogFlowFunc(("Bus was active, restart frame thread\n"));
    56105663        ASMAtomicXchgBool(&pThis->fBusStarted, true);
    5611         RTSemEventSignal(pThis->hSemEventFrame);
     5664        RTSemEventMultiSignal(pThis->hSemEventFrame);
    56125665    }
    56135666}
     
    57035756     */
    57045757    if (pThis->hSemEventFrame)
    5705         RTSemEventDestroy(pThis->hSemEventFrame);
     5758        RTSemEventMultiDestroy(pThis->hSemEventFrame);
    57065759    if (pThis->hSemEventFrameStopped)
    57075760        RTSemEventMultiDestroy(pThis->hSemEventFrameStopped);
     
    58745927                                   N_("EHCI: Failed to create critical section"));
    58755928
    5876     rc = RTSemEventCreate(&pThis->hSemEventFrame);
     5929    rc = RTSemEventMultiCreate(&pThis->hSemEventFrame);
    58775930    AssertRCReturn(rc, rc);
    58785931
     
    58865939
    58875940    rc = PDMDevHlpThreadCreate(pDevIns, &pThis->hThreadFrame, pThis, ohciR3ThreadFrame,
    5888                                ohciR3ThreadFrameWakeup, 0, RTTHREADTYPE_IO, "OhciFramer");
     5941                               ohciR3ThreadFrameWakeup, 0, RTTHREADTYPE_TIMER, "OhciFramer");
    58895942    if (RT_FAILURE(rc))
    58905943        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     
    59035956    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCanceledGenUrbs,  STAMTYPE_COUNTER, "/Devices/OHCI/CanceledGenUrbs",  STAMUNIT_OCCURENCES,     "Detected canceled general URBs.");
    59045957    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatDroppedUrbs,      STAMTYPE_COUNTER, "/Devices/OHCI/DroppedUrbs",      STAMUNIT_OCCURENCES,     "Dropped URBs (endpoint halted, or URB canceled).");
    5905     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer,            STAMTYPE_PROFILE, "/Devices/OHCI/Timer",            STAMUNIT_TICKS_PER_CALL, "Profiling ohciFrameBoundaryTimer.");
    59065958#endif
    59075959
  • TabularUnified trunk/src/VBox/Devices/USB/DrvVUSBRootHub.cpp

    r56292 r56454  
    429429     */
    430430    pUrb->enmState = VUSBURBSTATE_ALLOCATED;
     431    pUrb->fCompleting = false;
    431432    pUrb->pszDesc = NULL;
    432433    pUrb->VUsb.pNext = NULL;
     
    598599     * Cancel and reap the URB(s) on an endpoint.
    599600     */
    600     LogFlow(("vusbRhCancelUrbsEp: pRh=%p pUrb=%p\n", pRh));
     601    LogFlow(("vusbRhCancelUrbsEp: pRh=%p pUrb=%p\n", pRh, pUrb));
    601602
    602603    vusbUrbCancelAsync(pUrb, CANCELMODE_UNDO);
  • TabularUnified trunk/src/VBox/Devices/USB/VUSBDevice.cpp

    r56395 r56454  
    10471047     * Iterate the URBs and cancel them.
    10481048     */
    1049     RTCritSectEnter(&pDev->CritSectAsyncUrbs);
    10501049    PVUSBURB pUrb = pDev->pAsyncUrbHead;
    10511050    while (pUrb)
     
    10641063     * Reap any URBs which became ripe during cancel now.
    10651064     */
     1065    RTCritSectEnter(&pDev->CritSectAsyncUrbs);
    10661066    unsigned cReaped;
    10671067    do
  • TabularUnified trunk/src/VBox/Devices/USB/VUSBUrb.cpp

    r56292 r56454  
    977977           || pUrb->enmState == VUSBURBSTATE_CANCELLED);
    978978    if (pUrb->enmState != VUSBURBSTATE_CANCELLED)
     979    {
    979980        pUrb->enmState = VUSBURBSTATE_ALLOCATED;
     981        pUrb->fCompleting = false;
     982    }
    980983    RTCritSectLeave(&pPipe->CritSectCtrl);
    981984
     
    10121015              || pUrb->enmState == VUSBURBSTATE_CANCELLED, ("%d\n", pUrb->enmState));
    10131016
    1014     if (pUrb->VUsb.pDev->hSniffer)
     1017    if (   pUrb->VUsb.pDev
     1018        && pUrb->VUsb.pDev->hSniffer)
    10151019    {
    10161020        int rc = VUSBSnifferRecordEvent(pUrb->VUsb.pDev->hSniffer, pUrb,
     
    12881292     */
    12891293    pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED;
     1294    pExtra->Urb.fCompleting = false;
    12901295}
    12911296
     
    12991304    pExtra->enmStage = CTLSTAGE_SETUP;
    13001305    if (pExtra->Urb.enmState != VUSBURBSTATE_CANCELLED)
     1306    {
    13011307        pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED;
     1308        pExtra->Urb.fCompleting = false;
     1309    }
    13021310}
    13031311
     
    13451353        Assert(pUrb->VUsb.pvFreeCtx == &pExtra->Urb);
    13461354        pUrb->enmState = VUSBURBSTATE_ALLOCATED;
     1355        pUrb->fCompleting = false;
    13471356    }
    13481357}
     
    13941403        pExtra->Urb.u32Magic = VUSBURB_MAGIC;
    13951404        pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED;
     1405        pExtra->Urb.fCompleting = false;
    13961406#ifdef LOG_ENABLED
    13971407        RTStrAPrintf(&pExtra->Urb.pszDesc, "URB %p msg->%p", &pExtra->Urb, pUrb);
     
    14601470        pExtra->pMsg = (PVUSBSETUP)pExtra->Urb.abData;
    14611471        pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED;
     1472        pExtra->Urb.fCompleting = false;
    14621473    }
    14631474
     
    21802191void vusbUrbCancelAsync(PVUSBURB pUrb, CANCELMODE mode)
    21812192{
    2182     int rc = vusbDevIoThreadExec(pUrb->VUsb.pDev, 0 /* fFlags */, (PFNRT)vusbUrbCancelWorker, 2, pUrb, mode);
    2183     AssertRC(rc);
     2193    /* Don't try to cancel the URB when completion is in progress at the moment. */
     2194    if (!ASMAtomicXchgBool(&pUrb->fCompleting, true))
     2195    {
     2196        int rc = vusbDevIoThreadExec(pUrb->VUsb.pDev, 0 /* fFlags */, (PFNRT)vusbUrbCancelWorker, 2, pUrb, mode);
     2197        AssertRC(rc);
     2198    }
    21842199}
    21852200
     
    22002215    {
    22012216        pUrb->enmState = VUSBURBSTATE_REAPED;
    2202         vusbUrbCompletion(pUrb);
     2217        if (!ASMAtomicXchgBool(&pUrb->fCompleting, true))
     2218            vusbUrbCompletion(pUrb);
    22032219    }
    22042220    else if (pUrb->enmState == VUSBURBSTATE_CANCELLED)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette