Changeset 70964 in vbox
- Timestamp:
- Feb 11, 2018 9:25:29 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120809
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r70931 r70964 9 9 10 10 /* 11 * Copyright (C) 2006-201 7Oracle Corporation11 * Copyright (C) 2006-2018 Oracle Corporation 12 12 * 13 13 * This file is part of VirtualBox Open Source Edition (OSE), as … … 504 504 * Acquires the TM lock and HDA lock, returns on failure. 505 505 */ 506 #define DEVHDA_LOCK_BOTH_RETURN_VOID(a_pThis ) \506 #define DEVHDA_LOCK_BOTH_RETURN_VOID(a_pThis, a_SD) \ 507 507 do { \ 508 int rcLock = TMTimerLock((a_pThis)->pTimer , VERR_IGNORED); \508 int rcLock = TMTimerLock((a_pThis)->pTimer[a_SD], VERR_IGNORED); \ 509 509 if (rcLock != VINF_SUCCESS) \ 510 510 { \ … … 516 516 { \ 517 517 AssertRC(rcLock); \ 518 TMTimerUnlock((a_pThis)->pTimer ); \518 TMTimerUnlock((a_pThis)->pTimer[a_SD]); \ 519 519 return; \ 520 520 } \ … … 524 524 * Acquires the TM lock and HDA lock, returns on failure. 525 525 */ 526 #define DEVHDA_LOCK_BOTH_RETURN(a_pThis, a_ rcBusy) \526 #define DEVHDA_LOCK_BOTH_RETURN(a_pThis, a_SD, a_rcBusy) \ 527 527 do { \ 528 int rcLock = TMTimerLock((a_pThis)->pTimer , (a_rcBusy)); \528 int rcLock = TMTimerLock((a_pThis)->pTimer[a_SD], (a_rcBusy)); \ 529 529 if (rcLock != VINF_SUCCESS) \ 530 530 return rcLock; \ … … 533 533 { \ 534 534 AssertRC(rcLock); \ 535 TMTimerUnlock((a_pThis)->pTimer ); \535 TMTimerUnlock((a_pThis)->pTimer[a_SD]); \ 536 536 return rcLock; \ 537 537 } \ … … 541 541 * Releases the HDA lock and TM lock. 542 542 */ 543 #define DEVHDA_UNLOCK_BOTH(a_pThis ) \543 #define DEVHDA_UNLOCK_BOTH(a_pThis, a_SD) \ 544 544 do { \ 545 545 PDMCritSectLeave(&(a_pThis)->CritSect); \ 546 TMTimerUnlock((a_pThis)->pTimer ); \546 TMTimerUnlock((a_pThis)->pTimer[a_SD]); \ 547 547 } while (0) 548 548 … … 1306 1306 { 1307 1307 #ifdef IN_RING3 1308 DEVHDA_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); 1308 /* Get the stream descriptor. */ 1309 const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg); 1310 1311 DEVHDA_LOCK_BOTH_RETURN(pThis, uSD, VINF_IOM_R3_MMIO_WRITE); 1309 1312 1310 1313 /* … … 1319 1322 bool fReset = RT_BOOL(u32Value & HDA_SDCTL_SRST); 1320 1323 bool fInReset = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_SDCTL_SRST); 1321 1322 /* Get the stream descriptor. */1323 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg);1324 1324 1325 1325 LogFunc(("[SD%RU8] fRun=%RTbool, fInRun=%RTbool, fReset=%RTbool, fInReset=%RTbool, %R[sdctl]\n", … … 1338 1338 LogFunc(("[SD%RU8] Warning: Invalid stream tag %RU8 specified!\n", uSD, uTag)); 1339 1339 1340 DEVHDA_UNLOCK_BOTH(pThis );1340 DEVHDA_UNLOCK_BOTH(pThis, uSD); 1341 1341 return hdaRegWriteU24(pThis, iReg, u32Value); 1342 1342 } … … 1444 1444 AssertRC(rc2); 1445 1445 1446 rc2 = hdaTimerSet(pThis, TMTimerGet(pThis->pTimer) + pStream->State.cTransferTicks, false /* fForce */);1446 rc2 = hdaTimerSet(pThis, pStream, TMTimerGet(pThis->pTimer[pStream->u8SD]) + pStream->State.cTransferTicks, false /* fForce */); 1447 1447 AssertRC(rc2); 1448 1448 } … … 1472 1472 AssertRC(rc2); 1473 1473 1474 DEVHDA_UNLOCK_BOTH(pThis); 1475 1474 DEVHDA_UNLOCK_BOTH(pThis, uSD); 1476 1475 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 1477 1476 #else /* !IN_RING3 */ … … 1484 1483 { 1485 1484 #ifdef IN_RING3 1486 DEVHDA_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE); 1487 1488 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, STS, iReg)); 1485 const uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, STS, iReg); 1486 1487 DEVHDA_LOCK_BOTH_RETURN(pThis, uSD, VINF_IOM_R3_MMIO_WRITE); 1488 1489 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 1489 1490 if (!pStream) 1490 1491 { … … 1492 1493 HDA_SD_NUM_FROM_REG(pThis, STS, iReg), u32Value)); 1493 1494 1494 DEVHDA_UNLOCK_BOTH(pThis );1495 DEVHDA_UNLOCK_BOTH(pThis, uSD); 1495 1496 return hdaRegWriteU16(pThis, iReg, u32Value); 1496 1497 } … … 1540 1541 #endif 1541 1542 1542 const uint64_t tsNow = TMTimerGet(pThis->pTimer );1543 const uint64_t tsNow = TMTimerGet(pThis->pTimer[uSD]); 1543 1544 Assert(tsNow >= pStream->State.tsTransferLast); 1544 1545 … … 1568 1569 LogRelMax2(64, ("HDA: Stream #%RU8 interrupt lagging behind (expected %uus, got %uus), trying to catch up ...\n", 1569 1570 pStream->u8SD, 1570 (TMTimerGetFreq(pThis->pTimer ) / pThis->u16TimerHz) / 1000,(tsNow - pStream->State.tsTransferLast) / 1000));1571 (TMTimerGetFreq(pThis->pTimer[pStream->u8SD]) / pThis->u16TimerHz) / 1000,(tsNow - pStream->State.tsTransferLast) / 1000)); 1571 1572 1572 1573 cTicksToNext = 0; … … 1587 1588 1588 1589 /* Re-arm the timer. */ 1589 hdaTimerSet(pThis, tsNow + cTicksToNext, false /* fForce */); 1590 LogFunc(("Timer set SD%RU8\n", pStream->u8SD)); 1591 hdaTimerSet(pThis, pStream, tsNow + cTicksToNext, false /* fForce */); 1590 1592 } 1591 1593 } … … 1593 1595 hdaStreamUnlock(pStream); 1594 1596 1595 DEVHDA_UNLOCK_BOTH(pThis );1597 DEVHDA_UNLOCK_BOTH(pThis, uSD); 1596 1598 return VINF_SUCCESS; 1597 1599 #else /* IN_RING3 */ … … 2782 2784 2783 2785 /** 2784 * Main routine for the devicetimer.2786 * Main routine for the stream's timer. 2785 2787 * 2786 * @param pThis HDA state. 2787 */ 2788 static void hdaTimerMain(PHDASTATE pThis) 2789 { 2790 AssertPtrReturnVoid(pThis); 2791 2792 STAM_PROFILE_START(&pThis->StatTimer, a); 2793 2794 DEVHDA_LOCK_BOTH_RETURN_VOID(pThis); 2795 2796 /* Do all transfers from/to DMA. */ 2797 hdaDoTransfers(pThis); 2788 * @param pDevIns Device instance. 2789 * @param pTimer Timer this callback was called for. 2790 * @param pvUser Pointer to associated HDASTREAM. 2791 */ 2792 DECLCALLBACK(void) hdaTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 2793 { 2794 RT_NOREF(pDevIns, pTimer); 2795 2796 PHDASTREAM pStream = (PHDASTREAM)pvUser; 2797 AssertPtr(pStream); 2798 2799 PHDASTATE pThis = pStream->pHDAState; 2800 2801 DEVHDA_LOCK_BOTH_RETURN_VOID(pStream->pHDAState, pStream->u8SD); 2802 2803 hdaStreamUpdate(pStream, true /* fInTimer */); 2798 2804 2799 2805 /* Flag indicating whether to kick the timer again for a 2800 2806 * new data processing round. */ 2801 bool fSinksActive = false; 2802 2803 /* Do we need to kick the timer again? */ 2804 if ( AudioMixerSinkIsActive(pThis->SinkFront.pMixSink) 2805 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND 2806 || AudioMixerSinkIsActive(pThis->SinkCenterLFE.pMixSink) 2807 || AudioMixerSinkIsActive(pThis->SinkRear.pMixSink) 2808 #endif 2809 || AudioMixerSinkIsActive(pThis->SinkLineIn.pMixSink) 2810 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 2811 || AudioMixerSinkIsActive(pThis->SinkMicIn.pMixSink) 2812 #endif 2813 ) 2814 { 2815 fSinksActive = true; 2816 } 2817 2818 bool fTimerScheduled = false; 2819 if ( hdaStreamTransferIsScheduled(hdaGetStreamFromSink(pThis, &pThis->SinkFront)) 2820 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 2821 || hdaStreamTransferIsScheduled(hdaGetStreamFromSink(pThis, &pThis->SinkMicIn)) 2822 #endif 2823 || hdaStreamTransferIsScheduled(hdaGetStreamFromSink(pThis, &pThis->SinkLineIn))) 2824 { 2825 fTimerScheduled = true; 2826 } 2827 2828 Log3Func(("fSinksActive=%RTbool, fTimerScheduled=%RTbool\n", fSinksActive, fTimerScheduled)); 2829 2830 if ( fSinksActive 2807 const bool fSinkActive = AudioMixerSinkIsActive(pStream->pMixSink->pMixSink); 2808 const bool fTimerScheduled = hdaStreamTransferIsScheduled(pStream); 2809 2810 Log3Func(("fSinksActive=%RTbool, fTimerScheduled=%RTbool\n", fSinkActive, fTimerScheduled)); 2811 2812 if ( fSinkActive 2831 2813 && !fTimerScheduled) 2832 2814 { 2833 hdaTimerSet(pThis, TMTimerGet(pThis->pTimer) + TMTimerGetFreq(pThis->pTimer) / pThis->u16TimerHz, true /* fForce */);2834 }2835 2836 DEVHDA_UNLOCK_BOTH(pThis);2837 2838 STAM_PROFILE_STOP(&pThis->StatTimer, a);2815 hdaTimerSet(pThis, pStream, 2816 TMTimerGet(pThis->pTimer[pStream->u8SD]) + TMTimerGetFreq(pThis->pTimer[pStream->u8SD]) / pStream->pHDAState->u16TimerHz, 2817 true /* fForce */); 2818 } 2819 2820 DEVHDA_UNLOCK_BOTH(pThis, pStream->u8SD); 2839 2821 } 2840 2822 … … 3082 3064 3083 3065 /** 3084 * Timer callback which handles the audio data transfers on a periodic basis.3085 *3086 * @param pDevIns Device instance.3087 * @param pTimer Timer which was used when calling this.3088 * @param pvUser User argument as PHDASTATE.3089 */3090 static DECLCALLBACK(void) hdaTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)3091 {3092 RT_NOREF(pDevIns, pTimer);3093 3094 PHDASTATE pThis = (PHDASTATE)pvUser;3095 Assert(pThis == PDMINS_2_DATA(pDevIns, PHDASTATE));3096 AssertPtr(pThis);3097 3098 hdaTimerMain(pThis);3099 }3100 3101 /**3102 3066 * Main routine to perform the actual audio data transfers from the HDA streams 3103 3067 * to the backend(s) and vice versa. … … 3641 3605 int rc = VINF_SUCCESS; 3642 3606 3643 uint64_t tsExpire = 0; /* Timestamp of new timer expiration time / Whether to resume the device timer. */3644 3645 3607 /* 3646 3608 * Enable all previously active streams. … … 3679 3641 hdaStreamRegisterDMAHandlers(pThis, pStream); 3680 3642 #endif 3681 /* Determine the earliest timing slot we need to use. */ 3682 if (tsExpire) 3683 tsExpire = RT_MIN(tsExpire, hdaStreamTransferGetNext(pStream)); 3684 else 3685 tsExpire = hdaStreamTransferGetNext(pStream); 3686 3687 Log2Func(("[SD%RU8] tsExpire=%RU64\n", pStream->u8SD, tsExpire)); 3643 if (hdaStreamTransferIsScheduled(pStream)) 3644 hdaTimerSet(pThis, pStream, hdaStreamTransferGetNext(pStream), true /* fForce */); 3688 3645 3689 3646 /* Also keep track of the currently active streams. */ … … 3691 3648 } 3692 3649 } 3693 }3694 3695 /* Start the timer if one of the above streams were active during taking the saved state. */3696 if (tsExpire)3697 {3698 LogFunc(("Resuming timer at %RU64\n", tsExpire));3699 hdaTimerSet(pThis, tsExpire, true /* fForce */);3700 3650 } 3701 3651 … … 5137 5087 for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i) 5138 5088 { 5089 /* Create the emulation timer (per stream). 5090 * 5091 * Note: Use TMCLOCK_VIRTUAL_SYNC here, as the guest's HDA driver 5092 * relies on exact (virtual) DMA timing and uses DMA Position Buffers 5093 * instead of the LPIB registers. 5094 */ 5095 char szTimer[16]; 5096 RTStrPrintf2(szTimer, sizeof(szTimer), "HDA SD%RU8", i); 5097 5098 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaTimer, &pThis->aStreams[i], 5099 TMTIMER_FLAGS_NO_CRIT_SECT, szTimer, &pThis->pTimer[i]); 5100 AssertRCReturn(rc, rc); 5101 5102 /* Use our own critcal section for the device timer. 5103 * That way we can control more fine-grained when to lock what. */ 5104 rc = TMR3TimerSetCritSect(pThis->pTimer[i], &pThis->CritSect); 5105 AssertRCReturn(rc, rc); 5106 5139 5107 rc = hdaStreamCreate(&pThis->aStreams[i], pThis, i /* u8SD */); 5140 5108 AssertRC(rc); … … 5326 5294 ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 5327 5295 } 5328 }5329 5330 if (RT_SUCCESS(rc))5331 {5332 /* Create the emulation timer.5333 *5334 * Note: Use TMCLOCK_VIRTUAL_SYNC here, as the guest's HDA driver5335 * relies on exact (virtual) DMA timing and uses DMA Position Buffers5336 * instead of the LPIB registers.5337 */5338 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaTimer, pThis,5339 TMTIMER_FLAGS_NO_CRIT_SECT, "HDA Timer", &pThis->pTimer);5340 AssertRCReturn(rc, rc);5341 5342 /* Use our own critcal section for the device timer.5343 * That way we can control more fine-grained when to lock what. */5344 rc = TMR3TimerSetCritSect(pThis->pTimer, &pThis->CritSect);5345 AssertRCReturn(rc, rc);5346 5296 } 5347 5297 -
trunk/src/VBox/Devices/Audio/DevHDA.h
r70252 r70964 5 5 6 6 /* 7 * Copyright (C) 2016-201 7Oracle Corporation7 * Copyright (C) 2016-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 157 157 /** Number of active (running) SDn streams. */ 158 158 uint8_t cStreamsActive; 159 /** The timerfor pumping data thru the attached LUN drivers. */160 PTMTIMERR3 pTimer ;159 /** The stream timers for pumping data thru the attached LUN drivers. */ 160 PTMTIMERR3 pTimer[HDA_MAX_STREAMS]; 161 161 #ifdef VBOX_WITH_STATISTICS 162 162 STAMPROFILE StatTimer; -
trunk/src/VBox/Devices/Audio/DevHDACommon.cpp
r70295 r70964 5 5 6 6 /* 7 * Copyright (C) 2017 Oracle Corporation7 * Copyright (C) 2017-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 404 404 /* Sanity checks. */ 405 405 Assert(cbChunk <= pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff); 406 Assert(cbChunk % pStream->State.cbFrameSize == 0);407 Assert((cbChunk >> 1) >= 1);408 406 409 407 if (pStream->Dbg.Runtime.fEnabled) … … 677 675 * @returns Whether the new expiration time was set or not. 678 676 * @param pThis HDA state. 677 * @param pStream HDA stream to set timer for. 679 678 * @param tsExpire New (virtual) expiration time to set. 680 679 * @param fForce Whether to force setting the expiration time or not. … … 689 688 * Forcing a new expiration time will override the above mechanism. 690 689 */ 691 bool hdaTimerSet(PHDASTATE pThis, uint64_t tsExpire, bool fForce) 692 { 693 AssertPtr(pThis->pTimer); 690 bool hdaTimerSet(PHDASTATE pThis, PHDASTREAM pStream, uint64_t tsExpire, bool fForce) 691 { 692 AssertPtr(pThis); 693 AssertPtr(pStream); 694 694 695 695 uint64_t tsExpireMin = tsExpire; … … 697 697 if (!fForce) 698 698 { 699 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 700 { 701 PHDASTREAM pStream = &pThis->aStreams[i]; 702 703 if (hdaStreamTransferIsScheduled(pStream)) 704 tsExpireMin = RT_MIN(tsExpireMin, hdaStreamTransferGetNext(pStream)); 705 } 706 } 707 708 const uint64_t tsNow = TMTimerGet(pThis->pTimer); 699 if (hdaStreamTransferIsScheduled(pStream)) 700 tsExpireMin = RT_MIN(tsExpireMin, hdaStreamTransferGetNext(pStream)); 701 } 702 703 AssertPtr(pThis->pTimer[pStream->u8SD]); 704 705 #ifdef VBOX_STRICT 706 const uint64_t tsNow = TMTimerGet(pThis->pTimer[pStream->u8SD]); 709 707 710 708 if (tsExpireMin < tsNow) /* Make sure to not go backwards in time. */ 711 709 tsExpireMin = tsNow; 712 713 Log3Func(("u64Epxire=%RU64 -> u64ExpireMin=%RU64, fForce=%RTbool [%s]\n", 714 tsExpire, tsExpireMin, fForce, tsExpireMin == tsExpire ? "OK" : "DELAYED")); 715 716 int rc2 = TMTimerSet(pThis->pTimer, tsExpireMin); 717 AssertRC(rc2); 718 719 return tsExpireMin == tsExpire; 710 #endif 711 712 int rc2 = TMTimerSet(pThis->pTimer[pStream->u8SD], tsExpireMin); 713 AssertRC(rc2); 714 715 return true; 720 716 } 721 717 #endif /* IN_RING3 */ 722 -
trunk/src/VBox/Devices/Audio/DevHDACommon.h
r70250 r70964 5 5 6 6 /* 7 * Copyright (C) 2016-201 7Oracle Corporation7 * Copyright (C) 2016-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 636 636 */ 637 637 #ifdef IN_RING3 638 bool hdaTimerSet(PHDASTATE pThis, uint64_t u64Expire, bool fForce);638 bool hdaTimerSet(PHDASTATE pThis, PHDASTREAM pStream, uint64_t u64Expire, bool fForce); 639 639 #endif /* IN_RING3 */ 640 640 /** @} */ -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r70933 r70964 5 5 6 6 /* 7 * Copyright (C) 2017 Oracle Corporation7 * Copyright (C) 2017-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 53 53 pStream->pMixSink = NULL; 54 54 pStream->pHDAState = pThis; 55 pStream->pTimer = pThis->pTimer[u8SD]; 56 AssertPtr(pStream->pTimer); 55 57 56 58 pStream->State.fInReset = false; … … 60 62 #endif 61 63 62 int rc = RTCircBufCreate(&pStream->State.pCircBuf, _64K); /** @todo Make this configurable. */ 63 if (RT_SUCCESS(rc)) 64 { 65 rc = hdaStreamPeriodCreate(&pStream->State.Period); 66 if (RT_SUCCESS(rc)) 67 rc = RTCritSectInit(&pStream->State.CritSect); 68 } 69 70 int rc2; 64 int rc = RTCritSectInit(&pStream->CritSect); 65 AssertRCReturn(rc, rc); 66 67 rc = RTCircBufCreate(&pStream->State.pCircBuf, _64K); /** @todo Make this configurable. */ 68 AssertRCReturn(rc, rc); 69 70 rc = hdaStreamPeriodCreate(&pStream->State.Period); 71 AssertRCReturn(rc, rc); 71 72 72 73 #ifdef DEBUG 73 rc 2= RTCritSectInit(&pStream->Dbg.CritSect);74 AssertRC (rc2);74 rc = RTCritSectInit(&pStream->Dbg.CritSect); 75 AssertRCReturn(rc, rc); 75 76 #endif 76 77 … … 87 88 88 89 char szPath[RTPATH_MAX + 1]; 89 rc2 = DrvAudioHlpGetFileName(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile,90 0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAG_NONE);90 int rc2 = DrvAudioHlpGetFileName(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile, 91 0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAG_NONE); 91 92 AssertRC(rc2); 92 93 rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAG_NONE, &pStream->Dbg.Runtime.pFileStream); … … 133 134 #endif 134 135 135 if (RTCritSectIsInitialized(&pStream-> State.CritSect))136 { 137 rc2 = RTCritSectDelete(&pStream-> State.CritSect);136 if (RTCritSectIsInitialized(&pStream->CritSect)) 137 { 138 rc2 = RTCritSectDelete(&pStream->CritSect); 138 139 AssertRC(rc2); 139 140 } … … 366 367 pStream->State.cbDMALeft = 0; 367 368 368 const uint64_t cTicksPerHz = TMTimerGetFreq(p This->pTimer) / pThis->u16TimerHz;369 const uint64_t cTicksPerHz = TMTimerGetFreq(pStream->pTimer) / pThis->u16TimerHz; 369 370 370 371 /* Calculate the timer ticks per byte for this stream. */ … … 374 375 /* Calculate timer ticks per transfer. */ 375 376 pStream->State.cTransferTicks = pStream->State.cbTransferChunk * pStream->State.cTicksPerByte; 377 Assert(pStream->State.cTransferTicks); 376 378 377 379 /* Initialize the transfer timestamps. */ … … 626 628 AssertPtrReturn(pStream->pHDAState, false); 627 629 630 const uint64_t tsNow = TMTimerGet(pStream->pTimer); 631 628 632 const bool fScheduled = pStream->State.fRunning 629 633 && ( pStream->State.cTransferPendingInterrupts 630 || pStream->State.tsTransferNext > TMTimerGet(pStream->pHDAState->pTimer)); 631 632 Log3Func(("[SD%RU8] tsTransferNext=%RU64, cTransferPendingInterrupts=%RU8 -> %RTbool\n", 633 pStream->u8SD, pStream->State.tsTransferNext, pStream->State.cTransferPendingInterrupts, fScheduled)); 634 || pStream->State.tsTransferNext > tsNow); 635 636 #ifdef LOG_ENABLED 637 if (fScheduled) 638 { 639 if (pStream->State.cTransferPendingInterrupts) 640 Log3Func(("[SD%RU8] Scheduled (%RU8 IRQs pending)\n", 641 pStream->u8SD, pStream->State.cTransferPendingInterrupts)); 642 else 643 Log3Func(("[SD%RU8] Scheduled in %RU64\n", 644 pStream->u8SD, pStream->State.tsTransferNext - tsNow)); 645 } 646 #endif 634 647 635 648 return fScheduled; … … 708 721 } 709 722 723 Log3Func(("cbWrittenTotal=%RU32\n", cbWrittenTotal)); 724 710 725 if (pcbWritten) 711 726 *pcbWritten = cbWrittenTotal; … … 832 847 } 833 848 834 const uint64_t tsNow = TMTimerGet(p This->pTimer);849 const uint64_t tsNow = TMTimerGet(pStream->pTimer); 835 850 836 851 if (!pStream->State.tsTransferLast) … … 1219 1234 Log3Func(("[SD%RU8] Scheduling timer\n", pStream->u8SD)); 1220 1235 1221 TMTimerUnlock(pThis->pTimer); 1222 1223 hdaTimerSet(pThis, tsTransferNext, false /* fForce */); 1224 1225 TMTimerLock(pThis->pTimer, VINF_SUCCESS); 1236 TMTimerUnlock(pStream->pTimer); 1237 1238 LogFunc(("Timer set SD%RU8\n", pStream->u8SD)); 1239 hdaTimerSet(pStream->pHDAState, pStream, tsTransferNext, false /* fForce */); 1240 1241 TMTimerLock(pStream->pTimer, VINF_SUCCESS); 1226 1242 1227 1243 pStream->State.tsTransferNext = tsTransferNext; … … 1324 1340 { 1325 1341 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1326 if ( fInTimer)1342 if (!fInTimer) 1327 1343 { 1328 1344 #endif … … 1388 1404 } 1389 1405 #endif 1406 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1407 } 1408 else /* fInTimer */ 1409 { 1410 #endif 1411 const uint64_t tsNow = RTTimeMilliTS(); 1412 static uint64_t s_lasti = 0; 1413 if (s_lasti == 0) 1414 s_lasti = tsNow; 1415 1416 if (tsNow - s_lasti >= 10) /** @todo Fix this properly. */ 1417 { 1418 rc2 = hdaStreamAsyncIONotify(pStream); 1419 AssertRC(rc2); 1420 1421 s_lasti = tsNow; 1422 } 1390 1423 1391 1424 const uint32_t cbToTransfer = hdaStreamGetUsed(pStream); … … 1396 1429 } 1397 1430 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1398 } /* fInTimer */1431 } 1399 1432 #endif 1400 1433 } … … 1410 1443 { 1411 1444 AssertPtrReturnVoid(pStream); 1412 int rc2 = RTCritSectEnter(&pStream-> State.CritSect);1445 int rc2 = RTCritSectEnter(&pStream->CritSect); 1413 1446 AssertRC(rc2); 1414 1447 } … … 1423 1456 { 1424 1457 AssertPtrReturnVoid(pStream); 1425 int rc2 = RTCritSectLeave(&pStream-> State.CritSect);1458 int rc2 = RTCritSectLeave(&pStream->CritSect); 1426 1459 AssertRC(rc2); 1427 1460 } -
trunk/src/VBox/Devices/Audio/HDAStream.h
r70594 r70964 5 5 6 6 /* 7 * Copyright (C) 2017 Oracle Corporation7 * Copyright (C) 2017-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 122 122 /** Unused, padding. */ 123 123 uint8_t Padding0[3]; 124 /** Critical section to serialize access. */125 RTCRITSECT CritSect;126 124 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 127 125 /** Asynchronous I/O state members. */ … … 222 220 /** Pointer to HDA sink this stream is attached to. */ 223 221 R3PTRTYPE(PHDAMIXERSINK) pMixSink; 222 /** The stream'S critical section to serialize access. */ 223 RTCRITSECT CritSect; 224 /** Pointer to the stream's timer. */ 225 PTMTIMERR3 pTimer; 224 226 /** Internal state of this stream. */ 225 227 HDASTREAMSTATE State; … … 267 269 /** @} */ 268 270 271 /** @name Timer functions. 272 * @{ 273 */ 274 DECLCALLBACK(void) hdaStreamTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser); 275 /** @} */ 276 277 269 278 /** @name Async I/O stream functions. 270 279 * @{ … … 282 291 283 292 #endif /* IN_RING3 */ 284 285 293 #endif /* !HDA_STREAM_H */ 286 294 -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r70013 r70964 1842 1842 GEN_CHECK_OFF(HDASTREAMSTATE, uCurBDLE); 1843 1843 GEN_CHECK_OFF(HDASTREAMSTATE, fInReset); 1844 GEN_CHECK_OFF(HDASTREAMSTATE, CritSect);1845 1844 GEN_CHECK_OFF(HDASTREAMSTATE, Mapping); 1846 1845 GEN_CHECK_OFF(HDASTREAMSTATE, BDLE); … … 1860 1859 GEN_CHECK_OFF(HDASTREAM, State); 1861 1860 GEN_CHECK_OFF(HDASTREAM, Dbg); 1861 GEN_CHECK_OFF(HDASTREAM, CritSect); 1862 1862 1863 1863 GEN_CHECK_SIZE(HDASTATE); … … 1882 1882 GEN_CHECK_OFF(HDASTATE, fRCEnabled); 1883 1883 #ifndef VBOX_WITH_AUDIO_CALLBACKS 1884 GEN_CHECK_OFF(HDASTATE, pTimer);1885 1884 #endif 1886 1885 #ifdef VBOX_WITH_STATISTICS
Note:
See TracChangeset
for help on using the changeset viewer.