VirtualBox

Changeset 4573 in vbox


Ignore:
Timestamp:
Sep 6, 2007 2:25:36 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
24197
Message:

More statistics. Started implementing the guest side.

Location:
trunk
Files:
4 edited

Legend:

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

    r4571 r4573  
    362362#define VBOX_GUEST_STAT_THREADS             BIT(3)
    363363#define VBOX_GUEST_STAT_PROCESSES           BIT(4)
    364 #define VBOX_GUEST_STAT_PHYS_MEM_TOTAL      BIT(5)
    365 #define VBOX_GUEST_STAT_PHYS_MEM_AVAIL      BIT(6)
    366 #define VBOX_GUEST_STAT_PHYS_MEM_BALLOON    BIT(7)
    367 #define VBOX_GUEST_STAT_PAGE_FILE_SIZE      BIT(8)
     364#define VBOX_GUEST_STAT_HANDLES             BIT(5)
     365#define VBOX_GUEST_STAT_MEMORY_LOAD         BIT(6)
     366#define VBOX_GUEST_STAT_PHYS_MEM_TOTAL      BIT(7)
     367#define VBOX_GUEST_STAT_PHYS_MEM_AVAIL      BIT(8)
     368#define VBOX_GUEST_STAT_PHYS_MEM_BALLOON    BIT(9)
     369#define VBOX_GUEST_STAT_MEM_COMMIT_TOTAL    BIT(10)
     370#define VBOX_GUEST_STAT_MEM_KERNEL_TOTAL    BIT(11)
     371#define VBOX_GUEST_STAT_MEM_KERNEL_PAGED    BIT(12)
     372#define VBOX_GUEST_STAT_MEM_KERNEL_NONPAGED BIT(13)
     373#define VBOX_GUEST_STAT_MEM_SYSTEM_CACHE    BIT(14)
     374#define VBOX_GUEST_STAT_PAGE_FILE_SIZE      BIT(15)
    368375
    369376
     
    385392    /** Nr of processes */
    386393    uint32_t        u32Processes;
    387     /** Total physical memory (megabytes) */
     394    /** Nr of handles */
     395    uint32_t        u32Handles;
     396    /** Memory load (0-100) */
     397    uint32_t        u32MemoryLoad;
     398    /** Total physical memory (in 4kb pages) */
    388399    uint32_t        u32PhysMemTotal;
    389     /** Available physical memory (megabytes) */
     400    /** Available physical memory (in 4kb pages) */
    390401    uint32_t        u32PhysMemAvail;
    391     /** Ballooned physical memory (megabytes) */
     402    /** Ballooned physical memory (in 4kb pages) */
    392403    uint32_t        u32PhysMemBalloon;
    393     /** Pagefile size (megabytes) */
     404    /** Total number of committed memory (which is not necessarily in-use) (in 4kb pages) */
     405    uint32_t        u32MemCommitTotal;
     406    /** Total amount of memory used by the kernel (in 4kb pages) */
     407    uint32_t        u32MemKernelTotal;
     408    /** Total amount of paged memory used by the kernel (in 4kb pages) */
     409    uint32_t        u32MemKernelPaged;
     410    /** Total amount of nonpaged memory used by the kernel (in 4kb pages) */
     411    uint32_t        u32MemKernelNonPaged;
     412    /** Total amount of memory used for the system cache (in 4kb pages) */
     413    uint32_t        u32MemSystemCache;
     414    /** Pagefile size (in 4kb pages) */
    394415    uint32_t        u32PageFileSize;
    395416} VBoxGuestStatistics;
  • trunk/src/VBox/Additions/WINNT/VBoxService/VBoxGuest.cpp

    r4524 r4573  
    1818#define _WIN32_WINNT 0x0500
    1919#include <windows.h>
     20#include <psapi.h>
    2021#include "VBoxService.h"
    2122#include "VBoxGuest.h"
     
    3132    const VBOXSERVICEENV *pEnv;
    3233    uint32_t              uStatInterval;
     34    uint32_t              uMemBalloonSize;
     35
     36    uint64_t              ullLastCpuLoad_Idle;
     37    uint64_t              ullLastCpuLoad_Kernel;
     38    uint64_t              ullLastCpuLoad_User;
    3339
    3440    NTSTATUS (WINAPI *pfnNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
     41    void     (WINAPI *pfnGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer);
     42    BOOL     (WINAPI *pfnGetPerformanceInfo)(PPERFORMANCE_INFORMATION pPerformanceInformation, DWORD cb);
    3543} VBOXGUESTCONTEXT;
    3644
     
    4654    dprintf(("VBoxGuestInit\n"));
    4755
    48     gCtx.pEnv          = pEnv;
    49     gCtx.uStatInterval = 0;     /* default */
     56    gCtx.pEnv                   = pEnv;
     57    gCtx.uStatInterval          = 0;     /* default */
     58    gCtx.ullLastCpuLoad_Idle    = 0;
     59    gCtx.ullLastCpuLoad_Kernel  = 0;
     60    gCtx.ullLastCpuLoad_User    = 0;
     61    gCtx.uMemBalloonSize        = 0;
    5062
    5163    VMMDevGetStatisticsChangeRequest req;
     
    6173        dprintf(("VBoxGuestThread: DeviceIoControl failed with %d\n", GetLastError()));
    6274
     75    /* NtQuerySystemInformation might be dropped in future releases, so load it dynamically as per Microsoft's recommendation */
    6376    HMODULE hMod = LoadLibrary("NTDLL.DLL");
    6477    if (hMod)
     
    6881            dprintf(("gCtx.pfnNtQuerySystemInformation = %x\n", gCtx.pfnNtQuerySystemInformation));
    6982        else
     83        {
    7084            dprintf(("NTDLL.NtQuerySystemInformation not found!!\n"));
    71     }
     85            return VERR_NOT_IMPLEMENTED;
     86        }
     87    }
     88
     89    /* GlobalMemoryStatus is win2k and up, so load it dynamically */
     90    hMod = LoadLibrary("KERNEL32.DLL");
     91    if (hMod)
     92    {
     93        *(uintptr_t *)&gCtx.pfnGlobalMemoryStatusEx = (uintptr_t)GetProcAddress(hMod, "GlobalMemoryStatus");
     94        if (gCtx.pfnGlobalMemoryStatusEx)
     95            dprintf(("gCtx.GlobalMemoryStatus= %x\n", gCtx.pfnGlobalMemoryStatusEx));
     96        else
     97        {
     98            /** @todo now fails in NT4; do we care? */
     99            dprintf(("KERNEL32.GlobalMemoryStatus not found!!\n"));
     100            return VERR_NOT_IMPLEMENTED;
     101        }
     102    }
     103    /* GetPerformanceInfo is xp and up, so load it dynamically */
     104    hMod = LoadLibrary("PSAPI.DLL");
     105    if (hMod)
     106    {
     107        *(uintptr_t *)&gCtx.pfnGetPerformanceInfo = (uintptr_t)GetProcAddress(hMod, "GetPerformanceInfo");
     108        if (gCtx.pfnGetPerformanceInfo)
     109            dprintf(("gCtx.pfnGetPerformanceInfo= %x\n", gCtx.pfnGetPerformanceInfo));
     110        /* failure is not fatal */
     111    }
     112
     113    /* Check balloon size */
     114    DWORD dwMemBalloonSize;
     115    if (DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_CTL_CHECK_BALLOON, NULL, 0, &dwMemBalloonSize, sizeof(dwMemBalloonSize), &cbReturned, NULL))
     116    {
     117        dprintf(("VBoxGuestThread: new balloon size % MB\n", dwMemBalloonSize));
     118        gCtx.uMemBalloonSize = dwMemBalloonSize;
     119    }
     120    else
     121        dprintf(("VBoxGuestThread: DeviceIoControl (balloon) failed with %d\n", GetLastError()));
    72122
    73123    *pfStartThread = true;
     
    81131    dprintf(("VBoxGuestDestroy\n"));
    82132    return;
     133}
     134
     135void VBoxGuestReportStatistics(VBOXGUESTCONTEXT *pCtx)
     136{
     137    SYSTEM_INFO systemInfo;
     138    PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pProcInfo;
     139    MEMORYSTATUSEX memStatus;
     140    VMMDevReportGuestStats req;
     141    uint32_t cbStruct;
     142    DWORD    cbReturned;
     143    HANDLE   gVBoxDriver = pCtx->pEnv->hDriver;
     144
     145    Assert(gCtx.pfnGlobalMemoryStatusEx && gCtx.pfnNtQuerySystemInformation);
     146    if (    !gCtx.pfnGlobalMemoryStatusEx
     147        ||  !gCtx.pfnNtQuerySystemInformation)
     148        return;
     149
     150    vmmdevInitRequest(&req.header, VMMDevReq_ReportGuestStats);
     151
     152    /* Query and report guest statistics */
     153    GetSystemInfo(&systemInfo);
     154
     155    gCtx.pfnGlobalMemoryStatusEx(&memStatus);
     156
     157    req.guestStats.u32PhysMemTotal      = (uint32_t)(memStatus.ullTotalPhys / systemInfo.dwPageSize);
     158    req.guestStats.u32PhysMemAvail      = (uint32_t)(memStatus.ullAvailPhys / systemInfo.dwPageSize);
     159    req.guestStats.u32PageFileSize      = (uint32_t)(memStatus.ullTotalPageFile / systemInfo.dwPageSize);
     160    req.guestStats.u32MemoryLoad        = memStatus.dwMemoryLoad;
     161    req.guestStats.u32PhysMemBalloon    = pCtx->uMemBalloonSize;    /* in megabytes already */
     162    req.guestStats.u32StatCaps          = VBOX_GUEST_STAT_PHYS_MEM_TOTAL | VBOX_GUEST_STAT_PHYS_MEM_AVAIL | VBOX_GUEST_STAT_PAGE_FILE_SIZE | VBOX_GUEST_STAT_MEMORY_LOAD | VBOX_GUEST_STAT_PHYS_MEM_BALLOON;
     163
     164    if (gCtx.pfnGetPerformanceInfo)
     165    {
     166        PERFORMANCE_INFORMATION perfInfo;
     167
     168        if (gCtx.pfnGetPerformanceInfo(&perfInfo, sizeof(perfInfo)))
     169        {
     170            req.guestStats.u32Processes         = perfInfo.ProcessCount;
     171            req.guestStats.u32Threads           = perfInfo.ThreadCount;
     172            req.guestStats.u32MemCommitTotal    = perfInfo.CommitTotal;     /* already in pages */
     173            req.guestStats.u32MemKernelTotal    = perfInfo.KernelTotal;     /* already in pages */
     174            req.guestStats.u32MemKernelPaged    = perfInfo.KernelPaged;     /* already in pages */
     175            req.guestStats.u32MemKernelNonPaged = perfInfo.KernelNonpaged;  /* already in pages */
     176            req.guestStats.u32MemSystemCache    = perfInfo.SystemCache;     /* already in pages */
     177            req.guestStats.u32StatCaps |= VBOX_GUEST_STAT_PROCESSES | VBOX_GUEST_STAT_THREADS | VBOX_GUEST_STAT_MEM_COMMIT_TOTAL | VBOX_GUEST_STAT_MEM_KERNEL_TOTAL | VBOX_GUEST_STAT_MEM_KERNEL_PAGED | VBOX_GUEST_STAT_MEM_KERNEL_NONPAGED | VBOX_GUEST_STAT_MEM_SYSTEM_CACHE;
     178        }
     179        else
     180            dprintf(("GetPerformanceInfo failed with %d\n", GetLastError()));
     181    }
     182
     183    /* Query CPU load information */
     184    cbStruct = systemInfo.dwNumberOfProcessors*sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
     185    pProcInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)malloc(cbStruct);
     186    Assert(pProcInfo);
     187    if (!pProcInfo)
     188        return;
     189
     190    /* Unfortunately GetSystemTimes is XP SP1 and up only, so we need to use the semi-undocumented NtQuerySystemInformation */
     191    NTSTATUS rc = gCtx.pfnNtQuerySystemInformation(SystemProcessorPerformanceInformation, pProcInfo, cbStruct, &cbReturned);
     192    if (    !rc
     193        &&  cbReturned == cbStruct)
     194    {
     195        if (gCtx.ullLastCpuLoad_Kernel == 0)
     196        {   
     197            /* first time */
     198            gCtx.ullLastCpuLoad_Idle    = pProcInfo->IdleTime.QuadPart;
     199            gCtx.ullLastCpuLoad_Kernel  = pProcInfo->KernelTime.QuadPart;
     200            gCtx.ullLastCpuLoad_User    = pProcInfo->UserTime.QuadPart;
     201
     202            Sleep(250);
     203
     204            rc = gCtx.pfnNtQuerySystemInformation(SystemProcessorPerformanceInformation, pProcInfo, cbStruct, &cbReturned);
     205            Assert(!rc);
     206        }
     207
     208        uint64_t deltaIdle    = (pProcInfo->IdleTime.QuadPart - gCtx.ullLastCpuLoad_Idle);
     209        uint64_t deltaKernel  = (pProcInfo->KernelTime.QuadPart - gCtx.ullLastCpuLoad_Kernel);
     210        uint64_t deltaUser    = (pProcInfo->UserTime.QuadPart - gCtx.ullLastCpuLoad_User);
     211        uint64_t ullTotalTime = deltaIdle + deltaKernel + deltaUser;
     212
     213        req.guestStats.u32CpuLoad_Idle      = (uint32_t)(deltaIdle  * 100 / ullTotalTime);
     214        req.guestStats.u32CpuLoad_Kernel    = (uint32_t)(deltaKernel* 100 / ullTotalTime);
     215        req.guestStats.u32CpuLoad_User      = (uint32_t)(deltaUser  * 100 / ullTotalTime);
     216
     217        req.guestStats.u32StatCaps |= VBOX_GUEST_STAT_CPU_LOAD_IDLE | VBOX_GUEST_STAT_CPU_LOAD_KERNEL | VBOX_GUEST_STAT_CPU_LOAD_USER;
     218
     219        gCtx.ullLastCpuLoad_Idle    = pProcInfo->IdleTime.QuadPart;
     220        gCtx.ullLastCpuLoad_Kernel  = pProcInfo->KernelTime.QuadPart;
     221        gCtx.ullLastCpuLoad_User    = pProcInfo->UserTime.QuadPart;
     222    }
     223
     224    for (uint32_t i=0;i<systemInfo.dwNumberOfProcessors;i++)
     225    {
     226        req.guestStats.u32CpuId = i;
     227
     228        if (DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_VMMREQUEST, &req, req.header.size, &req, req.header.size, &cbReturned, NULL))
     229        {
     230            dprintf(("VBoxGuestThread: new statistics reported successfully!\n"));
     231        }
     232        else
     233            dprintf(("VBoxGuestThread: DeviceIoControl (stats report) failed with %d\n", GetLastError()));
     234    }
     235
     236    free(pProcInfo);
    83237}
    84238
     
    126280            if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_BALLOON_CHANGE_REQUEST)
    127281            {
    128                 DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_CTL_CHECK_BALLOON, NULL, 0, NULL, 0, NULL, NULL);
     282                DWORD dwMemBalloonSize;
     283                if (DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_CTL_CHECK_BALLOON, NULL, 0, &dwMemBalloonSize, sizeof(dwMemBalloonSize), &cbReturned, NULL))
     284                {
     285                    dprintf(("VBoxGuestThread: new balloon size % MB\n", dwMemBalloonSize));
     286                    pCtx->uMemBalloonSize = dwMemBalloonSize;
     287                }
     288                else
     289                    dprintf(("VBoxGuestThread: DeviceIoControl (balloon) failed with %d\n", GetLastError()));
    129290            }
    130291            if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST)
     
    140301                }
    141302                else
    142                     dprintf(("VBoxGuestThread: DeviceIoControl failed with %d\n", GetLastError()));
    143 
     303                    dprintf(("VBoxGuestThread: DeviceIoControl (stat) failed with %d\n", GetLastError()));
    144304            }
    145305        }
     
    155315            }
    156316        }
     317        /* Report statistics to the host */
    157318        if (    gCtx.uStatInterval
    158319            &&  gCtx.pfnNtQuerySystemInformation)
    159320        {
    160             SYSTEM_INFO systemInfo;
    161 
    162             /* Query and report guest statistics */
    163             GetSystemInfo(&systemInfo);
    164 
    165             //gCtx.pfnNtQuerySystemInformation(
     321            VBoxGuestReportStatistics(pCtx);
    166322        }
    167323    }
  • trunk/src/VBox/Main/GuestImpl.cpp

    r4571 r4573  
    278278    case GuestStatisticType_Threads:
    279279    case GuestStatisticType_Processes:
     280    case GuestStatisticType_Handles:
     281    case GuestStatisticType_MemoryLoad:
    280282    case GuestStatisticType_PhysMemTotal:
    281283    case GuestStatisticType_PhysMemAvailable:
     284    case GuestStatisticType_MemCommitTotal:
     285    case GuestStatisticType_MemKernelTotal:
     286    case GuestStatisticType_MemKernelPaged:
     287    case GuestStatisticType_MemKernelNonpaged:
     288    case GuestStatisticType_MemSystemCache:
    282289    case GuestStatisticType_PageFileSize:
    283290        *aStatVal = 0;
     
    303310    case GuestStatisticType_Threads:
    304311    case GuestStatisticType_Processes:
     312    case GuestStatisticType_Handles:
     313    case GuestStatisticType_MemoryLoad:
    305314    case GuestStatisticType_PhysMemTotal:
    306315    case GuestStatisticType_PhysMemAvailable:
     316    case GuestStatisticType_MemCommitTotal:
     317    case GuestStatisticType_MemKernelTotal:
     318    case GuestStatisticType_MemKernelPaged:
     319    case GuestStatisticType_MemKernelNonpaged:
     320    case GuestStatisticType_MemSystemCache:
    307321    case GuestStatisticType_PageFileSize:
    308322        break;
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r4571 r4573  
    431431      </desc>
    432432    </const>
    433     <const name="Processes"            value="5">
     433    <const name="Processes"            value="4">
    434434      <desc>
    435435        Total number of processes in the system.
    436436      </desc>
    437437    </const>
    438     <const name="PhysMemTotal"         value="6">
     438    <const name="Handles"              value="5">
     439      <desc>
     440        Total number of handles in the system.
     441      </desc>
     442    </const>
     443    <const name="MemoryLoad"           value="6">
     444      <desc>
     445        Memory load (0-100%).
     446      </desc>
     447    </const>
     448    <const name="PhysMemTotal"         value="7">
    439449      <desc>
    440450        Total physical memory in megabytes.
    441451      </desc>
    442452    </const>
    443     <const name="PhysMemAvailable"     value="7">
     453    <const name="PhysMemAvailable"     value="8">
    444454      <desc>
    445455        Free physical memory in megabytes.
    446456      </desc>
    447457    </const>
    448     <const name="PhysMemBalloon"       value="8">
     458    <const name="PhysMemBalloon"       value="9">
    449459      <desc>
    450460        Ballooned physical memory in megabytes.
    451461      </desc>
    452462    </const>
    453     <const name="PageFileSize"         value="9">
     463    <const name="MemCommitTotal"       value="10">
     464      <desc>
     465        Total amount of memory in the committed state in megabytes.
     466      </desc>
     467    </const>
     468    <const name="MemKernelTotal"       value="11">
     469      <desc>
     470        Total amount of memory used by the guest OS's kernel in megabytes.
     471      </desc>
     472    </const>
     473    <const name="MemKernelPaged"       value="12">
     474      <desc>
     475        Total amount of paged memory used by the guest OS's kernel in megabytes.
     476      </desc>
     477    </const>
     478    <const name="MemKernelNonpaged"    value="13">
     479      <desc>
     480        Total amount of nonpaged memory used by the guest OS's kernel in megabytes.
     481      </desc>
     482    </const>
     483    <const name="MemSystemCache"       value="14">
     484      <desc>
     485        Total amount of memory used by the guest OS's system cache in megabytes.
     486      </desc>
     487    </const>
     488    <const name="PageFileSize"         value="15">
    454489      <desc>
    455490        Pagefile size in megabytes.
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