VirtualBox

Changeset 82404 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Dec 5, 2019 12:36:11 AM (5 years ago)
Author:
vboxsync
Message:

DevHDA/hdaRegWriteSDSTS: Try reduce tiem spend holding the virtual-sync clock lock. More can perhaps be done here, if we could postpone the stream period and IRQ handling. bugref:9218

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevHDA.cpp

    r82403 r82404  
    14191419                                   VINF_SUCCESS);
    14201420
    1421     /**
    1422      * @todo r=bird: Must reduce the time we holding the virtual sync
    1423      *               clock lock here!
    1424      */
    1425     DEVHDA_UNLOCK(pDevIns, pThis);
    1426     DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE);
     1421    /* We only need to take the virtual-sync lock if we want to call
     1422       PDMDevHlpTimerGet or hdaR3TimerSet later.  Only precondition for that
     1423       is that we've got a non-zero ticks-per-transfer value. */
     1424    uint64_t const cTransferTicks = pStream->State.cTransferTicks;
     1425    if (cTransferTicks)
     1426    {
     1427        DEVHDA_UNLOCK(pDevIns, pThis);
     1428        DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE);
     1429    }
    14271430
    14281431    hdaR3StreamLock(pStream);
     
    14331436    HDA_REG_IND(pThis, iReg) &= ~(u32Value & v);
    14341437
     1438/** @todo r=bird: Check if we couldn't this stuff involving hdaR3StreamPeriodLock
     1439 *  and IRQs after PDMDevHlpTimerUnlockClock. */
     1440
     1441    /*
     1442     * ...
     1443     */
    14351444    /* Some guests tend to write SDnSTS even if the stream is not running.
    14361445     * So make sure to check if the RUN bit is set first. */
     
    14401449
    14411450    PHDASTREAMPERIOD pPeriod = &pStream->State.Period;
    1442 
    1443     if (hdaR3StreamPeriodLock(pPeriod))
    1444     {
    1445         const bool fNeedsInterrupt = hdaR3StreamPeriodNeedsInterrupt(pPeriod);
    1446         if (fNeedsInterrupt)
    1447             hdaR3StreamPeriodReleaseInterrupt(pPeriod);
    1448 
    1449         if (hdaR3StreamPeriodIsComplete(pPeriod))
    1450         {
    1451             /* Make sure to try to update the WALCLK register if a period is complete.
    1452              * Use the maximum WALCLK value all (active) streams agree to. */
    1453             const uint64_t uWalClkMax = hdaR3WalClkGetMax(pThis);
    1454             if (uWalClkMax > hdaWalClkGetCurrent(pThis))
    1455                 hdaR3WalClkSet(pThis, uWalClkMax, false /* fForce */);
    1456 
    1457             hdaR3StreamPeriodEnd(pPeriod);
    1458 
    1459             if (fRunning)
    1460                 hdaR3StreamPeriodBegin(pPeriod, hdaWalClkGetCurrent(pThis) /* Use current wall clock time */);
    1461         }
    1462 
    1463         hdaR3StreamPeriodUnlock(pPeriod); /* Unlock before processing interrupt. */
    1464     }
     1451    hdaR3StreamPeriodLock(pPeriod);
     1452    if (hdaR3StreamPeriodNeedsInterrupt(pPeriod))
     1453        hdaR3StreamPeriodReleaseInterrupt(pPeriod);
     1454    if (hdaR3StreamPeriodIsComplete(pPeriod))
     1455    {
     1456        /* Make sure to try to update the WALCLK register if a period is complete.
     1457         * Use the maximum WALCLK value all (active) streams agree to. */
     1458        const uint64_t uWalClkMax = hdaR3WalClkGetMax(pThis);
     1459        if (uWalClkMax > hdaWalClkGetCurrent(pThis))
     1460            hdaR3WalClkSet(pThis, uWalClkMax, false /* fForce */);
     1461
     1462        hdaR3StreamPeriodEnd(pPeriod);
     1463
     1464        if (fRunning)
     1465            hdaR3StreamPeriodBegin(pPeriod, hdaWalClkGetCurrent(pThis) /* Use current wall clock time */);
     1466    }
     1467    hdaR3StreamPeriodUnlock(pPeriod); /* Unlock before processing interrupt. */
    14651468
    14661469    HDA_PROCESS_INTERRUPT(pDevIns, pThis);
    14671470
    1468     const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStream->hTimer);
    1469     Assert(tsNow >= pStream->State.tsTransferLast);
    1470 
    1471     const uint64_t cTicksElapsed     = tsNow - pStream->State.tsTransferLast;
     1471    /*
     1472     * ...
     1473     */
     1474    uint64_t cTicksToNext = pStream->State.cTransferTicks;
     1475    Assert(cTicksToNext == cTicksToNext);
     1476    if (cTicksToNext) /* Only do any calculations if the stream currently is set up for transfers. */
     1477    {
     1478        const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStream->hTimer);
     1479        Assert(tsNow >= pStream->State.tsTransferLast);
     1480
     1481        const uint64_t cTicksElapsed     = tsNow - pStream->State.tsTransferLast;
    14721482# ifdef LOG_ENABLED
    1473     const uint64_t cTicksTransferred = pStream->State.cbTransferProcessed * pStream->State.cTicksPerByte;
     1483        const uint64_t cTicksTransferred = pStream->State.cbTransferProcessed * pStream->State.cTicksPerByte;
    14741484# endif
    14751485
    1476     uint64_t cTicksToNext = pStream->State.cTransferTicks;
    1477     if (cTicksToNext) /* Only do any calculations if the stream currently is set up for transfers. */
    1478     {
    14791486        Log3Func(("[SD%RU8] cTicksElapsed=%RU64, cTicksTransferred=%RU64, cTicksToNext=%RU64\n",
    14801487                  pStream->u8SD, cTicksElapsed, cTicksTransferred, cTicksToNext));
     
    15171524    }
    15181525
    1519     PDMDevHlpTimerUnlockClock(pDevIns, pStream->hTimer); /* Caller will unlock pThis->CritSect. */
     1526    if (cTransferTicks)
     1527        PDMDevHlpTimerUnlockClock(pDevIns, pStream->hTimer); /* Caller will unlock pThis->CritSect. */
    15201528    hdaR3StreamUnlock(pStream);
    15211529    return VINF_SUCCESS;
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