STAM.cpp revision a725911b86be55ff5bd5a3026eaa51c3a9e74d71
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * STAM - The Statistics Manager.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Copyright (C) 2006-2014 Oracle Corporation
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * available from http://www.virtualbox.org. This file is free software;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * you can redistribute it and/or modify it under the terms of the GNU
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * General Public License (GPL) as published by the Free Software
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** @page pg_stam STAM - The Statistics Manager
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The purpose for the statistics manager is to present the rest of the system
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * with a somewhat uniform way of accessing VMM statistics. STAM sports a
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * couple of different APIs for accessing them: STAMR3EnumU, STAMR3SnapshotU,
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * STAMR3DumpU, STAMR3DumpToReleaseLogU and the debugger. Main is exposing the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * XML based one, STAMR3SnapshotU.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The rest of the VMM together with the devices and drivers registers their
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync * statistics with STAM giving them a name. The name is hierarchical, the
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync * components separated by slashes ('/') and must start with a slash.
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync * Each item registered with STAM - also, half incorrectly, called a sample -
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * has a type, unit, visibility, data pointer and description associated with it
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * in addition to the name (described above). The type tells STAM what kind of
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * structure the pointer is pointing to. The visibility allows unused
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * statistics from cluttering the output or showing up in the GUI. All the bits
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * together makes STAM able to present the items in a sensible way to the user.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Some types also allows STAM to reset the data, which is very convenient when
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * digging into specific operations and such.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * PS. The VirtualBox Debugger GUI has a viewer for inspecting the statistics
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * STAM provides. You will also find statistics in the release and debug logs.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * And as mentioned in the introduction, the debugger console features a couple
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * of command: .stats and .statsreset.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @see grp_stam
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*******************************************************************************
956a0e3c076406b83d635174a201fd8761ee5133vboxsync* Header Files *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*******************************************************************************
956a0e3c076406b83d635174a201fd8761ee5133vboxsync* Defined Constants And Macros *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** The maximum name length excluding the terminator. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*******************************************************************************
956a0e3c076406b83d635174a201fd8761ee5133vboxsync* Structures and Typedefs *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Argument structure for stamR3PrintOne().
956a0e3c076406b83d635174a201fd8761ee5133vboxsync DECLCALLBACKMEMBER(void, pfnPrintf)(struct STAMR3PRINTONEARGS *pvArg, const char *pszFormat, ...);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Argument structure to stamR3EnumOne().
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The snapshot status structure.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Argument package passed to stamR3SnapshotOne, stamR3SnapshotPrintf and stamR3SnapshotOutput.
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync /** Pointer to the buffer start. */
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync /** Pointer to the buffer end. */
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync /** Pointer to the current buffer position. */
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync /** Pointer to the VM. */
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync /** The number of bytes allocated. */
a15d881e9ec9bffe9b27ae4174efb8d4dc4a0e17vboxsync /** The status code. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Whether to include the description strings. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Init record for a ring-0 statistic sample.
956a0e3c076406b83d635174a201fd8761ee5133vboxsynctypedef struct STAMR0SAMPLE
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The GVMMSTATS structure offset of the variable. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The type. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The unit. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The name. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync const char *pszName;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The description. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync const char *pszDesc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*******************************************************************************
956a0e3c076406b83d635174a201fd8761ee5133vboxsync* Internal Functions *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic void stamR3LookupDestroyTree(PSTAMLOOKUP pRoot);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int stamR3RegisterU(PUVM pUVM, void *pvSample, PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
956a0e3c076406b83d635174a201fd8761ee5133vboxsync STAMTYPE enmType, STAMVISIBILITY enmVisibility, const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int stamR3ResetOne(PSTAMDESC pDesc, void *pvArg);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic DECLCALLBACK(void) stamR3EnumLogPrintf(PSTAMR3PRINTONEARGS pvArg, const char *pszFormat, ...);
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsyncstatic DECLCALLBACK(void) stamR3EnumRelLogPrintf(PSTAMR3PRINTONEARGS pvArg, const char *pszFormat, ...);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic DECLCALLBACK(void) stamR3EnumPrintf(PSTAMR3PRINTONEARGS pvArg, const char *pszFormat, ...);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int stamR3SnapshotOne(PSTAMDESC pDesc, void *pvArg);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int stamR3SnapshotPrintf(PSTAMR3SNAPSHOTONE pThis, const char *pszFormat, ...);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int stamR3PrintOne(PSTAMDESC pDesc, void *pvArg);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int stamR3EnumOne(PSTAMDESC pDesc, void *pvArg);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic bool stamR3MultiMatch(const char * const *papszExpressions, unsigned cExpressions, unsigned *piExpression, const char *pszName);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic char ** stamR3SplitPattern(const char *pszPat, unsigned *pcExpressions, char **ppszCopy);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int stamR3EnumU(PUVM pUVM, const char *pszPat, bool fUpdateRing0, int (pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic void stamR3Ring0StatsUpdateU(PUVM pUVM, const char *pszPat);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic void stamR3Ring0StatsUpdateMultiU(PUVM pUVM, const char * const *papszExpressions, unsigned cExpressions);
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic DECLCALLBACK(void) stamR3EnumDbgfPrintf(PSTAMR3PRINTONEARGS pArgs, const char *pszFormat, ...);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*******************************************************************************
956a0e3c076406b83d635174a201fd8761ee5133vboxsync* Global Variables *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** Pattern argument. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { 0, 1, DBGCVAR_CAT_STRING, 0, "pattern", "Which samples the command shall be applied to. Use '*' as wildcard. Use ';' to separate expression." }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** Command descriptors. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { "stats", 0, 1, &g_aArgPat[0], RT_ELEMENTS(g_aArgPat), 0, stamR3CmdStats, "[pattern]", "Display statistics." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { "statsreset", 0, 1, &g_aArgPat[0], RT_ELEMENTS(g_aArgPat), 0, stamR3CmdStatsReset,"[pattern]", "Resets statistics." }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The GVMM mapping records - sans the host cpus.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cHaltCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltCalls", "The number of calls to GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cHaltBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cHaltTimeouts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cHaltNotBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cHaltWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cWakeUpCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/WakeUpCalls", "The number of calls to GVMMR0WakeUp." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cWakeUpNotHalted), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cWakeUpWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cPokeCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PokeCalls", "The number of calls to GVMMR0Poke." },
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cPokeNotBusy), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PokeNotBusy", "The number of times the EMT thread wasn't actually busy when GVMMR0Poke was called." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cPollCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PollCalls", "The number of calls to GVMMR0SchedPoll." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cPollHalts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedVM.cPollWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cHaltCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltCalls", "The number of calls to GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cHaltBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cHaltTimeouts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cHaltNotBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cHaltWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." },
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cWakeUpCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpCalls", "The number of calls to GVMMR0WakeUp." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cWakeUpNotHalted), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cWakeUpWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cPokeCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PokeCalls", "The number of calls to GVMMR0Poke." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cPokeNotBusy), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PokeNotBusy", "The number of times the EMT thread wasn't actually busy when GVMMR0Poke was called." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cPollCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PollCalls", "The number of calls to GVMMR0SchedPoll." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cPollHalts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." },
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync { RT_UOFFSETOF(GVMMSTATS, SchedSum.cPollWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, cVMs), STAMTYPE_U32, STAMUNIT_CALLS, "/GVMM/VMs", "The number of VMs accessible to the caller." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, cEMTs), STAMTYPE_U32, STAMUNIT_CALLS, "/GVMM/EMTs", "The number of emulation threads." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GVMMSTATS, cHostCpus), STAMTYPE_U32, STAMUNIT_CALLS, "/GVMM/HostCPUs", "The number of host CPUs." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The GMM mapping records.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cMaxPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cMaxPages", "The maximum number of pages GMM is allowed to allocate." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cReservedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cReservedPages", "The number of pages that has been reserved." },
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync { RT_UOFFSETOF(GMMSTATS, cOverCommittedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cOverCommittedPages", "The number of pages that we have over-committed in reservations." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cAllocatedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cAllocatedPages", "The number of actually allocated (committed if you like) pages." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cSharedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cSharedPages", "The number of pages that are shared. A subset of cAllocatedPages." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cDuplicatePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cDuplicatePages", "The number of pages that are actually shared between VMs." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cLeftBehindSharedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cLeftBehindSharedPages", "The number of pages that are shared that has been left behind by VMs not doing proper cleanups." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cBalloonedPages", "The number of current ballooned pages." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cChunks), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/cChunks", "The number of allocation chunks." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cFreedChunks), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/cFreedChunks", "The number of freed chunks ever." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, cShareableModules), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/cShareableModules", "The number of shareable modules." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.Reserved.cBasePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/Reserved/cBasePages", "The amount of base memory (RAM, ROM, ++) reserved by the VM." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.Reserved.cShadowPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Reserved/cShadowPages", "The amount of memory reserved for shadow/nested page tables." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.Reserved.cFixedPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Reserved/cFixedPages", "The amount of memory reserved for fixed allocations like MMIO2 and the hyper heap." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.Allocated.cBasePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/Allocated/cBasePages", "The amount of base memory (RAM, ROM, ++) allocated by the VM." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.Allocated.cShadowPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Allocated/cShadowPages", "The amount of memory allocated for shadow/nested page tables." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.Allocated.cFixedPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Allocated/cFixedPages", "The amount of memory allocated for fixed allocations like MMIO2 and the hyper heap." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cPrivatePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cPrivatePages", "The current number of private pages." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cSharedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cSharedPages", "The current number of shared pages." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cBalloonedPages", "The current number of ballooned pages." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cMaxBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cMaxBalloonedPages", "The max number of pages that can be ballooned." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cReqBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cReqBalloonedPages", "The number of pages we've currently requested the guest to give us." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cReqActuallyBalloonedPages),STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cReqActuallyBalloonedPages","The number of pages the guest has given us in response to the request." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cReqDeflatePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cReqDeflatePages", "The number of pages we've currently requested the guest to take back." },
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.cShareableModules), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/VM/cShareableModules", "The number of shareable modules traced by the VM." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.enmPolicy), STAMTYPE_U32, STAMUNIT_NONE, "/GMM/VM/enmPolicy", "The current over-commit policy." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.enmPriority), STAMTYPE_U32, STAMUNIT_NONE, "/GMM/VM/enmPriority", "The VM priority for arbitrating VMs in low and out of memory situation." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.fBallooningEnabled), STAMTYPE_BOOL, STAMUNIT_NONE, "/GMM/VM/fBallooningEnabled", "Whether ballooning is enabled or not." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.fSharedPagingEnabled), STAMTYPE_BOOL, STAMUNIT_NONE, "/GMM/VM/fSharedPagingEnabled", "Whether shared paging is enabled or not." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync { RT_UOFFSETOF(GMMSTATS, VMStats.fMayAllocate), STAMTYPE_BOOL, STAMUNIT_NONE, "/GMM/VM/fMayAllocate", "Whether the VM is allowed to allocate memory or not." },
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Initializes the STAM.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns VBox status code.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM Pointer to the VM.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Assert alignment and sizes.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertCompile(sizeof(pUVM->stam.s) <= sizeof(pUVM->stam.padding));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertRelease(sizeof(pUVM->stam.s) <= sizeof(pUVM->stam.padding));
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * Initialize the read/write lock and list.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Initialize the root node.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync PSTAMLOOKUP pRoot = (PSTAMLOOKUP)RTMemAlloc(sizeof(STAMLOOKUP));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Register the ring-0 statistics (GVMM/GMM).
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * Register debugger commands.
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync static bool fRegisteredCmds = false;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = DBGCRegisterCommands(&g_aCmds[0], RT_ELEMENTS(g_aCmds));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Terminates the STAM.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pUVM Pointer to the user mode VM structure.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Free used memory and the RWLock.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTListForEachSafe(&pUVM->stam.s.List, pCur, pNext, STAMDESC, ListEntry)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * Registers a sample with the statistics manager.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * Statistics are maintained on a per VM basis and is normally registered
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * during the VM init stage, but there is nothing preventing you from
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * register them at runtime.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Use STAMR3Deregister() to deregister statistics at runtime, however do
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * not bother calling at termination time.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * It is not possible to register the same sample twice.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @returns VBox status.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * @param pUVM Pointer to the user mode VM structure.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pvSample Pointer to the sample.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param enmType Sample type. This indicates what pvSample is pointing at.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pszName Sample name. The name is on this form "/<component>/<sample>".
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * Further nesting is possible.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param enmUnit Sample unit.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pszDesc Sample description.
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncVMMR3DECL(int) STAMR3RegisterU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(enmType != STAMTYPE_CALLBACK, VERR_INVALID_PARAMETER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync return stamR3RegisterU(pUVM, pvSample, NULL, NULL, enmType, enmVisibility, pszName, enmUnit, pszDesc);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Registers a sample with the statistics manager.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Statistics are maintained on a per VM basis and is normally registered
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * during the VM init stage, but there is nothing preventing you from
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * register them at runtime.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Use STAMR3Deregister() to deregister statistics at runtime, however do
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * not bother calling at termination time.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * It is not possible to register the same sample twice.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * @returns VBox status.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pVM Pointer to the VM.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * @param pvSample Pointer to the sample.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param enmType Sample type. This indicates what pvSample is pointing at.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pszName Sample name. The name is on this form "/<component>/<sample>".
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * Further nesting is possible.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param enmUnit Sample unit.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * @param pszDesc Sample description.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsyncVMMR3DECL(int) STAMR3Register(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync AssertReturn(enmType != STAMTYPE_CALLBACK, VERR_INVALID_PARAMETER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return stamR3RegisterU(pVM->pUVM, pvSample, NULL, NULL, enmType, enmVisibility, pszName, enmUnit, pszDesc);
* @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
VMMR3DECL(int) STAMR3RegisterFU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
return rc;
* @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
VMMR3DECL(int) STAMR3RegisterF(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
int rc = STAMR3RegisterVU(pVM->pUVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
return rc;
* @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
VMMR3DECL(int) STAMR3RegisterVU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
* @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
VMMR3DECL(int) STAMR3RegisterV(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
return STAMR3RegisterVU(pVM->pUVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
* @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
* @param pfnReset Callback for resetting the sample. NULL should be used if the sample can't be reset.
* @remark There is currently no device or driver variant of this API. Add one if it should become necessary!
VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
int rc = STAMR3RegisterCallbackV(pVM, pvSample, enmVisibility, enmUnit, pfnReset, pfnPrint, pszDesc, pszName, args);
return rc;
* @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
* @param pfnReset Callback for resetting the sample. NULL should be used if the sample can't be reset.
* @remark There is currently no device or driver variant of this API. Add one if it should become necessary!
VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
char *pszFormattedName;
if (!pszFormattedName)
return VERR_NO_MEMORY;
int rc = stamR3RegisterU(pVM->pUVM, pvSample, pfnReset, pfnPrint, STAMTYPE_CALLBACK, enmVisibility, pszFormattedName, enmUnit, pszDesc);
return rc;
#ifdef VBOX_STRICT
#ifdef STAM_WITH_LOOKUP_TREE
return iDiff;
static PSTAMLOOKUP stamR3LookupNewChild(PSTAMLOOKUP pParent, const char *pchName, uint32_t cchName, uint32_t offName,
if (!pNew)
return NULL;
if (!pvNew)
return NULL;
iChild = 0;
iChild++;
while (i > iChild)
return pNew;
static PSTAMLOOKUP stamR3LookupFindChild(PSTAMLOOKUP pParent, const char *pchName, uint32_t cchName, uint32_t *piChild)
if (!iDiff)
if (piChild)
if (iDiff < 0)
if (piChild)
if (piChild)
return NULL;
while (iChild-- > 0)
if (iDiff <= 0)
if (piChild)
if (piChild)
*piChild = 0;
return NULL;
iCur = 0;
if (!pCur)
return NULL;
if (!pChild)
if (!pszEnd)
return NULL;
iCur = 0;
return NULL;
return NULL;
if (!pCur)
return NULL;
return NULL;
return NULL;
if (!pCur)
return NULL;
static PSTAMDESC stamR3LookupFindPatternDescRange(PSTAMLOOKUP pRoot, PRTLISTANCHOR pList, const char *pszPat,
if (!cch)
if (!pChild)
if (!pszEnd)
return NULL;
if (!pCur)
if (!pParent)
if (!pCur)
* @param pfnReset Callback for resetting the sample. NULL should be used if the sample can't be reset.
* @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
* @remark There is currently no device or driver variant of this API. Add one if it should become necessary!
static int stamR3RegisterU(PUVM pUVM, void *pvSample, PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
STAMTYPE enmType, STAMVISIBILITY enmVisibility, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
#ifdef STAM_WITH_LOOKUP_TREE
if (cch == 0)
return VERR_INVALID_NAME;
if (!pChild)
if (!pChild)
return VERR_NO_MEMORY;
if (!pszEnd)
return VERR_ALREADY_EXISTS;
if (iDiff > 0)
if (!iDiff)
return VERR_ALREADY_EXISTS;
#ifdef VBOX_STRICT
switch (enmType)
case STAMTYPE_U64:
case STAMTYPE_U64_RESET:
case STAMTYPE_X64:
case STAMTYPE_X64_RESET:
case STAMTYPE_COUNTER:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_RATIO_U32:
case STAMTYPE_RATIO_U32_RESET:
case STAMTYPE_U32:
case STAMTYPE_U32_RESET:
case STAMTYPE_X32:
case STAMTYPE_X32_RESET:
case STAMTYPE_U16:
case STAMTYPE_U16_RESET:
case STAMTYPE_X16:
case STAMTYPE_X16_RESET:
case STAMTYPE_U8:
case STAMTYPE_U8_RESET:
case STAMTYPE_X8:
case STAMTYPE_X8_RESET:
case STAMTYPE_BOOL:
case STAMTYPE_BOOL_RESET:
case STAMTYPE_CALLBACK:
int rc;
if (pNew)
if (pszDesc)
if (pCur)
#ifdef STAM_WITH_LOOKUP_TREE
return rc;
#ifdef STAM_WITH_LOOKUP_TREE
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
PSTAMDESC pCur = stamR3LookupFindPatternDescRange(pUVM->stam.s.pRoot, &pUVM->stam.s.List, pszPat, &pLast);
if (pCur)
return rc;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
if (fGVMMMatched)
char *pszCopy;
unsigned cExpressions;
if (!papszExpressions)
return VERR_NO_MEMORY;
fGVMMMatched = true;
if (!fGVMMMatched)
fGMMMatched = true;
if (fGVMMMatched)
if (fGMMMatched)
return rc;
case STAMTYPE_COUNTER:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_RATIO_U32_RESET:
case STAMTYPE_CALLBACK:
case STAMTYPE_U8_RESET:
case STAMTYPE_X8_RESET:
case STAMTYPE_U16_RESET:
case STAMTYPE_X16_RESET:
case STAMTYPE_U32_RESET:
case STAMTYPE_X32_RESET:
case STAMTYPE_U64_RESET:
case STAMTYPE_X64_RESET:
case STAMTYPE_BOOL_RESET:
case STAMTYPE_U8:
case STAMTYPE_X8:
case STAMTYPE_U16:
case STAMTYPE_X16:
case STAMTYPE_U32:
case STAMTYPE_X32:
case STAMTYPE_U64:
case STAMTYPE_X64:
case STAMTYPE_RATIO_U32:
case STAMTYPE_BOOL:
return VINF_SUCCESS;
VMMR3DECL(int) STAMR3Snapshot(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc)
if (pcchSnapshot)
return rc;
case STAMTYPE_COUNTER:
return VINF_SUCCESS;
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
return VINF_SUCCESS;
stamR3SnapshotPrintf(pThis, "<Profile cPeriods=\"%lld\" cTicks=\"%lld\" cTicksMin=\"%lld\" cTicksMax=\"%lld\"",
case STAMTYPE_RATIO_U32:
case STAMTYPE_RATIO_U32_RESET:
if (pDesc->enmVisibility == STAMVISIBILITY_USED && !pDesc->u.pRatioU32->u32A && !pDesc->u.pRatioU32->u32B)
return VINF_SUCCESS;
case STAMTYPE_CALLBACK:
case STAMTYPE_U8:
case STAMTYPE_U8_RESET:
return VINF_SUCCESS;
case STAMTYPE_X8:
case STAMTYPE_X8_RESET:
return VINF_SUCCESS;
case STAMTYPE_U16:
case STAMTYPE_U16_RESET:
return VINF_SUCCESS;
case STAMTYPE_X16:
case STAMTYPE_X16_RESET:
return VINF_SUCCESS;
case STAMTYPE_U32:
case STAMTYPE_U32_RESET:
return VINF_SUCCESS;
case STAMTYPE_X32:
case STAMTYPE_X32_RESET:
return VINF_SUCCESS;
case STAMTYPE_U64:
case STAMTYPE_U64_RESET:
return VINF_SUCCESS;
case STAMTYPE_X64:
case STAMTYPE_X64_RESET:
return VINF_SUCCESS;
case STAMTYPE_BOOL:
case STAMTYPE_BOOL_RESET:
return VINF_SUCCESS;
case STAMVISIBILITY_ALWAYS:
case STAMVISIBILITY_USED:
case STAMVISIBILITY_NOT_GUI:
if (!pszBadChar)
switch (*pszBadChar)
} while (pszBadChar);
if (!pszNew)
return cch;
if (!pszSnapshot)
return VINF_SUCCESS;
return VINF_SUCCESS;
static DECLCALLBACK(void) stamR3EnumLogPrintf(PSTAMR3PRINTONEARGS pArgs, const char *pszFormat, ...)
return VINF_SUCCESS;
static DECLCALLBACK(void) stamR3EnumRelLogPrintf(PSTAMR3PRINTONEARGS pArgs, const char *pszFormat, ...)
return VINF_SUCCESS;
case STAMTYPE_COUNTER:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8llu %s\n", pDesc->pszName, pDesc->u.pCounter->c, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8llu %s (%12llu ticks, %7llu times, max %9llu, min %7lld)\n", pDesc->pszName,
pDesc->u.pProfile->cTicks, pDesc->u.pProfile->cPeriods, pDesc->u.pProfile->cTicksMax, pDesc->u.pProfile->cTicksMin);
case STAMTYPE_RATIO_U32:
case STAMTYPE_RATIO_U32_RESET:
if (pDesc->enmVisibility == STAMVISIBILITY_USED && !pDesc->u.pRatioU32->u32A && !pDesc->u.pRatioU32->u32B)
return VINF_SUCCESS;
case STAMTYPE_CALLBACK:
case STAMTYPE_U8:
case STAMTYPE_U8_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8u %s\n", pDesc->pszName, *pDesc->u.pu8, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_X8:
case STAMTYPE_X8_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8x %s\n", pDesc->pszName, *pDesc->u.pu8, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_U16:
case STAMTYPE_U16_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8u %s\n", pDesc->pszName, *pDesc->u.pu16, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_X16:
case STAMTYPE_X16_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8x %s\n", pDesc->pszName, *pDesc->u.pu16, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_U32:
case STAMTYPE_U32_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8u %s\n", pDesc->pszName, *pDesc->u.pu32, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_X32:
case STAMTYPE_X32_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8x %s\n", pDesc->pszName, *pDesc->u.pu32, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_U64:
case STAMTYPE_U64_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8llu %s\n", pDesc->pszName, *pDesc->u.pu64, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_X64:
case STAMTYPE_X64_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %8llx %s\n", pDesc->pszName, *pDesc->u.pu64, STAMR3GetUnit(pDesc->enmUnit));
case STAMTYPE_BOOL:
case STAMTYPE_BOOL_RESET:
return VINF_SUCCESS;
pArgs->pfnPrintf(pArgs, "%-32s %s %s\n", pDesc->pszName, *pDesc->u.pf ? "true " : "false ", STAMR3GetUnit(pDesc->enmUnit));
return VINF_SUCCESS;
int rc;
return rc;
if (!pszCopy)
return NULL;
if (!papszExpressions)
return NULL;
if (++i >= cExpressions)
return papszExpressions;
if (fUpdateRing0)
if (rc)
if (fUpdateRing0)
#ifdef STAM_WITH_LOOKUP_TREE
if (pCur)
if (pCur)
if (rc)
if (rc)
char *pszCopy;
unsigned cExpressions;
if (!papszExpressions)
return VERR_NO_MEMORY;
if (fUpdateRing0)
unsigned iExpression = 0;
if (rc)
return rc;
static void stamR3Ring0StatsUpdateMultiU(PUVM pUVM, const char * const *papszExpressions, unsigned cExpressions)
bool fUpdate = false;
fUpdate = true;
if (!fUpdate)
if (fUpdate)
fUpdate = false;
fUpdate = true;
if (fUpdate)
switch (enmUnit)
#ifdef VBOX_WITH_DEBUGGER
static DECLCALLBACK(int) stamR3CmdStats(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
return stamR3EnumU(pUVM, cArgs ? paArgs[0].u.pszString : NULL, true /* fUpdateRing0 */, stamR3PrintOne, &Args);
static DECLCALLBACK(void) stamR3EnumDbgfPrintf(PSTAMR3PRINTONEARGS pArgs, const char *pszFormat, ...)
static DECLCALLBACK(int) stamR3CmdStatsReset(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)