Changeset 65004 in vbox for trunk/src/VBox/Devices/Audio/DevHDA.cpp
- Timestamp:
- Dec 23, 2016 4:06:58 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r65003 r65004 1020 1020 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1021 1021 static DECLCALLBACK(int) hdaStreamAsyncIOThread(RTTHREAD hThreadSelf, void *pvUser); 1022 static int hdaStreamAsyncIOCreate(PHDASTATE pThis, PHDASTREAM pStream); 1023 static int hdaStreamAsyncIODestroy(PHDASTATE pThis, PHDASTREAM pStream); 1022 1024 static int hdaStreamAsyncIONotify(PHDASTATE pThis, PHDASTREAM pStream); 1023 1025 static void hdaStreamAsyncIOLock(PHDASTREAM pStream); … … 1703 1705 static int hdaStreamCreate(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD) 1704 1706 { 1705 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1707 RT_NOREF(pThis); 1708 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1706 1709 AssertReturn(uSD <= HDA_MAX_STREAMS, VERR_INVALID_PARAMETER); 1707 1710 … … 1718 1721 rc = RTCircBufCreate(&pStream->State.pCircBuf, _4K); /** @todo Make this configurable. */ 1719 1722 1723 LogFlowFunc(("uSD=%RU8\n", uSD)); 1724 return rc; 1725 } 1726 1727 static 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 1720 1737 #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); 1750 1740 #else 1751 1741 RT_NOREF(pThis); 1752 1742 #endif 1753 1743 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); 1767 1745 AssertRC(rc2); 1768 1746 … … 1772 1750 pStream->State.pCircBuf = NULL; 1773 1751 } 1774 1775 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO1776 /*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 #else1805 RT_NOREF(pThis);1806 #endif1807 1752 1808 1753 LogFlowFuncLeave(); … … 1858 1803 1859 1804 /* 1860 * Setreset state.1805 * Enter reset state. 1861 1806 */ 1862 1807 Assert(ASMAtomicReadBool(&pStream->State.fInReset) == false); /* No nested calls. */ 1863 1808 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 1864 1820 1865 1821 /* … … 1897 1853 HDA_STREAM_REG(pThis, BDPL, uSD) = 0; 1898 1854 1899 intrc2 = hdaStreamInit(pThis, pStream, uSD);1855 rc2 = hdaStreamInit(pThis, pStream, uSD); 1900 1856 AssertRC(rc2); 1901 1857 … … 1914 1870 1915 1871 #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); 1917 1876 #endif 1918 1877 … … 4519 4478 4520 4479 /** 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 */ 4486 static 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 */ 4530 static 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 /** 4521 4563 * Lets the stream's async I/O thread know that there is some data to process. 4522 4564 * … … 4531 4573 } 4532 4574 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 */ 4533 4580 static void hdaStreamAsyncIOLock(PHDASTREAM pStream) 4534 4581 { 4535 4582 PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO; 4583 4584 if (!ASMAtomicReadBool(&pAIO->fStarted)) 4585 return; 4536 4586 4537 4587 int rc2 = RTCritSectEnter(&pAIO->CritSect); … … 4539 4589 } 4540 4590 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 */ 4541 4596 static void hdaStreamAsyncIOUnlock(PHDASTREAM pStream) 4542 4597 { 4543 4598 PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO; 4599 4600 if (!ASMAtomicReadBool(&pAIO->fStarted)) 4601 return; 4544 4602 4545 4603 int rc2 = RTCritSectLeave(&pAIO->CritSect);
Note:
See TracChangeset
for help on using the changeset viewer.