Changeset 19089 in vbox
- Timestamp:
- Apr 21, 2009 5:31:47 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 46233
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/uvm.h
r13858 r19089 71 71 /** Magic / eye-catcher (UVM_MAGIC). */ 72 72 uint32_t u32Magic; 73 uint32_t uReserved; /**< alignment */ 73 /** The number of virtual CPUs. */ 74 uint32_t cCpus; 74 75 /** The ring-3 mapping of the shared VM structure. */ 75 76 PVM pVM; -
trunk/src/VBox/VMM/VM.cpp
r18927 r19089 137 137 static DECLCALLBACK(int) vmR3Load(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser); 138 138 static DECLCALLBACK(int) vmR3PowerOff(PVM pVM); 139 static void vmR3DestroyUVM(PUVM pUVM );139 static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait); 140 140 static void vmR3AtDtor(PVM pVM); 141 141 static int vmR3AtResetU(PUVM pUVM); … … 371 371 372 372 /* cleanup */ 373 vmR3DestroyUVM(pUVM );373 vmR3DestroyUVM(pUVM, 2000); 374 374 LogFlow(("VMR3Create: returns %Rrc\n", rc)); 375 375 return rc; … … 397 397 AssertReturn(pUVM, VERR_NO_MEMORY); 398 398 pUVM->u32Magic = UVM_MAGIC; 399 pUVM->cCpus = cCPUs; 399 400 400 401 AssertCompile(sizeof(pUVM->vm.s) <= sizeof(pUVM->vm.padding)); … … 1620 1621 1621 1622 /* 1622 * Wait for the EMT thread to terminate. 1623 * Now do the final bit where the heap and VM structures are freed up. 1624 * This will also wait 30 secs for the emulation threads to terminate. 1623 1625 */ 1624 Assert(pUVM->vm.s.fTerminateEMT); 1625 /** @todo SMP */ 1626 rc = RTThreadWait(pUVM->aCpus[0].vm.s.ThreadEMT, 30000, NULL); 1627 AssertMsgRC(rc, ("EMT thread wait failed, rc=%Rrc\n", rc)); 1628 1629 /* 1630 * Now do the final bit where the heap and VM structures are freed up. 1631 */ 1632 vmR3DestroyUVM(pUVM); 1626 vmR3DestroyUVM(pUVM, 30000); 1633 1627 } 1634 1628 … … 1744 1738 1745 1739 /* 1746 * Did EMT call VMR3Destroy and have to do it all?1740 * Did an EMT call VMR3Destroy and end up having to do all the work? 1747 1741 */ 1748 1742 if (pUVM->vm.s.fEMTDoesTheCleanup) 1749 vmR3DestroyUVM(pUVM );1743 vmR3DestroyUVM(pUVM, 30000); 1750 1744 } 1751 1745 … … 1759 1753 * vmR3DestroyFinalBitFromEMT completes. 1760 1754 * 1761 * @param pVM VM Handle. 1762 */ 1763 static void vmR3DestroyUVM(PUVM pUVM) 1764 { 1765 /* 1766 * Terminate the EMT if still running (creation failure only). 1767 */ 1768 if (!pUVM->vm.s.fTerminateEMT) 1769 { 1770 ASMAtomicUoWriteBool(&pUVM->vm.s.fTerminateEMT, true); 1755 * @param pVM VM Handle. 1756 * @param cMilliesEMTWait The number of milliseconds to wait for the emulation 1757 * threads. 1758 */ 1759 static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait) 1760 { 1761 /* 1762 * Signal termination of each the emulation threads and 1763 * wait for them to complete. 1764 */ 1765 /* Signal them. */ 1766 ASMAtomicUoWriteBool(&pUVM->vm.s.fTerminateEMT, true); 1767 for (VMCPUID i = 0; i < pUVM->cCpus; i++) 1768 { 1769 ASMAtomicUoWriteBool(&pUVM->aCpus[i].vm.s.fTerminateEMT, true); 1771 1770 if (pUVM->pVM) 1771 VM_FF_SET(pUVM->pVM, VM_FF_TERMINATE); 1772 VMR3NotifyFFU(pUVM, false); 1773 if (pUVM->aCpus[i].vm.s.EventSemWait != NIL_RTSEMEVENT) /** @todo remove test when we start initializing it! */ 1774 RTSemEventSignal(pUVM->aCpus[i].vm.s.EventSemWait); 1775 } 1776 RTSemEventSignal(pUVM->vm.s.EventSemWait); 1777 1778 /* Wait for them. */ 1779 uint64_t NanoTS = RTTimeNanoTS(); 1780 RTTHREAD hSelf = RTThreadSelf(); 1781 ASMAtomicUoWriteBool(&pUVM->vm.s.fTerminateEMT, true); 1782 for (VMCPUID i = 0; i < pUVM->cCpus; i++) 1783 { 1784 RTTHREAD hThread = pUVM->aCpus[i].vm.s.ThreadEMT; 1785 if ( hThread != NIL_RTTHREAD 1786 && hThread != hSelf) 1772 1787 { 1773 VM_FF_SET(pUVM->pVM, VM_FF_TERMINATE); 1774 VMR3NotifyFF(pUVM->pVM, false); 1788 uint64_t cMilliesElapsed = (RTTimeNanoTS() - NanoTS) / 1000000; 1789 int rc2 = RTThreadWait(hThread, 1790 cMilliesElapsed < cMilliesEMTWait 1791 ? RT_MAX(cMilliesEMTWait - cMilliesElapsed, 2000) 1792 : 2000, 1793 NULL); 1794 if (rc2 == VERR_TIMEOUT) /* avoid the assertion when debugging. */ 1795 rc2 = RTThreadWait(hThread, 1000, NULL); 1796 AssertLogRelMsgRC(rc2, ("i=%u rc=%Rrc\n", i, rc2)); 1797 if (RT_SUCCESS(rc2)) 1798 pUVM->aCpus[0].vm.s.ThreadEMT = NIL_RTTHREAD; 1775 1799 } 1776 RTSemEventSignal(pUVM->vm.s.EventSemWait); 1777 1778 /** @todo SMP */ 1779 int rc2 = RTThreadWait(pUVM->aCpus[0].vm.s.ThreadEMT, 2000, NULL); 1780 AssertRC(rc2); 1781 } 1800 } 1801 1802 /* Cleanup the semaphores. */ 1803 for (VMCPUID i = 0; i < pUVM->cCpus; i++) 1804 if (pUVM->aCpus[i].vm.s.EventSemWait != NIL_RTSEMEVENT) /** @todo remove test when we start initializing it! */ 1805 { 1806 RTSemEventDestroy(pUVM->aCpus[i].vm.s.EventSemWait); 1807 pUVM->aCpus[i].vm.s.EventSemWait = NIL_RTSEMEVENT; 1808 } 1782 1809 RTSemEventDestroy(pUVM->vm.s.EventSemWait); 1783 1810 pUVM->vm.s.EventSemWait = NIL_RTSEMEVENT;
Note:
See TracChangeset
for help on using the changeset viewer.