VirtualBox

Changeset 65004 in vbox


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

Audio: Start async I/O threads on demand.

Location:
trunk/src/VBox/Devices/Audio
Files:
2 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);
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r65002 r65004  
    485485#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    486486static DECLCALLBACK(int)  ichac97StreamAsyncIOThread(RTTHREAD hThreadSelf, void *pvUser);
     487static int                ichac97StreamAsyncIOCreate(PAC97STATE pThis, PAC97STREAM pStream);
     488static int                ichac97StreamAsyncIODestroy(PAC97STATE pThis, PAC97STREAM pStream);
    487489static int                ichac97StreamAsyncIONotify(PAC97STATE pThis, PAC97STREAM pStream);
    488490static void               ichac97StreamAsyncIOLock(PAC97STREAM pStream);
     
    633635
    634636#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    635     ichac97StreamAsyncIOLock(pStream);
     637    if (fEnable)
     638        rc = ichac97StreamAsyncIOCreate(pThis, pStream);
     639    if (RT_SUCCESS(rc))
     640        ichac97StreamAsyncIOLock(pStream);
    636641#endif
    637642
     
    708713static int ichac97StreamCreate(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8Strm)
    709714{
     715    RT_NOREF(pThis);
    710716    AssertPtrReturn(pStream, VERR_INVALID_PARAMETER);
     717    /** @todo Validate u8Strm. */
    711718
    712719    LogFunc(("[SD%RU8] pStream=%p\n", u8Strm, pStream));
     
    717724    if (RT_SUCCESS(rc))
    718725        rc = RTCircBufCreate(&pStream->State.pCircBuf, _4K); /** @todo Make this configurable. */
    719 
    720 #ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    721     /*
    722      * Create async I/O stuff.
    723      */
    724     PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
    725 
    726     pAIO->fShutdown = false;
    727 
    728     if (RT_SUCCESS(rc))
    729     {
    730         rc = RTSemEventCreate(&pAIO->Event);
    731         if (RT_SUCCESS(rc))
    732         {
    733             rc = RTCritSectInit(&pAIO->CritSect);
    734             if (RT_SUCCESS(rc))
    735             {
    736                 AC97STREAMTHREADCTX Ctx = { pThis, pStream };
    737 
    738                 char szThreadName[64];
    739                 RTStrPrintf2(szThreadName, sizeof(szThreadName), "ac97AIO%RU8", pStream->u8Strm);
    740 
    741                 /** @todo Create threads on demand? */
    742 
    743                 rc = RTThreadCreate(&pAIO->Thread, ichac97StreamAsyncIOThread, &Ctx,
    744                                     0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, szThreadName);
    745                 if (RT_SUCCESS(rc))
    746                     rc = RTThreadUserWait(pAIO->Thread, 10 * 1000 /* 10s timeout */);
    747             }
    748         }
    749     }
    750 #else
    751     RT_NOREF(pThis);
    752 #endif
    753726
    754727    return rc;
     
    776749
    777750#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    778     /*
    779      * Destroy async I/O stuff.
    780      */
    781     PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
    782 
    783     if (ASMAtomicReadBool(&pAIO->fStarted))
    784     {
    785         ASMAtomicWriteBool(&pAIO->fShutdown, true);
    786 
    787         rc2 = ichac97StreamAsyncIONotify(pThis, pStream);
    788         AssertRC(rc2);
    789 
    790         int rcThread;
    791         rc2 = RTThreadWait(pAIO->Thread, 30 * 1000 /* 30s timeout */, &rcThread);
    792         LogFunc(("Async I/O thread ended with %Rrc (%Rrc)\n", rc2, rcThread));
    793 
    794         if (RT_SUCCESS(rc2))
    795         {
    796             rc2 = RTCritSectDelete(&pAIO->CritSect);
    797             AssertRC(rc2);
    798 
    799             rc2 = RTSemEventDestroy(pAIO->Event);
    800             AssertRC(rc2);
    801 
    802             pAIO->fStarted  = false;
    803             pAIO->fShutdown = false;
    804         }
    805     }
     751    rc2 = ichac97StreamAsyncIODestroy(pThis, pStream);
     752    AssertRC(rc2);
    806753#else
    807754    RT_NOREF(pThis);
     
    10591006
    10601007    return VINF_SUCCESS;
     1008}
     1009
     1010/**
     1011 * Creates the async I/O thread for a specific AC'97 audio stream.
     1012 *
     1013 * @returns IPRT status code.
     1014 * @param   pThis               AC'97 state.
     1015 * @param   pStream             AC'97 audio stream to create the async I/O thread for.
     1016 */
     1017static int ichac97StreamAsyncIOCreate(PAC97STATE pThis, PAC97STREAM pStream)
     1018{
     1019    PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
     1020
     1021    int rc;
     1022
     1023    if (!ASMAtomicReadBool(&pAIO->fStarted))
     1024    {
     1025        pAIO->fShutdown = false;
     1026
     1027        rc = RTSemEventCreate(&pAIO->Event);
     1028        if (RT_SUCCESS(rc))
     1029        {
     1030            rc = RTCritSectInit(&pAIO->CritSect);
     1031            if (RT_SUCCESS(rc))
     1032            {
     1033                AC97STREAMTHREADCTX Ctx = { pThis, pStream };
     1034
     1035                char szThreadName[64];
     1036                RTStrPrintf2(szThreadName, sizeof(szThreadName), "ac97AIO%RU8", pStream->u8Strm);
     1037
     1038                /** @todo Create threads on demand? */
     1039
     1040                rc = RTThreadCreate(&pAIO->Thread, ichac97StreamAsyncIOThread, &Ctx,
     1041                                    0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, szThreadName);
     1042                if (RT_SUCCESS(rc))
     1043                    rc = RTThreadUserWait(pAIO->Thread, 10 * 1000 /* 10s timeout */);
     1044            }
     1045        }
     1046    }
     1047    else
     1048        rc = VINF_SUCCESS;
     1049
     1050    LogFunc(("[SD%RU8]: Returning %Rrc\n", pStream->u8Strm, rc));
     1051    return rc;
     1052}
     1053
     1054/**
     1055 * Destroys the async I/O thread of a specific AC'97 audio stream.
     1056 *
     1057 * @returns IPRT status code.
     1058 * @param   pThis               AC'97 state.
     1059 * @param   pStream             AC'97 audio stream to destroy the async I/O thread for.
     1060 */
     1061static int ichac97StreamAsyncIODestroy(PAC97STATE pThis, PAC97STREAM pStream)
     1062{
     1063    PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
     1064
     1065    if (!ASMAtomicReadBool(&pAIO->fStarted))
     1066        return VINF_SUCCESS;
     1067
     1068    ASMAtomicWriteBool(&pAIO->fShutdown, true);
     1069
     1070    int rc = ichac97StreamAsyncIONotify(pThis, pStream);
     1071    AssertRC(rc);
     1072
     1073    int rcThread;
     1074    rc = RTThreadWait(pAIO->Thread, 30 * 1000 /* 30s timeout */, &rcThread);
     1075    LogFunc(("Async I/O thread ended with %Rrc (%Rrc)\n", rc, rcThread));
     1076
     1077    if (RT_SUCCESS(rc))
     1078    {
     1079        rc = RTCritSectDelete(&pAIO->CritSect);
     1080        AssertRC(rc);
     1081
     1082        rc = RTSemEventDestroy(pAIO->Event);
     1083        AssertRC(rc);
     1084
     1085        pAIO->fStarted  = false;
     1086        pAIO->fShutdown = false;
     1087    }
     1088
     1089    LogFunc(("[SD%RU8]: Returning %Rrc\n", pStream->u8Strm, rc));
     1090    return rc;
    10611091}
    10621092
     
    15491579
    15501580    LogFlowFunc(("[SD%RU8]\n", pStream->u8Strm));
     1581
     1582#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
     1583    /*
     1584     * Make sure to destroy the async I/O thread for this stream on reset, as we
     1585     * can't be sure that the same stream is being used in the next cycle
     1586     * (and therefore would leave unused threads around).
     1587     */
     1588    int rc2 = ichac97StreamAsyncIODestroy(pThis, pStream);
     1589    AssertRC(rc2);
     1590#endif
    15511591
    15521592    if (pStream->State.pCircBuf)
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