Changeset 26292 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Feb 5, 2010 2:28:23 PM (15 years ago)
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 2 deleted
- 5 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
r23452 r26292 37 37 VBoxVRDP.cpp \ 38 38 VBoxRestore.cpp \ 39 VBoxStatistics.cpp \40 VBoxMemBalloon.cpp \41 39 helpers.cpp \ 42 40 VBoxTray.rc -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r24984 r26292 25 25 #include "VBoxRestore.h" 26 26 #include "VBoxVRDP.h" 27 #include "VBoxStatistics.h"28 #include "VBoxMemBalloon.h"29 27 #include "VBoxHostVersion.h" 30 28 #include <VBoxHook.h> … … 72 70 VBoxSeamlessDestroy 73 71 }, 74 #ifdef VBOX_WITH_MANAGEMENT75 {76 "Memory Balloon",77 VBoxMemBalloonInit,78 VBoxMemBalloonThread,79 VBoxMemBalloonDestroy,80 },81 {82 "Guest Statistics",83 VBoxStatsInit,84 VBoxStatsThread,85 VBoxStatsDestroy,86 },87 #endif88 72 #ifdef VBOX_WITH_VRDP_SESSION_HANDLING 89 73 { -
trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk
r26061 r26292 34 34 VBoxService_TEMPLATE = VBOXGUESTR3EXE 35 35 VBoxService_DEFS = VBOXSERVICE_TIMESYNC 36 VBoxService_DEFS.win += _WIN32_WINNT=0x0501 36 VBoxService_DEFS.win += _WIN32_WINNT=0x0501 37 ##VBOXSERVICE_MANAGEMENT 37 38 VBoxService_DEFS.os2 = VBOX_WITH_HGCM VBOXSERVICE_CLIPBOARD 38 39 ifdef VBOX_WITH_GUEST_PROPS … … 67 68 VBoxService-win.rc \ 68 69 VBoxService-win.cpp 70 71 ## VBoxServiceStats.cpp \ 72 ## VBoxServiceBalloon.cpp 73 69 74 VBoxService_SOURCES.os2 = \ 70 75 VBoxService-os2.def \ -
trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp
r26136 r26292 93 93 #ifdef VBOXSERVICE_CPUHOTPLUG /* Disabled by default. Use --enable-cpuhotplug to enable */ 94 94 { &g_CpuHotPlug, NIL_RTTHREAD, false, false, false, false }, 95 #endif 96 #ifdef VBOXSERVICE_MANAGEMENT 97 { &g_MemBalloon, NIL_RTTHREAD, false, false, false, false }, 98 { &g_VMStatistics, NIL_RTTHREAD, false, false, false, false }, 95 99 #endif 96 100 }; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r26136 r26292 146 146 extern VBOXSERVICE g_Exec; 147 147 extern VBOXSERVICE g_CpuHotPlug; 148 #ifdef VBOXSERVICE_MANAGEMENT 149 extern VBOXSERVICE g_MemBalloon; 150 extern VBOXSERVICE g_VMStatistics; 151 #endif 148 152 149 153 #ifdef RT_OS_WINDOWS -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
r26282 r26292 23 23 #include <psapi.h> 24 24 #include "VBoxTray.h" 25 #include "VBoxStatistics.h"26 #include "VBoxMemBalloon.h"27 25 #include <VBoxDisplay.h> 28 26 #include <VBox/VMMDev.h> … … 35 33 typedef struct _VBOXSTATSCONTEXT 36 34 { 37 const VBOXSERVICEENV *pEnv;38 35 uint32_t uStatInterval; 39 36 … … 42 39 uint64_t ullLastCpuLoad_User; 43 40 41 #ifdef RT_OS_WINDOWS 44 42 NTSTATUS (WINAPI *pfnNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength); 45 43 void (WINAPI *pfnGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer); 46 44 BOOL (WINAPI *pfnGetPerformanceInfo)(PPERFORMANCE_INFORMATION pPerformanceInformation, DWORD cb); 45 #endif 47 46 } VBOXSTATSCONTEXT; 48 47 49 48 /******************************************************************************* 49 * Global Variables * 50 *******************************************************************************/ 50 51 static VBOXSTATSCONTEXT gCtx = {0}; 51 52 52 53 int VBoxStatsInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread) 54 { 55 HANDLE gVBoxDriver = pEnv->hDriver; 56 DWORD cbReturned; 57 58 Log(("VBoxStatsInit\n")); 53 /** The semaphore we're blocking on. */ 54 static RTSEMEVENTMULTI g_VMStatEvent = NIL_RTSEMEVENTMULTI; 55 /** The vmstats interval (millseconds). */ 56 uint32_t g_VMStatsInterval = 0; 57 58 59 /** @copydoc VBOXSERVICE::pfnPreInit */ 60 static DECLCALLBACK(int) VBoxServiceVMStatsPreInit(void) 61 { 62 return VINF_SUCCESS; 63 } 64 65 66 /** @copydoc VBOXSERVICE::pfnOption */ 67 static DECLCALLBACK(int) VBoxServiceVMStatsOption(const char **ppszShort, int argc, char **argv, int *pi) 68 { 69 int rc = -1; 70 if (ppszShort) 71 /* no short options */; 72 else if (!strcmp(argv[*pi], "--vmstats-interval")) 73 rc = VBoxServiceArgUInt32(argc, argv, "", pi, 74 &g_VMStatsInterval, 1000, UINT32_MAX - 1); 75 return rc; 76 } 77 78 79 /** @copydoc VBOXSERVICE::pfnInit */ 80 static DECLCALLBACK(int) VBoxServiceVMStatsInit(void) 81 { 82 VBoxServiceVerbose(3, "VBoxServiceVMStatsInit\n"); 83 84 int rc = RTSemEventMultiCreate(&g_VMStatEvent); 85 AssertRCReturn(rc, rc); 59 86 60 87 gCtx.pEnv = pEnv; … … 76 103 Log(("VBoxStatsInit: DeviceIoControl failed with %d\n", GetLastError())); 77 104 105 #ifdef RT_OS_WINDOWS 78 106 /* NtQuerySystemInformation might be dropped in future releases, so load it dynamically as per Microsoft's recommendation */ 79 107 HMODULE hMod = LoadLibrary("NTDLL.DLL"); … … 82 110 *(uintptr_t *)&gCtx.pfnNtQuerySystemInformation = (uintptr_t)GetProcAddress(hMod, "NtQuerySystemInformation"); 83 111 if (gCtx.pfnNtQuerySystemInformation) 84 Log(("gCtx.pfnNtQuerySystemInformation = %x\n", gCtx.pfnNtQuerySystemInformation));112 VBoxServiceVerbose(3, "VBoxStatsInit: gCtx.pfnNtQuerySystemInformation = %x\n", gCtx.pfnNtQuerySystemInformation); 85 113 else 86 114 { 87 Log(("NTDLL.NtQuerySystemInformation not found!!\n"));115 VBoxServiceError("VBoxStatsInit: NTDLL.NtQuerySystemInformation not found!!\n"); 88 116 return VERR_NOT_IMPLEMENTED; 89 117 } … … 96 124 *(uintptr_t *)&gCtx.pfnGlobalMemoryStatusEx = (uintptr_t)GetProcAddress(hMod, "GlobalMemoryStatusEx"); 97 125 if (gCtx.pfnGlobalMemoryStatusEx) 98 Log(("gCtx.GlobalMemoryStatusEx = %x\n", gCtx.pfnGlobalMemoryStatusEx));126 VBoxServiceVerbose(3, "VBoxStatsInit: gCtx.GlobalMemoryStatusEx = %x\n", gCtx.pfnGlobalMemoryStatusEx); 99 127 else 100 128 { 101 129 /** @todo now fails in NT4; do we care? */ 102 Log(("KERNEL32.GlobalMemoryStatusEx not found!!\n"));130 VBoxServiceError("VBoxStatsInit: KERNEL32.GlobalMemoryStatusEx not found!!\n"); 103 131 return VERR_NOT_IMPLEMENTED; 104 132 } … … 110 138 *(uintptr_t *)&gCtx.pfnGetPerformanceInfo = (uintptr_t)GetProcAddress(hMod, "GetPerformanceInfo"); 111 139 if (gCtx.pfnGetPerformanceInfo) 112 Log(("gCtx.pfnGetPerformanceInfo= %x\n", gCtx.pfnGetPerformanceInfo));140 VBoxServiceVerbose(3, "VBoxStatsInit: gCtx.pfnGetPerformanceInfo= %x\n", gCtx.pfnGetPerformanceInfo); 113 141 /* failure is not fatal */ 114 142 } 115 116 *pfStartThread = true; 117 *ppInstance = &gCtx; 143 #endif /* RT_OS_WINDOWS */ 144 118 145 return VINF_SUCCESS; 119 146 } 120 147 121 148 122 void VBoxStatsDestroy(const VBOXSERVICEENV *pEnv, void *pInstance) 123 { 124 Log(("VBoxStatsDestroy\n")); 125 return; 126 } 127 128 void VBoxStatsReportStatistics(VBOXSTATSCONTEXT *pCtx) 149 static void VBoxServiceVMStatsReport(VBOXSTATSCONTEXT *pCtx) 129 150 { 130 151 SYSTEM_INFO systemInfo; … … 235 256 } 236 257 237 /** 238 * Thread function to wait for and process seamless mode change 239 * requests 240 */ 241 unsigned __stdcall VBoxStatsThread(void *pInstance) 258 /** @copydoc VBOXSERVICE::pfnWorker */ 259 DECLCALLBACK(int) VBoxServiceVMStatsWorker(bool volatile *pfShutdown) 242 260 { 243 261 VBOXSTATSCONTEXT *pCtx = (VBOXSTATSCONTEXT *)pInstance; … … 247 265 DWORD cbReturned; 248 266 267 int rc = VINF_SUCCESS; 268 269 /* 270 * Tell the control thread that it can continue 271 * spawning services. 272 */ 273 RTThreadUserSignal(RTThreadSelf()); 274 249 275 maskInfo.u32OrMask = VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST; 250 276 maskInfo.u32NotMask = 0; … … 259 285 } 260 286 261 do 262 { 263 /* wait for a seamless change event */ 264 VBoxGuestWaitEventInfo waitEvent; 265 waitEvent.u32TimeoutIn = (pCtx->uStatInterval) ? pCtx->uStatInterval : 5000; 266 waitEvent.u32EventMaskIn = VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST; 267 if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL)) 268 { 269 Log(("VBoxStatsThread: DeviceIOControl succeded\n")); 270 271 /* are we supposed to stop? */ 272 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0) 273 break; 274 275 Log(("VBoxStatsThread: checking event\n")); 276 277 /* did we get the right event? */ 278 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST) 279 { 280 VMMDevGetStatisticsChangeRequest req; 281 vmmdevInitRequest(&req.header, VMMDevReq_GetStatisticsChangeRequest); 282 req.eventAck = VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST; 283 284 if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_VMMREQUEST(req.header.size), &req, req.header.size, &req, req.header.size, &cbReturned, NULL)) 285 { 286 Log(("VBoxStatsThread: new statistics interval %d seconds\n", req.u32StatInterval)); 287 pCtx->uStatInterval = req.u32StatInterval * 1000; 288 } 289 else 290 Log(("VBoxStatsThread: DeviceIoControl (stat) failed with %d\n", GetLastError())); 291 } 292 } 293 else 294 { 295 Log(("VBoxStatsThread: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n")); 296 297 /* sleep a bit to not eat too much CPU in case the above call always fails */ 298 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0) 299 { 300 fTerminate = true; 301 break; 302 } 303 } 287 /* 288 * Now enter the loop retrieving runtime data continuously. 289 */ 290 for (;;) 291 { 304 292 /* Report statistics to the host */ 305 if ( gCtx.uStatInterval 306 && gCtx.pfnNtQuerySystemInformation) 307 { 308 VBoxStatsReportStatistics(pCtx); 309 } 310 } 311 while (!fTerminate); 293 if (gCtx.pfnNtQuerySystemInformation) 294 { 295 VBoxServiceVMStatsReport(); 296 } 297 298 /* 299 * Block for a while. 300 * 301 * The event semaphore takes care of ignoring interruptions and it 302 * allows us to implement service wakeup later. 303 */ 304 if (*pfShutdown) 305 break; 306 int rc2 = RTSemEventMultiWait(g_VMStatEvent, g_VMStatsInterval); 307 if (*pfShutdown) 308 break; 309 if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2)) 310 { 311 VBoxServiceError("RTSemEventMultiWait failed; rc2=%Rrc\n", rc2); 312 rc = rc2; 313 break; 314 } 315 } 312 316 313 317 maskInfo.u32OrMask = 0; … … 322 326 } 323 327 328 RTSemEventMultiDestroy(g_VMStatsEvent); 329 g_VMStatsEvent = NIL_RTSEMEVENTMULTI; 330 324 331 Log(("VBoxStatsThread: finished statistics change request thread\n")); 325 332 return 0; … … 327 334 328 335 336 /** @copydoc VBOXSERVICE::pfnTerm */ 337 static DECLCALLBACK(void) VBoxServiceVMStatsTerm(void) 338 { 339 VBoxServiceVerbose(3, "VBoxServiceVMStatsTerm\n"); 340 return; 341 } 342 343 344 /** @copydoc VBOXSERVICE::pfnStop */ 345 static DECLCALLBACK(void) VBoxServiceVMStatsStop(void) 346 { 347 RTSemEventMultiSignal(g_VMStatsEvent); 348 } 349 350 351 /** 352 * The 'vminfo' service description. 353 */ 354 VBOXSERVICE g_VMStatistics = 355 { 356 /* pszName. */ 357 "vmstats", 358 /* pszDescription. */ 359 "Virtual Machine Statistics", 360 /* pszUsage. */ 361 "[--vmstats-interval <ms>]" 362 , 363 /* pszOptions. */ 364 " --vmstats-interval Specifies the interval at which to retrieve the\n" 365 " VM statistcs. The default is 10000 ms.\n" 366 , 367 /* methods */ 368 VBoxServiceVMStatsPreInit, 369 VBoxServiceVMStatsOption, 370 VBoxServiceVMStatsInit, 371 VBoxServiceVMStatsWorker, 372 VBoxServiceVMStatsStop, 373 VBoxServiceVMStatsTerm 374 };
Note:
See TracChangeset
for help on using the changeset viewer.