VirtualBox

Changeset 19089 in vbox


Ignore:
Timestamp:
Apr 21, 2009 5:31:47 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
46233
Message:

VMM: Fixed cleanup issue where the EMT was left behind by always waiting for the EMTs in vmR3DestroyUVM.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/uvm.h

    r13858 r19089  
    7171    /** Magic / eye-catcher (UVM_MAGIC). */
    7272    uint32_t        u32Magic;
    73     uint32_t        uReserved;          /**< alignment */
     73    /** The number of virtual CPUs. */
     74    uint32_t        cCpus;
    7475    /** The ring-3 mapping of the shared VM structure. */
    7576    PVM             pVM;
  • trunk/src/VBox/VMM/VM.cpp

    r18927 r19089  
    137137static DECLCALLBACK(int) vmR3Load(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
    138138static DECLCALLBACK(int) vmR3PowerOff(PVM pVM);
    139 static void              vmR3DestroyUVM(PUVM pUVM);
     139static void              vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait);
    140140static void              vmR3AtDtor(PVM pVM);
    141141static int               vmR3AtResetU(PUVM pUVM);
     
    371371
    372372    /* cleanup */
    373     vmR3DestroyUVM(pUVM);
     373    vmR3DestroyUVM(pUVM, 2000);
    374374    LogFlow(("VMR3Create: returns %Rrc\n", rc));
    375375    return rc;
     
    397397    AssertReturn(pUVM, VERR_NO_MEMORY);
    398398    pUVM->u32Magic = UVM_MAGIC;
     399    pUVM->cCpus = cCPUs;
    399400
    400401    AssertCompile(sizeof(pUVM->vm.s) <= sizeof(pUVM->vm.padding));
     
    16201621
    16211622        /*
    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.
    16231625         */
    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);
    16331627    }
    16341628
     
    17441738
    17451739    /*
    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?
    17471741     */
    17481742    if (pUVM->vm.s.fEMTDoesTheCleanup)
    1749         vmR3DestroyUVM(pUVM);
     1743        vmR3DestroyUVM(pUVM, 30000);
    17501744}
    17511745
     
    17591753 * vmR3DestroyFinalBitFromEMT completes.
    17601754 *
    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 */
     1759static 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);
    17711770        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)
    17721787        {
    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;
    17751799        }
    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        }
    17821809    RTSemEventDestroy(pUVM->vm.s.EventSemWait);
    17831810    pUVM->vm.s.EventSemWait = NIL_RTSEMEVENT;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette