VirtualBox

Ignore:
Timestamp:
Dec 23, 2016 4:06:58 PM (8 years ago)
Author:
vboxsync
Message:

Audio: Start async I/O threads on demand.

File:
1 edited

Legend:

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

    r65003 r65004  
    10201020# ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
    10211021static DECLCALLBACK(int) hdaStreamAsyncIOThread(RTTHREAD hThreadSelf, void *pvUser);
     1022static int               hdaStreamAsyncIOCreate(PHDASTATE pThis, PHDASTREAM pStream);
     1023static int               hdaStreamAsyncIODestroy(PHDASTATE pThis, PHDASTREAM pStream);
    10221024static int               hdaStreamAsyncIONotify(PHDASTATE pThis, PHDASTREAM pStream);
    10231025static void              hdaStreamAsyncIOLock(PHDASTREAM pStream);
     
    17031705static int hdaStreamCreate(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD)
    17041706{
    1705     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     1707    RT_NOREF(pThis);
     1708    AssertPtrReturn(pStream,             VERR_INVALID_POINTER);
    17061709    AssertReturn(uSD <= HDA_MAX_STREAMS, VERR_INVALID_PARAMETER);
    17071710
     
    17181721        rc = RTCircBufCreate(&pStream->State.pCircBuf, _4K); /** @todo Make this configurable. */
    17191722
     1723    LogFlowFunc(("uSD=%RU8\n", uSD));
     1724    return rc;
     1725}
     1726
     1727static void hdaStreamDestroy(PHDASTATE pThis, PHDASTREAM pStream)
     1728{
     1729    AssertPtrReturnVoid(pStream);
     1730
     1731    LogFlowFunc(("[SD%RU8]: Destroying ...\n", pStream->u8SD));
     1732
     1733    hdaStreamMapDestroy(&pStream->State.Mapping);
     1734
     1735    int rc2;
     1736
    17201737#ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
    1721     /*
    1722      * Create async I/O stuff.
    1723      */
    1724     PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
    1725 
    1726     pAIO->fShutdown = false;
    1727 
    1728     if (RT_SUCCESS(rc))
    1729     {
    1730         rc = RTSemEventCreate(&pAIO->Event);
    1731         if (RT_SUCCESS(rc))
    1732         {
    1733             rc = RTCritSectInit(&pAIO->CritSect);
    1734             if (RT_SUCCESS(rc))
    1735             {
    1736                 HDASTREAMTHREADCTX Ctx = { pThis, pStream };
    1737 
    1738                 char szThreadName[64];
    1739                 RTStrPrintf2(szThreadName, sizeof(szThreadName), "hdaAIO%RU8", pStream->u8SD);
    1740 
    1741                 /** @todo Create threads on demand? */
    1742 
    1743                 rc = RTThreadCreate(&pAIO->Thread, hdaStreamAsyncIOThread, &Ctx,
    1744                                     0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, szThreadName);
    1745                 if (RT_SUCCESS(rc))
    1746                     rc = RTThreadUserWait(pAIO->Thread, 10 * 1000 /* 10s timeout */);
    1747             }
    1748         }
    1749     }
     1738    rc2 = hdaStreamAsyncIODestroy(pThis, pStream);
     1739    AssertRC(rc2);
    17501740#else
    17511741    RT_NOREF(pThis);
    17521742#endif
    17531743
    1754     LogFlowFunc(("uSD=%RU8\n", uSD));
    1755     return rc;
    1756 }
    1757 
    1758 static void hdaStreamDestroy(PHDASTATE pThis, PHDASTREAM pStream)
    1759 {
    1760     AssertPtrReturnVoid(pStream);
    1761 
    1762     LogFlowFunc(("[SD%RU8]: Destroying ...\n", pStream->u8SD));
    1763 
    1764     hdaStreamMapDestroy(&pStream->State.Mapping);
    1765 
    1766     int rc2 = RTCritSectDelete(&pStream->State.CritSect);
     1744    rc2 = RTCritSectDelete(&pStream->State.CritSect);
    17671745    AssertRC(rc2);
    17681746
     
    17721750        pStream->State.pCircBuf = NULL;
    17731751    }
    1774 
    1775 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
    1776     /*
    1777      * Destroy async I/O stuff.
    1778      */
    1779     PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
    1780 
    1781     if (ASMAtomicReadBool(&pAIO->fStarted))
    1782     {
    1783         ASMAtomicWriteBool(&pAIO->fShutdown, true);
    1784 
    1785         rc2 = hdaStreamAsyncIONotify(pThis, pStream);
    1786         AssertRC(rc2);
    1787 
    1788         int rcThread;
    1789         rc2 = RTThreadWait(pAIO->Thread, 30 * 1000 /* 30s timeout */, &rcThread);
    1790         LogFunc(("Async I/O thread ended with %Rrc (%Rrc)\n", rc2, rcThread));
    1791 
    1792         if (RT_SUCCESS(rc2))
    1793         {
    1794             rc2 = RTCritSectDelete(&pAIO->CritSect);
    1795             AssertRC(rc2);
    1796 
    1797             rc2 = RTSemEventDestroy(pAIO->Event);
    1798             AssertRC(rc2);
    1799 
    1800             pAIO->fStarted  = false;
    1801             pAIO->fShutdown = false;
    1802         }
    1803     }
    1804 #else
    1805     RT_NOREF(pThis);
    1806 #endif
    18071752
    18081753    LogFlowFuncLeave();
     
    18581803
    18591804    /*
    1860      * Set reset state.
     1805     * Enter reset state.
    18611806     */
    18621807    Assert(ASMAtomicReadBool(&pStream->State.fInReset) == false); /* No nested calls. */
    18631808    ASMAtomicXchgBool(&pStream->State.fInReset, true);
     1809
     1810    int rc2;
     1811#ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     1812    /*
     1813     * Make sure to destroy the async I/O thread for this stream on reset, as we
     1814     * can't be sure that the same stream is being used in the next cycle
     1815     * (and therefore would leave unused threads around).
     1816     */
     1817    rc2 = hdaStreamAsyncIODestroy(pThis, pStream);
     1818    AssertRC(rc2);
     1819#endif
    18641820
    18651821    /*
     
    18971853    HDA_STREAM_REG(pThis, BDPL,  uSD) = 0;
    18981854
    1899     int rc2 = hdaStreamInit(pThis, pStream, uSD);
     1855    rc2 = hdaStreamInit(pThis, pStream, uSD);
    19001856    AssertRC(rc2);
    19011857
     
    19141870
    19151871#ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
    1916     hdaStreamAsyncIOLock(pStream);
     1872    if (fEnable)
     1873        rc = hdaStreamAsyncIOCreate(pThis, pStream);
     1874    if (RT_SUCCESS(rc))
     1875        hdaStreamAsyncIOLock(pStream);
    19171876#endif
    19181877
     
    45194478
    45204479/**
     4480 * Creates the async I/O thread for a specific HDA audio stream.
     4481 *
     4482 * @returns IPRT status code.
     4483 * @param   pThis               HDA state.
     4484 * @param   pStream             HDA audio stream to create the async I/O thread for.
     4485 */
     4486static int hdaStreamAsyncIOCreate(PHDASTATE pThis, PHDASTREAM pStream)
     4487{
     4488    PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
     4489
     4490    int rc;
     4491
     4492    if (!ASMAtomicReadBool(&pAIO->fStarted))
     4493    {
     4494        pAIO->fShutdown = false;
     4495
     4496        rc = RTSemEventCreate(&pAIO->Event);
     4497        if (RT_SUCCESS(rc))
     4498        {
     4499            rc = RTCritSectInit(&pAIO->CritSect);
     4500            if (RT_SUCCESS(rc))
     4501            {
     4502                HDASTREAMTHREADCTX Ctx = { pThis, pStream };
     4503
     4504                char szThreadName[64];
     4505                RTStrPrintf2(szThreadName, sizeof(szThreadName), "hdaAIO%RU8", pStream->u8SD);
     4506
     4507                /** @todo Create threads on demand? */
     4508
     4509                rc = RTThreadCreate(&pAIO->Thread, hdaStreamAsyncIOThread, &Ctx,
     4510                                    0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, szThreadName);
     4511                if (RT_SUCCESS(rc))
     4512                    rc = RTThreadUserWait(pAIO->Thread, 10 * 1000 /* 10s timeout */);
     4513            }
     4514        }
     4515    }
     4516    else
     4517        rc = VINF_SUCCESS;
     4518
     4519    LogFunc(("[SD%RU8]: Returning %Rrc\n", pStream->u8SD, rc));
     4520    return rc;
     4521}
     4522
     4523/**
     4524 * Destroys the async I/O thread of a specific HDA audio stream.
     4525 *
     4526 * @returns IPRT status code.
     4527 * @param   pThis               HDA state.
     4528 * @param   pStream             HDA audio stream to destroy the async I/O thread for.
     4529 */
     4530static int hdaStreamAsyncIODestroy(PHDASTATE pThis, PHDASTREAM pStream)
     4531{
     4532    PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
     4533
     4534    if (!ASMAtomicReadBool(&pAIO->fStarted))
     4535        return VINF_SUCCESS;
     4536
     4537    ASMAtomicWriteBool(&pAIO->fShutdown, true);
     4538
     4539    int rc = hdaStreamAsyncIONotify(pThis, pStream);
     4540    AssertRC(rc);
     4541
     4542    int rcThread;
     4543    rc = RTThreadWait(pAIO->Thread, 30 * 1000 /* 30s timeout */, &rcThread);
     4544    LogFunc(("Async I/O thread ended with %Rrc (%Rrc)\n", rc, rcThread));
     4545
     4546    if (RT_SUCCESS(rc))
     4547    {
     4548        rc = RTCritSectDelete(&pAIO->CritSect);
     4549        AssertRC(rc);
     4550
     4551        rc = RTSemEventDestroy(pAIO->Event);
     4552        AssertRC(rc);
     4553
     4554        pAIO->fStarted  = false;
     4555        pAIO->fShutdown = false;
     4556    }
     4557
     4558    LogFunc(("[SD%RU8]: Returning %Rrc\n", pStream->u8SD, rc));
     4559    return rc;
     4560}
     4561
     4562/**
    45214563 * Lets the stream's async I/O thread know that there is some data to process.
    45224564 *
     
    45314573}
    45324574
     4575/**
     4576 * Locks the async I/O thread of a specific HDA audio stream.
     4577 *
     4578 * @param   pStream             HDA stream to lock async I/O thread for.
     4579 */
    45334580static void hdaStreamAsyncIOLock(PHDASTREAM pStream)
    45344581{
    45354582    PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
     4583
     4584    if (!ASMAtomicReadBool(&pAIO->fStarted))
     4585        return;
    45364586
    45374587    int rc2 = RTCritSectEnter(&pAIO->CritSect);
     
    45394589}
    45404590
     4591/**
     4592 * Unlocks the async I/O thread of a specific HDA audio stream.
     4593 *
     4594 * @param   pStream             HDA stream to unlock async I/O thread for.
     4595 */
    45414596static void hdaStreamAsyncIOUnlock(PHDASTREAM pStream)
    45424597{
    45434598    PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
     4599
     4600    if (!ASMAtomicReadBool(&pAIO->fStarted))
     4601        return;
    45444602
    45454603    int rc2 = RTCritSectLeave(&pAIO->CritSect);
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