VBoxServiceStats.cpp revision 70a2dc6fea37323160351b9f9d20fc8c41f27cfe
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * VBoxStats - Guest statistics notification
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Copyright (C) 2006-2007 Sun Microsystems, Inc.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * This file is part of VirtualBox Open Source Edition (OSE), as
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * available from http://www.virtualbox.org. This file is free software;
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * you can redistribute it and/or modify it under the terms of the GNU
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * General Public License (GPL) as published by the Free Software
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Foundation, in version 2 as it comes in the "COPYING" file of the
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * Clara, CA 95054 USA or visit http://www.sun.com if you need
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington * additional information or have any questions.
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/*******************************************************************************
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington* Header Files *
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington*******************************************************************************/
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/** @todo port me. */
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/*******************************************************************************
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major* Structures and Typedefs *
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major*******************************************************************************/
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major uint64_t au64LastCpuLoad_Idle[VMM_MAX_CPU_COUNT];
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major uint64_t au64LastCpuLoad_Kernel[VMM_MAX_CPU_COUNT];
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major uint64_t au64LastCpuLoad_User[VMM_MAX_CPU_COUNT];
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major uint64_t au64LastCpuLoad_Nice[VMM_MAX_CPU_COUNT];
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington NTSTATUS (WINAPI *pfnNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major void (WINAPI *pfnGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer);
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major BOOL (WINAPI *pfnGetPerformanceInfo)(PPERFORMANCE_INFORMATION pPerformanceInformation, DWORD cb);
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/*******************************************************************************
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major* Global Variables *
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major*******************************************************************************/
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/** The semaphore we're blocking on. */
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Majorstatic RTSEMEVENTMULTI g_VMStatEvent = NIL_RTSEMEVENTMULTI;
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/** @copydoc VBOXSERVICE::pfnPreInit */
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Majorstatic DECLCALLBACK(int) VBoxServiceVMStatsPreInit(void)
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/** @copydoc VBOXSERVICE::pfnOption */
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Majorstatic DECLCALLBACK(int) VBoxServiceVMStatsOption(const char **ppszShort, int argc, char **argv, int *pi)
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major/** @copydoc VBOXSERVICE::pfnInit */
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Majorstatic DECLCALLBACK(int) VBoxServiceVMStatsInit(void)
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington VBoxServiceVerbose(3, "VBoxServiceVMStatsInit\n");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington int rc = RTSemEventMultiCreate(&g_VMStatEvent);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington gCtx.cMsStatInterval = 0; /* default; update disabled */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington rc = VbglR3StatQueryInterval(&gCtx.cMsStatInterval);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington VBoxServiceVerbose(3, "VBoxStatsInit: new statistics interval %u seconds\n", gCtx.cMsStatInterval);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington VBoxServiceVerbose(3, "VBoxStatsInit: DeviceIoControl failed with %d\n", rc);
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington /* NtQuerySystemInformation might be dropped in future releases, so load it dynamically as per Microsoft's recommendation */
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington *(uintptr_t *)&gCtx.pfnNtQuerySystemInformation = (uintptr_t)GetProcAddress(hMod, "NtQuerySystemInformation");
1067e734d6cec73ee954f2e43c1bba0e09d267cfPhill Cunnington VBoxServiceVerbose(3, "VBoxStatsInit: gCtx.pfnNtQuerySystemInformation = %x\n", gCtx.pfnNtQuerySystemInformation);
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major VBoxServiceError("VBoxStatsInit: NTDLL.NtQuerySystemInformation not found!!\n");
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major /* GlobalMemoryStatus is win2k and up, so load it dynamically */
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major *(uintptr_t *)&gCtx.pfnGlobalMemoryStatusEx = (uintptr_t)GetProcAddress(hMod, "GlobalMemoryStatusEx");
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major VBoxServiceVerbose(3, "VBoxStatsInit: gCtx.GlobalMemoryStatusEx = %x\n", gCtx.pfnGlobalMemoryStatusEx);
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major /** @todo now fails in NT4; do we care? */
dfc4e0fc3052835b2a069aa9d869fa1161c33fe6Peter Major VBoxServiceError("VBoxStatsInit: KERNEL32.GlobalMemoryStatusEx not found!!\n");
if (hMod)
VBoxServiceVerbose(3, "VBoxStatsInit: gCtx.pfnGetPerformanceInfo= %x\n", gCtx.pfnGetPerformanceInfo);
return VINF_SUCCESS;
static void VBoxServiceVMStatsReport(void)
#if defined(RT_OS_WINDOWS)
req.guestStats.u32PageFileSize = (uint32_t)(memStatus.ullTotalPageFile / _4K) - req.guestStats.u32PhysMemTotal;
req.guestStats.u32StatCaps = VBOX_GUEST_STAT_PHYS_MEM_TOTAL | VBOX_GUEST_STAT_PHYS_MEM_AVAIL | VBOX_GUEST_STAT_PAGE_FILE_SIZE
req.guestStats.u32StatCaps |= VBOX_GUEST_STAT_PROCESSES | VBOX_GUEST_STAT_THREADS | VBOX_GUEST_STAT_HANDLES
if (!pProcInfo)
/* Unfortunately GetSystemTimes is XP SP1 and up only, so we need to use the semi-undocumented NtQuerySystemInformation */
NTSTATUS rc = gCtx.pfnNtQuerySystemInformation(SystemProcessorPerformanceInformation, pProcInfo, cbStruct, &cbReturned);
if ( !rc
rc = gCtx.pfnNtQuerySystemInformation(SystemProcessorPerformanceInformation, pProcInfo, cbStruct, &cbReturned);
req.guestStats.u32StatCaps |= VBOX_GUEST_STAT_CPU_LOAD_IDLE | VBOX_GUEST_STAT_CPU_LOAD_KERNEL | VBOX_GUEST_STAT_CPU_LOAD_USER;
VBoxServiceVerbose(3, "VBoxStatsReportStatistics: new statistics (CPU %u) reported successfully!\n", i);
VBoxServiceVerbose(3, "VBoxStatsReportStatistics: DeviceIoControl (stats report) failed with %d\n", GetLastError());
char *psz;
bool fCpuInfoAvail = false;
+ u64DeltaNice;
fCpuInfoAvail = true;
VBoxServiceVerbose(3, "VBoxStatsReportStatistics: new statistics (CPU %u) reported successfully!\n", u32CpuId);
if (!fCpuInfoAvail)
if (pStatKern)
if (pStatPages)
if (pStat)
if (pStat)
if (pStatZFS)
if (pStat)
if (pStatInfo)
if (pStatVMInfo)
bool fCpuInfoAvail = false;
fCpuInfoAvail = true;
VBoxServiceVerbose(3, "VBoxStatsReportStatistics: new statistics (CPU %u) reported successfully!\n", cCpus);
cCPUs++;
if (!fCpuInfoAvail)
return rc;
if (*pfShutdown)
if (*pfShutdown)
NULL,
NULL,