69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync/* $Id$ */
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync/** @file
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * This file contains the introduction to Main for developers.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync */
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync/*
3f8dc16a69546ae938abc5b07b62693316cfb0cevboxsync * Copyright (C) 2011-2013 Oracle Corporation
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * available from http://www.virtualbox.org. This file is free software;
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * General Public License (GPL) as published by the Free Software
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync */
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync/** @page pg_main Main API
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * First of all, check out the "Technical background" chapter in the manual, pay
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * attention to the "VirtualBox executables and components" chapter. It lists
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * three processes, (1) VBoxSVC, (2) VirtualBox in manager mode and (3)
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * VirtualBox in VM mode. This will be referred to as (1) server, (2) client
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * and (3) VM process, respectively.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * @section sec_main_walk_thru_suspend IConsole::Pause Walkthru
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * The instigator can be a client (VirtualBox in manager mode, VBoxManage
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * controlvm, web services, ++) or the VM process it self (i.e. you select
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * pause via the menu or the host key short cut).
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * We will not cover the case where the guest triggers a suspend.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * Approximate sequence of events:
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - Client calls IConsole::Pause.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - The COM/XPCOM routes this to the VM process, invoking Console::Pause() in
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * ConsoleImpl.cpp. (The IConsole::Pause method in the client process is a
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * COM/XPCOM stub method which does marshalling+IPC.)
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - Console::Pause validates the Console object state, the VM state and the VM
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * handle.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - Console::Pause calls VMR3Suspend to do the actual suspending.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - VMR3Suspend() in VMM/VMMR3/VM.cpp calls VMMR3EmtRendezvous() to change the
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * VM state synchronously on all EMTs (threads performing as virtual CPUs).
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - VMMR3EmtRendezvous() will first detect that the caller isn't an EMT and
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * use VMR3ReqCallWait() to forward the call to an EMT.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - When VMMR3EmtRendezvous() is called again on an EMT, it will signal the
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * other EMTs by raising a force action flag (VM_FF_EMT_RENDEZVOUS) and then
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * poke them via VMR3NotifyGlobalFFU(). Then wait for them all to arrive.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - The other EMTs will call VMMR3EmtRendezvousFF as soon as they can.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - When all EMTs are there, the calling back of vmR3Suspend() on each CPU in
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * decending order will start.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - When the CPU with the higest ID calls vmR3Suspend() the VM state is
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * changed to VMSTATE_SUSPENDING or VMSTATE_SUSPENDING_EXT_LS.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - When the CPU with ID 0 calls vmR3Suspend() the virtual device emulations
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * and drivers get notified via PDMR3Suspend().
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - PDMR3Suspend() in VMM/VMMR3/PDM.cpp will iterate thru all device
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * emulations and notify them that the VM is suspending by calling their
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * PDMDEVREG::pfnSuspend / PDMUSBREG::pfnSuspend entry point (can be NULL).
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * For each device it will iterate the chains of drivers and call their
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * PDMDRVREG::pfnSuspend entry point as well.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - Should a worker thread in a PDM device or PDM driver be busy and need some
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * extra time to finish up / notice the pending suspend, the device or driver
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * will ask for more time via PDMDevHlpSetAsyncNotification(),
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * PDMDrvHlpSetAsyncNotification() or PDMUsbHlpSetAsyncNotification().
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * PDMR3Suspend will then poll these devices and drivers frequently until all
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * are done.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - PDMR3Suspend() will return to vmR3Suspend() once all PDM devices and PDM
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * drivers has responded to the pfnSuspend callback.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - The virtual CPU with ID 0 returns from vmR3Suspend() to the rendezvous
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * code and the EMTs are released.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - The inner VMMR3EmtRendezvous() call returns and this in turn triggers the
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * VMR3ReqCallWait() call to return (with the status code of the inner call).
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - The outer VMMR3EmtRendezvous() returns to VMR3Suspend().
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - VMR3Suspend() returns to Console::Pause().
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - Console::Pause() checks the result and flags provides error details on
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * failure.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - Console::Pause() returns to the COM/XPCOM marshalling/IPC stuff.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - Switch back to client process.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * - The IConsole::Pause() call returns. The end.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * Summary of above: Client process calls into the VM process, VM process does a
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * bunch of inter thread calls with all the EMT, EMT0 suspends the PDM devices
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * and drivers.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * The EMTs will return to the outer execution loop, vmR3EmulationThreadWithId()
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * in VMM/VMMR3/VMEmt.cpp, where they will mostly do sleep. They will not
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync * execute any guest code until VMR3Resume() is called.
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync *
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync */
69fba4ea53b1349f616bfcfce7e3014d4653ea1bvboxsync