VirtualBox

忽略:
時間撮記:
2014-1-17 下午01:17:34 (11 年 以前)
作者:
vboxsync
訊息:

USBProxy-darwin: Fix high CPU consumption caused by not sleeping in the reap callback. Fix stalling I/O because CFRunLoopStop doesn't always work if the woken thread sleeps in CFRunLoopInMode with the returnAfterSourceHandled flag set to true

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp

    r49817 r50093  
    220220    /** we want to add and remove RunLoopSourceRefs to run loop's of
    221221     * every EMT thread participated in USB processing. */
    222     RTLISTANCHOR        HeadOfRunLoopLst;
     222    RTLISTANCHOR            HeadOfRunLoopLst;
    223223    /** Pointer to the proxy device instance. */
    224224    PUSBPROXYDEV            pProxyDev;
     
    241241    /** The tail of the landed Darwin URBs. */
    242242    PUSBPROXYURBOSX         pTaxingTail;
     243    /* Runloop source for waking up the reaper thread. */
     244    CFRunLoopSourceRef      hRunLoopSrcWakeRef;
     245    /** List of threads used for reaping which can be woken up. */
     246    RTLISTANCHOR            HeadOfRunLoopWakeLst;
    243247    /** Runloop reference of the thread reaping. */
    244248    volatile CFRunLoopRef   hRunLoopReaping;
     
    10661070
    10671071
     1072static DECLCALLBACK(void) usbProxyDarwinPerformWakeup(void *pInfo)
     1073{
     1074    return;
     1075}
     1076
    10681077/* -=-=-=-=-=- The exported methods -=-=-=-=-=- */
    10691078
     
    12611270                                if (irc != kIOReturnNoDevice)
    12621271                                {
    1263                                     //pProxyDev->iActiveCfg = irc == kIOReturnSuccess ? u8Cfg : -1;
    1264                                     pProxyDev->iActiveCfg = -1;
    1265                                     pProxyDev->cIgnoreSetConfigs = 1;
    1266 
    1267                                     pProxyDev->Backend.pv = pDevOsX;
    1268                                     usbProxyDarwinAddRunLoopRef(&pDevOsX->HeadOfRunLoopLst, pDevOsX->RunLoopSrcRef);
    1269                                     return VINF_SUCCESS;        /* return */
     1272                                    CFRunLoopSourceContext CtxRunLoopSource;
     1273                                    CtxRunLoopSource.version = 0;
     1274                                    CtxRunLoopSource.info = NULL;
     1275                                    CtxRunLoopSource.retain = NULL;
     1276                                    CtxRunLoopSource.release = NULL;
     1277                                    CtxRunLoopSource.copyDescription = NULL;
     1278                                    CtxRunLoopSource.equal = NULL;
     1279                                    CtxRunLoopSource.hash = NULL;
     1280                                    CtxRunLoopSource.schedule = NULL;
     1281                                    CtxRunLoopSource.cancel = NULL;
     1282                                    CtxRunLoopSource.perform = usbProxyDarwinPerformWakeup;
     1283                                    pDevOsX->hRunLoopSrcWakeRef = CFRunLoopSourceCreate(NULL, 0, &CtxRunLoopSource);
     1284                                    if (CFRunLoopSourceIsValid(pDevOsX->hRunLoopSrcWakeRef))
     1285                                    {
     1286                                        //pProxyDev->iActiveCfg = irc == kIOReturnSuccess ? u8Cfg : -1;
     1287                                        RTListInit(&pDevOsX->HeadOfRunLoopWakeLst);
     1288                                        pProxyDev->iActiveCfg = -1;
     1289                                        pProxyDev->cIgnoreSetConfigs = 1;
     1290
     1291                                        pProxyDev->Backend.pv = pDevOsX;
     1292                                        usbProxyDarwinAddRunLoopRef(&pDevOsX->HeadOfRunLoopLst, pDevOsX->RunLoopSrcRef);
     1293                                        return VINF_SUCCESS;        /* return */
     1294                                    }
     1295                                    else
     1296                                    {
     1297                                        LogRel(("USB: Device '%s' out of memory allocating runloop source\n", pszAddress));
     1298                                        vrc = VERR_NO_MEMORY;
     1299                                    }
    12701300                                }
    12711301                                vrc = VERR_VUSB_DEVICE_NOT_ATTACHED;
     
    13491379        CFRelease(pDevOsX->RunLoopSrcRef);
    13501380        pDevOsX->RunLoopSrcRef = NULL;
     1381    }
     1382
     1383    if (pDevOsX->hRunLoopSrcWakeRef)
     1384    {
     1385        int rc = usbProxyDarwinRemoveSourceRefFromAllRunLoops(&pDevOsX->HeadOfRunLoopWakeLst, pDevOsX->hRunLoopSrcWakeRef);
     1386        AssertRC(rc);
     1387
     1388        RTListInit((PRTLISTNODE)&pDevOsX->HeadOfRunLoopWakeLst);
     1389
     1390        CFRelease(pDevOsX->hRunLoopSrcWakeRef);
     1391        pDevOsX->hRunLoopSrcWakeRef = NULL;
    13511392    }
    13521393
     
    17631804     */
    17641805    if (RT_LIKELY(irc == kIOReturnSuccess))
     1806    {
     1807        Log(("%s: usbProxyDarwinUrbQueue: success\n", pUrb->pszDesc));
    17651808        return true;
     1809    }
    17661810    switch (irc)
    17671811    {
     
    17931837    PVUSBURB pUrb = NULL;
    17941838    PUSBPROXYDEVOSX pDevOsX = (PUSBPROXYDEVOSX)pProxyDev->Backend.pv;
    1795 
    1796     ASMAtomicXchgPtr((void * volatile *)&pDevOsX->hRunLoopReaping, CFRunLoopGetCurrent());
    1797 
    1798     if (ASMAtomicReadBool(&pDevOsX->fReapingThreadWake))
     1839    CFRunLoopRef hRunLoopRef = CFRunLoopGetCurrent();
     1840
     1841    Assert(!pDevOsX->hRunLoopReaping);
     1842
     1843    if (!CFRunLoopContainsSource(hRunLoopRef, pDevOsX->hRunLoopSrcWakeRef, g_pRunLoopMode))
     1844        usbProxyDarwinAddRunLoopRef(&pDevOsX->HeadOfRunLoopWakeLst, pDevOsX->hRunLoopSrcWakeRef);
     1845
     1846    ASMAtomicXchgPtr((void * volatile *)&pDevOsX->hRunLoopReaping, hRunLoopRef);
     1847
     1848    if (ASMAtomicXchgBool(&pDevOsX->fReapingThreadWake, false))
    17991849    {
    18001850        /* Return immediately. */
     
    18101860
    18111861    if (    !pDevOsX->pTaxingHead
    1812         &&  cMillies
    1813         &&  pDevOsX->pInFlightHead)
     1862        &&  cMillies)
    18141863        CFRunLoopRunInMode(g_pRunLoopMode, cMillies / 1000.0, true);
    18151864
    18161865    ASMAtomicXchgPtr((void * volatile *)&pDevOsX->hRunLoopReaping, NULL);
     1866    ASMAtomicXchgBool(&pDevOsX->fReapingThreadWake, false);
    18171867
    18181868    /*
     
    18401890        LogFlowFunc(("LEAVE: %s: pProxyDev=%s returns %p\n", pUrb->pszDesc, pProxyDev->pUsbIns->pszName, pUrb));
    18411891    else
    1842         LogFlowFunc(("LEAVE: NULL pProxyDev=%s returns NULL", pProxyDev->pUsbIns->pszName));
     1892        LogFlowFunc(("LEAVE: NULL pProxyDev=%s returns NULL\n", pProxyDev->pUsbIns->pszName));
     1893
    18431894    return pUrb;
    18441895}
     
    18911942    PUSBPROXYDEVOSX pDevOsX = (PUSBPROXYDEVOSX)pProxyDev->Backend.pv;
    18921943
     1944    LogFlow(("usbProxyDarwinWakeup: pProxyDev=%p\n", pProxyDev));
     1945
    18931946    ASMAtomicXchgBool(&pDevOsX->fReapingThreadWake, true);
    18941947
    18951948    CFRunLoopRef hRunLoopWake = (CFRunLoopRef)ASMAtomicReadPtr((void * volatile *)&pDevOsX->hRunLoopReaping);
    18961949    if (hRunLoopWake)
    1897         CFRunLoopStop(hRunLoopWake);
    1898 
    1899     ASMAtomicXchgBool(&pDevOsX->fReapingThreadWake, false);
     1950    {
     1951        LogFlow(("usbProxyDarwinWakeup: Waking runloop %p\n", hRunLoopWake));
     1952        CFRunLoopSourceSignal(pDevOsX->hRunLoopSrcWakeRef);
     1953        CFRunLoopWakeUp(hRunLoopWake);
     1954    }
    19001955
    19011956    return VINF_SUCCESS;
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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