VirtualBox

Changeset 65095 in vbox


Ignore:
Timestamp:
Jan 4, 2017 9:10:27 AM (8 years ago)
Author:
vboxsync
Message:

Audio/DevHDA.cpp: Update for async I/O.

File:
1 edited

Legend:

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

    r65070 r65095  
    642642    /** Shutdown indicator. */
    643643    volatile bool         fShutdown;
     644    /** Whether the thread should do any data processing or not. */
     645    volatile bool         fEnabled;
    644646    uint32_t              Padding1;
    645647} HDASTREAMSTATEAIO, *PHDASTREAMSTATEAIO;
     
    10051007static int           hdaStreamUpdate(PHDASTATE pThis, PHDASTREAM pStream);
    10061008DECLINLINE(uint32_t) hdaStreamUpdateLPIB(PHDASTATE pThis, PHDASTREAM pStream, uint32_t u32LPIB);
     1009static void          hdaStreamLock(PHDASTREAM pStream);
     1010static void          hdaStreamUnlock(PHDASTREAM pStream);
    10071011#endif /* IN_RING3 */
    10081012/** @} */
     
    10191023static void              hdaStreamAsyncIOLock(PHDASTREAM pStream);
    10201024static void              hdaStreamAsyncIOUnlock(PHDASTREAM pStream);
     1025static void              hdaStreamAsyncIOEnable(PHDASTREAM pStream, bool fEnable);
    10211026# endif
    10221027#endif
     
    13061311
    13071312/**
     1313 * Locks an HDA stream for serialized access.
     1314 *
     1315 * @returns IPRT status code.
     1316 * @param   pStream             HDA stream to lock.
     1317 */
     1318static void hdaStreamLock(PHDASTREAM pStream)
     1319{
     1320    AssertPtrReturnVoid(pStream);
     1321    int rc2 = RTCritSectEnter(&pStream->State.CritSect);
     1322    AssertRC(rc2);
     1323}
     1324
     1325
     1326/**
     1327 * Unlocks a formerly locked HDA stream.
     1328 *
     1329 * @returns IPRT status code.
     1330 * @param   pStream             HDA stream to unlock.
     1331 */
     1332static void hdaStreamUnlock(PHDASTREAM pStream)
     1333{
     1334    AssertPtrReturnVoid(pStream);
     1335    int rc2 = RTCritSectLeave(&pStream->State.CritSect);
     1336    AssertRC(rc2);
     1337}
     1338
     1339
     1340/**
    13081341 * Fetches the next BDLE to use for a stream.
    13091342 *
     
    18091842    LogFunc(("[SD%RU8]: Reset\n", uSD));
    18101843
    1811     int rc2;
    1812 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
    1813     /*
    1814      * Make sure to destroy the async I/O thread for this stream on reset, as we
    1815      * can't be sure that the same stream is being used in the next cycle
    1816      * (and therefore would leave unused threads around).
    1817      */
    1818     rc2 = hdaStreamAsyncIODestroy(pThis, pStream);
    1819     AssertRC(rc2);
    1820 #endif
    1821 
    18221844    /*
    18231845     * First, reset the internal stream state.
     
    18541876    HDA_STREAM_REG(pThis, BDPL,  uSD) = 0;
    18551877
    1856     rc2 = hdaStreamInit(pThis, pStream, uSD);
     1878    int rc2 = hdaStreamInit(pThis, pStream, uSD);
    18571879    AssertRC(rc2);
    18581880}
     
    18631885    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    18641886
    1865     LogFlowFunc(("[SD%RU8]: fEnable=%RTbool, pMixSink=%p\n", pStream->u8SD, fEnable, pStream->pMixSink));
     1887    LogFunc(("[SD%RU8]: fEnable=%RTbool, pMixSink=%p\n", pStream->u8SD, fEnable, pStream->pMixSink));
    18661888
    18671889    int rc = VINF_SUCCESS;
     1890
     1891    hdaStreamLock(pStream);
    18681892
    18691893#ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
    18701894    hdaStreamAsyncIOLock(pStream);
     1895    hdaStreamAsyncIOEnable(pStream, fEnable);
    18711896#endif
    18721897
     
    18801905            rc = AudioMixerSinkCtl(pStream->pMixSink->pMixSink, enmCmd);
    18811906    }
    1882     else
    1883         rc = VINF_SUCCESS;
    18841907
    18851908#ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     
    18871910#endif
    18881911
    1889     if (RT_FAILURE(rc))
    1890     {
    1891         LogFunc(("Failed with rc=%Rrc\n", rc));
    1892         return rc;
    1893     }
    1894 
     1912    /* Make sure to leave the lock before (eventually) starting the timer. */
     1913    hdaStreamUnlock(pStream);
     1914
     1915#ifndef VBOX_WITH_AUDIO_HDA_CALLBACKS
    18951916    /* Second, see if we need to start or stop the timer. */
    18961917    if (!fEnable)
    1897     {
    1898 # ifndef VBOX_WITH_AUDIO_HDA_CALLBACKS
    18991918        hdaTimerMaybeStop(pThis);
    1900 # endif
    1901     }
    19021919    else
    1903     {
    1904 # ifndef VBOX_WITH_AUDIO_HDA_CALLBACKS
    19051920        hdaTimerMaybeStart(pThis);
    1906 # endif
    1907     }
    1908 
    1909     LogFlowFunc(("u8Strm=%RU8, fEnable=%RTbool, cStreamsActive=%RU8\n", pStream->u8SD, fEnable, pThis->cStreamsActive));
    1910     return VINF_SUCCESS;
    1911 }
    1912 
    1913 static void hdaStreamAssignToSink(PHDASTREAM pStream, PHDAMIXERSINK pMixSink)
    1914 {
    1915     AssertPtrReturnVoid(pStream);
    1916 
    1917     int rc2 = RTCritSectEnter(&pStream->State.CritSect);
    1918     if (RT_SUCCESS(rc2))
    1919     {
    1920         pStream->pMixSink = pMixSink;
    1921 
    1922         rc2 = RTCritSectLeave(&pStream->State.CritSect);
    1923         AssertRC(rc2);
    1924     }
     1921#endif
     1922
     1923    LogFunc(("[SD%RU8]: cStreamsActive=%RU8, rc=%Rrc\n", pStream->u8SD, pThis->cStreamsActive, rc));
     1924    return rc;
    19251925}
    19261926
     
    23712371    AssertPtr(pStream);
    23722372
    2373     /* Note: Do not use hdaRegWriteSDLock() here, as SDnCTL might change the RUN bit. */
    2374     int rc2 = RTCritSectEnter(&pStream->State.CritSect);
    2375     AssertRC(rc2);
    2376 
    23772373    if (fInReset)
    23782374    {
     
    23992395        ASMAtomicXchgBool(&pStream->State.fInReset, true);
    24002396
     2397        hdaStreamLock(pStream);
     2398
    24012399        hdaStreamReset(pThis, pStream);
     2400
     2401        hdaStreamUnlock(pStream);
    24022402    }
    24032403    else
     
    24142414            {
    24152415                /* Make sure to first fetch the current BDLE before enabling the stream below. */
    2416                 rc2 = hdaBDLEFetch(pThis, &pStream->State.BDLE, pStream->u64BDLBase, pStream->State.uCurBDLE);
     2416                int rc2 = hdaBDLEFetch(pThis, &pStream->State.BDLE, pStream->u64BDLBase, pStream->State.uCurBDLE);
    24172417                AssertRC(rc2);
    24182418            }
     
    24222422    }
    24232423
    2424     rc2 = hdaRegWriteU24(pThis, iReg, u32Value);
     2424    int rc2 = hdaRegWriteU24(pThis, iReg, u32Value);
    24252425    AssertRC(rc2);
    24262426
    24272427    /* Make sure to handle interrupts here as well. */
    24282428    hdaProcessInterrupt(pThis);
    2429 
    2430     rc2 = RTCritSectLeave(&pStream->State.CritSect);
    2431     AssertRC(rc2);
    24322429
    24332430    return VINF_SUCCESS; /* Always return success to the MMIO handler. */
     
    36583655 * @param   pThis               HDA state.
    36593656 * @param   enmMixerCtl         Mixer control to remove.
     3657 *
     3658 * @remarks Can be called as a callback by the HDA codec.
    36603659 */
    36613660static DECLCALLBACK(int) hdaMixerRemoveStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl)
     
    37363735 * @param   uSD                 SD stream number (number + 1) to set. Set to 0 for unassign.
    37373736 * @param   uChannel            Channel to set. Only valid if a valid SD stream number is specified.
     3737 *
     3738 * @remarks Can be called as a callback by the HDA codec.
    37383739 */
    37393740static DECLCALLBACK(int) hdaMixerSetStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, uint8_t uSD, uint8_t uChannel)
     
    37713772        if (pStream)
    37723773        {
    3773             pSink->uSD      = uSD;
    3774             pSink->uChannel = uChannel;
    3775 
    3776             /* Make sure that the stream also has this sink set. */
    3777             hdaStreamAssignToSink(pStream, pSink);
     3774            hdaStreamLock(pStream);
     3775
     3776            pSink->uSD        = uSD;
     3777            pSink->uChannel   = uChannel;
     3778            pStream->pMixSink = pSink;
     3779
     3780            hdaStreamUnlock(pStream);
    37783781
    37793782            rc = VINF_SUCCESS;
     
    38003803 * @param   enmMixerCtl         Mixer control to set volume for.
    38013804 * @param   pVol                Pointer to volume data to set.
     3805 *
     3806 * @remarks Can be called as a callback by the HDA codec.
    38023807 */
    38033808static DECLCALLBACK(int) hdaMixerSetVolume(PHDASTATE pThis,
     
    44074412        if (RT_SUCCESS(rc2))
    44084413        {
     4414            if (!pAIO->fEnabled)
     4415            {
     4416                RTCritSectLeave(&pAIO->CritSect);
     4417                continue;
     4418            }
     4419
    44094420            uint32_t cbToProcess;
    44104421            uint32_t cbProcessed = 0;
     
    45664577    AssertRC(rc2);
    45674578}
     4579
     4580/**
     4581 * Enables (resumes) or disables (pauses) the async I/O thread.
     4582 *
     4583 * @param   pStream             HDA stream to enable/disable async I/O thread for.
     4584 * @param   fEnable             Whether to enable or disable the I/O thread.
     4585 *
     4586 * @remarks Does not do locking.
     4587 */
     4588static void hdaStreamAsyncIOEnable(PHDASTREAM pStream, bool fEnable)
     4589{
     4590    PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
     4591    ASMAtomicXchgBool(&pAIO->fEnabled, fEnable);
     4592}
    45684593#endif /* VBOX_WITH_AUDIO_HDA_ASYNC_IO */
    45694594
     
    45864611    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    45874612
     4613    hdaStreamLock(pStream);
     4614
    45884615    PHDAMIXERSINK pSink  = pStream->pMixSink;
    45894616    AssertPtr(pSink);
     
    45934620
    45944621    if (!AudioMixerSinkIsActive(pSink->pMixSink))
     4622    {
     4623        hdaStreamUnlock(pStream);
    45954624        return VINF_SUCCESS;
     4625    }
    45964626
    45974627    Log2Func(("[SD%RU8]\n", pStream->u8SD));
    4598 
    4599     int rc = VINF_SUCCESS;
    46004628
    46014629    bool fDone = false;
     
    47354763    } /* while !fDone */
    47364764
    4737     return rc;
     4765    hdaStreamUnlock(pStream);
     4766
     4767    return VINF_SUCCESS;
    47384768}
    47394769#endif /* IN_RING3 */
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