Changeset 88864 in vbox for trunk/src/VBox/Devices
- Timestamp:
- May 4, 2021 4:40:24 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp
r88861 r88864 52 52 *********************************************************************************************************************************/ 53 53 /** Max GetCurrentPadding value we accept (to make sure it's safe to convert to bytes). */ 54 #define VBOX_WASAPI_MAX_PADDING UINT32_C(0x007fffff) 54 #define VBOX_WASAPI_MAX_PADDING UINT32_C(0x007fffff) 55 56 /** Maximum number of cached device configs in each direction. 57 * The number 4 was picked at random. */ 58 #define VBOX_WASAPI_MAX_TOTAL_CONFIG_ENTRIES 4 55 59 56 60 #if 0 57 61 /** @name WM_DRVHOSTAUDIOWAS_XXX - Worker thread messages. 58 62 * @{ */ 59 #define WM_DRVHOSTAUDIOWAS_PURGE_CACHE (WM_APP + 3)63 #define WM_DRVHOSTAUDIOWAS_PURGE_CACHE (WM_APP + 3) 60 64 /** @} */ 61 65 #endif … … 65 69 * @{ */ 66 70 #define DRVHOSTAUDIOWAS_DO_PURGE_CACHE ((uintptr_t)0x49f37300 + 1) 67 #define DRVHOSTAUDIOWAS_DO_STREAM_DEV_SWITCH ((uintptr_t)0x49f37300 + 2) 71 #define DRVHOSTAUDIOWAS_DO_PRUNE_CACHE ((uintptr_t)0x49f37300 + 2) 72 #define DRVHOSTAUDIOWAS_DO_STREAM_DEV_SWITCH ((uintptr_t)0x49f37300 + 3) 68 73 /** @} */ 69 74 … … 114 119 /** Init complete timestamp (just for reference). */ 115 120 uint64_t nsInited; 121 /** When it was last used. */ 122 uint64_t nsLastUsed; 116 123 /** The stringified properties. */ 117 124 char szProps[32]; … … 258 265 * can do cleanups. */ 259 266 RTSEMEVENTMULTI hEvtCachePurge; 267 /** Total number of device config entire for capturing. 268 * This includes in-use ones. */ 269 uint32_t volatile cCacheEntriesIn; 270 /** Total number of device config entire for playback. 271 * This includes in-use ones. */ 272 uint32_t volatile cCacheEntriesOut; 260 273 261 274 #if 0 … … 720 733 * @param pDevCfg Device config entry. Must not be in the list. 721 734 */ 722 static void drvHostAudioWasCacheDestroyDevConfig(PDRVHOSTAUDIOWASCACHEDEVCFG pDevCfg) 723 { 735 static void drvHostAudioWasCacheDestroyDevConfig(PDRVHOSTAUDIOWAS pThis, PDRVHOSTAUDIOWASCACHEDEVCFG pDevCfg) 736 { 737 if (pDevCfg->pDevEntry->enmDir == PDMAUDIODIR_IN) 738 ASMAtomicDecU32(&pThis->cCacheEntriesIn); 739 else 740 ASMAtomicDecU32(&pThis->cCacheEntriesOut); 741 724 742 uint32_t cTypeClientRefs = 0; 725 743 if (pDevCfg->pIAudioCaptureClient) … … 756 774 * @param pDevEntry The device entry. Must not be in the cache! 757 775 */ 758 static void drvHostAudioWasCacheDestroyDevEntry(PDRVHOSTAUDIOWAS CACHEDEV pDevEntry)776 static void drvHostAudioWasCacheDestroyDevEntry(PDRVHOSTAUDIOWAS pThis, PDRVHOSTAUDIOWASCACHEDEV pDevEntry) 759 777 { 760 778 Log8Func(("Destroying cache entry: %p - '%ls'\n", pDevEntry, pDevEntry->wszDevId)); … … 763 781 RTListForEachSafe(&pDevEntry->ConfigList, pDevCfg, pDevCfgNext, DRVHOSTAUDIOWASCACHEDEVCFG, ListEntry) 764 782 { 765 drvHostAudioWasCacheDestroyDevConfig(p DevCfg);783 drvHostAudioWasCacheDestroyDevConfig(pThis, pDevCfg); 766 784 } 767 785 … … 777 795 RTMemFree(pDevEntry); 778 796 Log8Func(("Destroyed cache entry: %p cDevRefs=%u\n", pDevEntry, cDevRefs)); 797 } 798 799 800 /** 801 * Prunes the cache. 802 */ 803 static void drvHostAudioWasCachePrune(PDRVHOSTAUDIOWAS pThis) 804 { 805 /* 806 * Prune each direction separately. 807 */ 808 struct 809 { 810 PDMAUDIODIR enmDir; 811 uint32_t volatile *pcEntries; 812 } aWork[] = { { PDMAUDIODIR_IN, &pThis->cCacheEntriesIn }, { PDMAUDIODIR_OUT, &pThis->cCacheEntriesOut }, }; 813 for (uint32_t iWork = 0; iWork < RT_ELEMENTS(aWork); iWork++) 814 { 815 /* 816 * Remove the least recently used entry till we're below the threshold 817 * or there are no more inactive entries. 818 */ 819 LogFlowFunc(("iWork=%u cEntries=%u\n", iWork, *aWork[iWork].pcEntries)); 820 while (*aWork[iWork].pcEntries > VBOX_WASAPI_MAX_TOTAL_CONFIG_ENTRIES) 821 { 822 RTCritSectEnter(&pThis->CritSectCache); 823 PDRVHOSTAUDIOWASCACHEDEVCFG pLeastRecentlyUsed = NULL; 824 PDRVHOSTAUDIOWASCACHEDEV pDevEntry; 825 RTListForEach(&pThis->CacheHead, pDevEntry, DRVHOSTAUDIOWASCACHEDEV, ListEntry) 826 { 827 if (pDevEntry->enmDir == aWork[iWork].enmDir) 828 { 829 PDRVHOSTAUDIOWASCACHEDEVCFG pHeadCfg = RTListGetFirst(&pDevEntry->ConfigList, 830 DRVHOSTAUDIOWASCACHEDEVCFG, ListEntry); 831 if ( pHeadCfg 832 && (!pLeastRecentlyUsed || pHeadCfg->nsLastUsed < pLeastRecentlyUsed->nsLastUsed)) 833 pLeastRecentlyUsed = pHeadCfg; 834 } 835 } 836 if (pLeastRecentlyUsed) 837 RTListNodeRemove(&pLeastRecentlyUsed->ListEntry); 838 RTCritSectLeave(&pThis->CritSectCache); 839 840 if (!pLeastRecentlyUsed) 841 break; 842 drvHostAudioWasCacheDestroyDevConfig(pThis, pLeastRecentlyUsed); 843 } 844 } 779 845 } 780 846 … … 792 858 if (!pDevEntry) 793 859 break; 794 drvHostAudioWasCacheDestroyDevEntry(p DevEntry);860 drvHostAudioWasCacheDestroyDevEntry(pThis, pDevEntry); 795 861 } 796 862 … … 820 886 { 821 887 RTListNodeRemove(&pDevCfg->ListEntry); 888 pDevCfg->nsLastUsed = RTTimeNanoTS(); 822 889 return pDevCfg; 823 890 } … … 874 941 { 875 942 LogRelMax(64, ("WasAPI: Activate(%ls, IAudioClient) failed: %Rhrc\n", pDevEntry->wszDevId, hrc)); 876 pDevCfg->nsInited = RTTimeNanoTS(); 943 pDevCfg->nsInited = RTTimeNanoTS(); 944 pDevCfg->nsLastUsed = pDevCfg->nsInited; 877 945 return pDevCfg->rcSetup = VERR_AUDIO_STREAM_COULD_NOT_CREATE; 878 946 } … … 944 1012 cDefaultPeriodInNtTicks * 100); 945 1013 pDevCfg->nsInited = RTTimeNanoTS(); 1014 pDevCfg->nsLastUsed = pDevCfg->nsInited; 946 1015 pDevCfg->rcSetup = VINF_SUCCESS; 947 1016 … … 984 1053 if (pClosestMatch) 985 1054 CoTaskMemFree(pClosestMatch); 986 pDevCfg->nsInited = RTTimeNanoTS(); 1055 pDevCfg->nsInited = RTTimeNanoTS(); 1056 pDevCfg->nsLastUsed = 0; 987 1057 Log8Func(("returns VERR_AUDIO_STREAM_COULD_NOT_CREATE (inited in %'RU64 ns)\n", pDevCfg->nsInited - pDevCfg->nsCreated)); 988 1058 return pDevCfg->rcSetup = VERR_AUDIO_STREAM_COULD_NOT_CREATE; … … 1028 1098 PDMAudioPropsToString(&pDevCfg->Props, pDevCfg->szProps, sizeof(pDevCfg->szProps)); 1029 1099 pDevCfg->nsCreated = RTTimeNanoTS(); 1100 pDevCfg->nsLastUsed = pDevCfg->nsCreated; 1101 1102 uint32_t cCacheEntries; 1103 if (pDevCfg->pDevEntry->enmDir == PDMAUDIODIR_IN) 1104 cCacheEntries = ASMAtomicIncU32(&pThis->cCacheEntriesIn); 1105 else 1106 cCacheEntries = ASMAtomicIncU32(&pThis->cCacheEntriesOut); 1107 if (cCacheEntries > VBOX_WASAPI_MAX_TOTAL_CONFIG_ENTRIES) 1108 { 1109 LogFlowFunc(("Trigger cache pruning.\n")); 1110 int rc2 = pThis->pIHostAudioPort->pfnDoOnWorkerThread(pThis->pIHostAudioPort, NULL /*pStream*/, 1111 DRVHOSTAUDIOWAS_DO_PRUNE_CACHE, NULL /*pvUser*/); 1112 AssertRCStmt(rc2, drvHostAudioWasCachePrune(pThis)); 1113 } 1030 1114 1031 1115 if (!fOnWorker) … … 1176 1260 RTCritSectEnter(&pThis->CritSectCache); 1177 1261 RTListAppend(&pDevCfg->pDevEntry->ConfigList, &pDevCfg->ListEntry); 1262 uint32_t const cEntries = pDevCfg->pDevEntry->enmDir == PDMAUDIODIR_IN ? pThis->cCacheEntriesIn : pThis->cCacheEntriesOut; 1178 1263 RTCritSectLeave(&pThis->CritSectCache); 1264 1265 /* Trigger pruning if we're over the threshold. */ 1266 if (cEntries > VBOX_WASAPI_MAX_TOTAL_CONFIG_ENTRIES) 1267 { 1268 LogFlowFunc(("Trigger cache pruning.\n")); 1269 int rc2 = pThis->pIHostAudioPort->pfnDoOnWorkerThread(pThis->pIHostAudioPort, NULL /*pStream*/, 1270 DRVHOSTAUDIOWAS_DO_PRUNE_CACHE, NULL /*pvUser*/); 1271 AssertRCStmt(rc2, drvHostAudioWasCachePrune(pThis)); 1272 } 1179 1273 } 1180 1274 else 1181 1275 { 1182 1276 Log8Func(("IAudioClient::Reset failed (%Rhrc) on %p/'%s', destroying it.\n", hrc, pDevCfg, pDevCfg->szProps)); 1183 drvHostAudioWasCacheDestroyDevConfig(p DevCfg);1277 drvHostAudioWasCacheDestroyDevConfig(pThis, pDevCfg); 1184 1278 } 1185 1279 } … … 1599 1693 LogRelMax(64, ("WasAPI: Failed to set up new device config '%ls:%s' for stream '%s': %Rrc\n", 1600 1694 pDevCfg->pDevEntry->wszDevId, pDevCfg->szProps, pStreamWas->Cfg.szName, rc)); 1601 drvHostAudioWasCacheDestroyDevConfig(p DevCfg);1695 drvHostAudioWasCacheDestroyDevConfig(pThis, pDevCfg); 1602 1696 pThis->pIHostAudioPort->pfnStreamNotifyDeviceChanged(pThis->pIHostAudioPort, &pStreamWas->Core, true /*fReInit*/); 1603 1697 } … … 1620 1714 Assert(pvUser == NULL); 1621 1715 drvHostAudioWasCachePurge(pThis, true /*fOnWorker*/); 1716 break; 1717 1718 case DRVHOSTAUDIOWAS_DO_PRUNE_CACHE: 1719 Assert(pStream == NULL); 1720 Assert(pvUser == NULL); 1721 drvHostAudioWasCachePrune(pThis); 1622 1722 break; 1623 1723
Note:
See TracChangeset
for help on using the changeset viewer.