VirtualBox

Changeset 23024 in vbox for trunk/src


Ignore:
Timestamp:
Sep 15, 2009 9:30:09 AM (15 years ago)
Author:
vboxsync
Message:

VM.cpp: More state cleanup.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VM.cpp

    r23023 r23024  
    12241224    }
    12251225
    1226     VMSTATE enmVMState = pVM->enmVMState;
     1226    VMSTATE enmVMState = VMR3GetState(pVM);
    12271227    AssertMsgReturn(    enmVMState == VMSTATE_SUSPENDING
    12281228                    ||  enmVMState == VMSTATE_SUSPENDING_LS,
     
    12391239        PDMR3Suspend(pVM);
    12401240
    1241         /* Change to the final state. */
    1242         if (pVM->enmVMState != VMSTATE_SUSPENDING_LS)
    1243             vmR3SetState(pVM, fFatal ? VMSTATE_FATAL_ERROR : VMSTATE_SUSPENDED, VMSTATE_SUSPENDING);
     1241        /*
     1242         * Change to the final state. Live saving makes this a wee bit more
     1243         * complicated than one would like.
     1244         */
     1245        PUVM pUVM = pVM->pUVM;
     1246        RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);
     1247        VMSTATE enmVMState = pVM->enmVMState;
     1248        if (enmVMState != VMSTATE_SUSPENDING_LS)
     1249            vmR3SetStateLocked(pVM, pUVM, fFatal ? VMSTATE_FATAL_ERROR : VMSTATE_SUSPENDED, VMSTATE_SUSPENDING);
    12441250        else if (!fFatal)
    1245             vmR3SetState(pVM, VMSTATE_SUSPENDED_LS, VMSTATE_SUSPENDING_LS);
     1251            vmR3SetStateLocked(pVM, pUVM, VMSTATE_SUSPENDED_LS, VMSTATE_SUSPENDING_LS);
    12461252        else
    12471253        {
    1248             vmR3SetState(pVM, VMSTATE_FATAL_ERROR_LS, VMSTATE_SUSPENDING_LS);
     1254            vmR3SetStateLocked(pVM, pUVM, VMSTATE_FATAL_ERROR_LS, VMSTATE_SUSPENDING_LS);
    12491255            SSMR3Cancel(pVM);
    12501256        }
     1257        RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    12511258    }
    12521259
     
    13371344     *        latter seems easy and perhaps more attractive, the former might be
    13381345     *        better wrt TSC/TM... */
    1339     AssertMsgReturn(pVM->enmVMState == VMSTATE_RUNNING, ("%s\n", VMR3GetStateName(pVM->enmVMState)), VERR_VM_INVALID_VM_STATE);
     1346    AssertMsgReturn(VMR3GetState(pVM) == VMSTATE_RUNNING, ("%s\n", VMR3GetStateName(VMR3GetState(pVM))), VERR_VM_INVALID_VM_STATE);
    13401347    return VINF_EM_RESUME;
    13411348}
     
    14331440    LogFlow(("vmR3SaveLiveStep2: pVM=%p pSSM=%p\n", pVM, pSSM));
    14341441    VM_ASSERT_EMT0(pVM);
    1435     Assert(pVM->enmVMState == VMSTATE_SUSPENDED_LS);
     1442    Assert(VMR3GetState(pVM) == VMSTATE_SUSPENDED_LS);
    14361443
    14371444    int rc = SSMR3LiveDoStep2(pSSM);
     
    16341641
    16351642    /*
    1636      * Request the operation in EMT.
     1643     * Forward the request to EMT(0).
    16371644     */
    16381645    int rc = VMR3ReqCallWaitU(pVM->pUVM, 0 /*idDstCpu*/,
     
    16471654 * cycling thru the other EMTs first.
    16481655 *
    1649  * @returns VBox status code.
     1656 * @returns VBox strict status code.
    16501657 *
    16511658 * @param   pVM     The VM handle.
     
    16631670    if (pVCpu->idCpu == pVM->cCpus - 1)
    16641671    {
    1665         PUVM pUVM = pVM->pUVM;
    1666         RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);
    1667 
    1668         VMSTATE enmStateNew;
    1669         VMSTATE enmStateOld = pVM->enmVMState;
    1670         switch (enmStateOld)
    1671         {
    1672             case VMSTATE_RUNNING:
    1673             case VMSTATE_SUSPENDED:
    1674             case VMSTATE_DEBUGGING:
    1675             case VMSTATE_LOAD_FAILURE:
    1676             case VMSTATE_GURU_MEDITATION:
    1677             case VMSTATE_FATAL_ERROR:
    1678                 enmStateNew = VMSTATE_POWERING_OFF;
    1679                 break;
    1680 
    1681             case VMSTATE_RUNNING_LS:
    1682             case VMSTATE_DEBUGGING_LS:
    1683             case VMSTATE_GURU_MEDITATION_LS:
    1684             case VMSTATE_FATAL_ERROR_LS:
    1685                 enmStateNew = VMSTATE_POWERING_OFF_LS;
    1686                 break;
    1687 
    1688             default:
    1689                 AssertLogRelMsgFailed(("%s\n", VMR3GetStateName(enmStateOld)));
    1690                 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    1691                 return VERR_VM_INVALID_VM_STATE;
    1692         }
    1693 
    1694         vmR3SetStateLocked(pVM, pUVM, enmStateNew, enmStateOld);
    1695         RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
     1672        int rc = vmR3TrySetState(pVM, "VMR3PowerOff", 10,
     1673                                 VMSTATE_POWERING_OFF,    VMSTATE_RUNNING,
     1674                                 VMSTATE_POWERING_OFF,    VMSTATE_SUSPENDED,
     1675                                 VMSTATE_POWERING_OFF,    VMSTATE_DEBUGGING,
     1676                                 VMSTATE_POWERING_OFF,    VMSTATE_LOAD_FAILURE,
     1677                                 VMSTATE_POWERING_OFF,    VMSTATE_GURU_MEDITATION,
     1678                                 VMSTATE_POWERING_OFF,    VMSTATE_FATAL_ERROR,
     1679                                 VMSTATE_POWERING_OFF_LS, VMSTATE_RUNNING_LS,
     1680                                 VMSTATE_POWERING_OFF_LS, VMSTATE_DEBUGGING_LS,
     1681                                 VMSTATE_POWERING_OFF_LS, VMSTATE_GURU_MEDITATION_LS,
     1682                                 VMSTATE_POWERING_OFF_LS, VMSTATE_FATAL_ERROR_LS);
     1683        if (RT_FAILURE(rc))
     1684            return rc;
    16961685    }
    16971686
     
    16991688     * Check the state.
    17001689     */
    1701     VMSTATE const enmVMState = pVM->enmVMState;
     1690    VMSTATE enmVMState = VMR3GetState(pVM);
    17021691    AssertMsgReturn(   enmVMState == VMSTATE_POWERING_OFF
    17031692                    || enmVMState == VMSTATE_POWERING_OFF_LS,
     
    17801769        PUVM pUVM = pVM->pUVM;
    17811770        RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);
    1782         VMSTATE enmVMState = pVM->enmVMState;
     1771        enmVMState = pVM->enmVMState;
    17831772        if (enmVMState == VMSTATE_POWERING_OFF_LS)
    17841773            vmR3SetStateLocked(pVM, pUVM, VMSTATE_OFF_LS, VMSTATE_POWERING_OFF_LS);
     
    17921781
    17931782/**
    1794  * Power Off the VM.
    1795  *
    1796  * @returns 0 on success.
    1797  * @returns VBox error code on failure.
    1798  * @param   pVM     VM which should be destroyed.
     1783 * Power off the VM.
     1784 *
     1785 * @returns VBox status code. When called on EMT, this will be a strict status
     1786 *          code that has to be propagated up the call stack.
     1787 *
     1788 * @param   pVM     The handle of the VM to be powered off.
     1789 *
    17991790 * @thread      Any thread.
    18001791 * @vmstate     Suspended, Running, Guru Meditation, Load Failure
    1801  * @vmstateto   Off
     1792 * @vmstateto   Off or OffLS
    18021793 */
    18031794VMMR3DECL(int)   VMR3PowerOff(PVM pVM)
    18041795{
    18051796    LogFlow(("VMR3PowerOff: pVM=%p\n", pVM));
    1806 
    1807     /*
    1808      * Validate input.
    1809      */
    1810     if (!pVM)
    1811     {
    1812         AssertMsgFailed(("Invalid VM pointer\n"));
    1813         return VERR_INVALID_PARAMETER;
    1814     }
    1815 
    1816     /*
    1817      * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work)
     1797    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     1798
     1799    /*
     1800     * Forward the request to the EMTs in reverse order, making all the other
     1801     * EMTs stop working before EMT(0) comes and does the actual powering off.
    18181802     */
    18191803    int rc = VMR3ReqCallWaitU(pVM->pUVM, VMCPUID_ALL_REVERSE, (PFNRT)vmR3PowerOff, 1, pVM);
     
    23552339    /*
    23562340     * The first EMT will try change the state to resetting.
     2341     * We do the live save cancellation inside the state critsect because it
     2342     * is cleaner and safer.
    23572343     */
    23582344    if (pVCpu->idCpu == pVM->cCpus - 1)
     
    23602346        PUVM pUVM = pVM->pUVM;
    23612347        RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);
    2362         VMSTATE enmStateOld = pVM->enmVMState;
    2363         switch (enmStateOld)
    2364         {
    2365             case VMSTATE_RUNNING:
    2366             case VMSTATE_SUSPENDED:
    2367                 vmR3SetStateLocked(pVM, pUVM, VMSTATE_RESETTING, enmStateOld);
    2368                 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    2369                 break;
    2370 
    2371             case VMSTATE_RUNNING_LS:
    2372                 vmR3SetStateLocked(pVM, pUVM, VMSTATE_RESETTING_LS, enmStateOld);
    2373                 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    2374 
    2375                 SSMR3Cancel(pVM);
    2376                 break;
    2377 
    2378             default:
    2379                 AssertLogRelMsgFailed(("%s\n", VMR3GetStateName(enmStateOld)));
    2380                 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    2381                 return VERR_VM_INVALID_VM_STATE;
    2382         }
     2348        int rc = vmR3TrySetState(pVM, "VMR3Reset", 3,
     2349                                 VMSTATE_RESETTING,     VMSTATE_RUNNING,
     2350                                 VMSTATE_RESETTING,     VMSTATE_SUSPENDED,
     2351                                 VMSTATE_RESETTING_LS,  VMSTATE_RUNNING_LS);
     2352        if (rc == 3)
     2353            SSMR3Cancel(pVM);
     2354        RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
     2355        if (RT_FAILURE(rc))
     2356            return rc;
    23832357    }
    23842358
     
    23862360     * Check the state.
    23872361     */
    2388     VMSTATE enmVMState = pVM->enmVMState;
     2362    VMSTATE enmVMState = VMR3GetState(pVM);
    23892363    AssertLogRelMsgReturn(   enmVMState == VMSTATE_RESETTING
    23902364                          || enmVMState == VMSTATE_RESETTING_LS,
     
    25442518 * @param   enmStateOld         The old (current) state.
    25452519 * @param   enmStateNew         The proposed new state.
     2520 *
     2521 * @remarks The reference for this is found in doc/vp/VMM.vpp, the VMSTATE
     2522 *          diagram (under State Machine Diagram).
    25462523 */
    25472524static bool vmR3ValidateStateTransition(VMSTATE enmStateOld, VMSTATE enmStateNew)
    25482525{
    2549 #ifdef /*VBOX_STRICT*/ DEBUG_bird
     2526#ifdef VBOX_STRICT
    25502527    switch (enmStateOld)
    25512528    {
     
    27302707                   "from destroying the VM. There are restrictions in the way the state changes "
    27312708                   "are propagated up to the EM execution loop and it makes the program flow very "
    2732                    "difficult to follow.\n"));
     2709                   "difficult to follow. (%s, expected %s, old %s)\n",
     2710                   VMR3GetStateName(pVM->enmVMState), VMR3GetStateName(enmStateNew),
     2711                   VMR3GetStateName(enmStateOld)));
    27332712    }
    27342713}
     
    27472726    vmR3ValidateStateTransition(enmStateOld, enmStateNew);
    27482727
    2749     Assert(pVM->enmVMState == enmStateOld);
     2728    AssertMsg(pVM->enmVMState == enmStateOld,
     2729              ("%s != %s\n", VMR3GetStateName(pVM->enmVMState), VMR3GetStateName(enmStateOld)));
    27502730    pUVM->vm.s.enmPrevVMState = enmStateOld;
    27512731    pVM->enmVMState           = enmStateNew;
    27522732
    27532733    vmR3DoAtState(pVM, pUVM, enmStateNew, enmStateOld);
     2734}
     2735
     2736
     2737/**
     2738 * Sets the current VM state.
     2739 *
     2740 * @param   pVM             VM handle.
     2741 * @param   enmStateNew     The new state.
     2742 * @param   enmStateOld     The old state (for asserting only).
     2743 */
     2744static void vmR3SetState(PVM pVM, VMSTATE enmStateNew, VMSTATE enmStateOld)
     2745{
     2746    PUVM pUVM = pVM->pUVM;
     2747    RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);
     2748
     2749    AssertMsg(pVM->enmVMState == enmStateOld,
     2750              ("%s != %s\n", VMR3GetStateName(pVM->enmVMState), VMR3GetStateName(enmStateOld)));
     2751    vmR3SetStateLocked(pVM, pUVM, enmStateNew, pVM->enmVMState);
     2752
     2753    RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    27542754}
    27552755
     
    28102810    if (RT_FAILURE(rc))
    28112811    {
    2812         /* bitch */
     2812        /*
     2813         * Complain about it.
     2814         */
    28132815        if (cTransitions == 1)
    28142816            LogRel(("%s: %s -> %s failed, because the VM state is actually %s\n",
     
    28432845
    28442846
    2845 
    2846 /**
    2847  * Sets the current VM state.
    2848  *
    2849  * @param   pVM             VM handle.
    2850  * @param   enmStateNew     The new state.
    2851  * @param   enmStateOld     The old state (for asserting only).
    2852  */
    2853 static void vmR3SetState(PVM pVM, VMSTATE enmStateNew, VMSTATE enmStateOld)
    2854 {
    2855     PUVM pUVM = pVM->pUVM;
    2856     RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);
    2857 
    2858     AssertMsg(enmStateOld == pVM->enmVMState, ("\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(pVM->enmVMState)));
    2859     vmR3SetStateLocked(pVM, pUVM, enmStateNew, pVM->enmVMState);
    2860 
    2861     RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
    2862 }
    2863 
    2864 
    28652847/**
    28662848 * Flag a guru meditation ... a hack.
     
    36133595    return pUVCpu->vm.s.ThreadEMT;
    36143596}
     3597
Note: See TracChangeset for help on using the changeset viewer.

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