Changeset 12594 in vbox for trunk/src/VBox/Main/win
- Timestamp:
- Sep 19, 2008 9:45:17 AM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 36831
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/win/PerformanceWin.cpp
r12537 r12594 22 22 */ 23 23 24 /* @todo Replace the following _WIN32_WINNT override with proper diagnostic: 25 #if (_WIN32_WINNT < 0x0501) 24 #ifndef _WIN32_WINNT 25 #define _WIN32_WINNT 0x0500 26 #else /* !_WIN32_WINNT */ 27 #if (_WIN32_WINNT < 0x0500) 26 28 #error Win XP or later required! 27 #endif 28 */ 29 #ifdef _WIN32_WINNT 30 #if (_WIN32_WINNT < 0x0501) 31 #undef _WIN32_WINNT 32 #define _WIN32_WINNT 0x0501 33 #endif 34 #else 35 #define _WIN32_WINNT 0x0501 36 #endif 29 #endif /* _WIN32_WINNT < 0x0500 */ 30 #endif /* !_WIN32_WINNT */ 31 37 32 #include <windows.h> 38 33 #include <winternl.h> 39 34 #include <psapi.h> 40 35 extern "C" { 41 36 #include <powrprof.h> 42 37 } 38 43 39 #include <iprt/err.h> 44 40 #include <iprt/mp.h> … … 50 46 #include "Performance.h" 51 47 48 #ifndef NT_ERROR 49 #define NT_ERROR(Status) ((ULONG)(Status) >> 30 == 3) 50 #endif 51 52 52 namespace pm { 53 53 … … 55 55 { 56 56 public: 57 CollectorWin(); 58 virtual ~CollectorWin(); 57 59 virtual int preCollect(const CollectorHints& hints); 58 60 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle); … … 76 78 77 79 VMProcessMap mProcessStats; 80 81 typedef BOOL (WINAPI *PFNGST)( 82 LPFILETIME lpIdleTime, 83 LPFILETIME lpKernelTime, 84 LPFILETIME lpUserTime); 85 typedef NTSTATUS (WINAPI *PFNNQSI)( 86 SYSTEM_INFORMATION_CLASS SystemInformationClass, 87 PVOID SystemInformation, 88 ULONG SystemInformationLength, 89 PULONG ReturnLength); 90 91 PFNGST mpfnGetSystemTimes; 92 PFNNQSI mpfnNtQuerySystemInformation; 93 HMODULE mhNtDll; 78 94 }; 79 95 … … 81 97 { 82 98 return new CollectorWin(); 99 } 100 101 CollectorWin::CollectorWin() : mhNtDll(0) 102 { 103 mpfnGetSystemTimes = (PFNGST)GetProcAddress( 104 GetModuleHandle(TEXT("kernel32.dll")), 105 "GetSystemTimes"); 106 if (!mpfnGetSystemTimes) 107 { 108 /* Fall back to deprecated NtQuerySystemInformation */ 109 if (!(mhNtDll = LoadLibrary(TEXT("ntdll.dll")))) 110 { 111 LogRel(("Failed to load NTDLL.DLL with error 0x%x. GetSystemTimes() is" 112 " not available either. CPU and VM metrics will not be collected.\n", 113 GetLastError())); 114 mpfnNtQuerySystemInformation = 0; 115 } 116 else if (!(mpfnNtQuerySystemInformation = (PFNNQSI)GetProcAddress(mhNtDll, 117 "NtQuerySystemInformation"))) 118 { 119 LogRel(("Neither GetSystemTimes() nor NtQuerySystemInformation() is" 120 " not available. CPU and VM metrics will not be collected.\n")); 121 mpfnNtQuerySystemInformation = 0; 122 } 123 } 124 } 125 126 CollectorWin::~CollectorWin() 127 { 128 if (mhNtDll) 129 FreeLibrary(mhNtDll); 83 130 } 84 131 … … 158 205 } 159 206 207 typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION 208 { 209 LARGE_INTEGER IdleTime; 210 LARGE_INTEGER KernelTime; 211 LARGE_INTEGER UserTime; 212 LARGE_INTEGER Reserved1[2]; 213 ULONG Reserved2; 214 } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; 215 160 216 int CollectorWin::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle) 161 217 { … … 164 220 FILETIME ftIdle, ftKernel, ftUser; 165 221 166 if (!GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) 167 { 168 DWORD dwError = GetLastError(); 169 Log (("GetSystemTimes() -> 0x%x\n", dwError)); 170 return RTErrConvertFromWin32(dwError); 171 } 172 173 *user = FILETTIME_TO_100NS(ftUser); 174 *idle = FILETTIME_TO_100NS(ftIdle); 175 *kernel = FILETTIME_TO_100NS(ftKernel) - *idle; 222 if (mpfnGetSystemTimes) 223 { 224 if (!mpfnGetSystemTimes(&ftIdle, &ftKernel, &ftUser)) 225 { 226 DWORD dwError = GetLastError(); 227 Log (("GetSystemTimes() -> 0x%x\n", dwError)); 228 return RTErrConvertFromWin32(dwError); 229 } 230 231 *user = FILETTIME_TO_100NS(ftUser); 232 *idle = FILETTIME_TO_100NS(ftIdle); 233 *kernel = FILETTIME_TO_100NS(ftKernel) - *idle; 234 } 235 else 236 { 237 /* GetSystemTimes is not available, fall back to NtQuerySystemInformation */ 238 if (!mpfnNtQuerySystemInformation) 239 return VERR_NOT_IMPLEMENTED; 240 241 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION sppi[MAXIMUM_PROCESSORS]; 242 ULONG ulReturned; 243 NTSTATUS status = mpfnNtQuerySystemInformation( 244 SystemProcessorPerformanceInformation, &sppi, sizeof(sppi), &ulReturned); 245 if (NT_ERROR(status)) 246 { 247 Log(("NtQuerySystemInformation() -> 0x%x\n", status)); 248 return RTErrConvertFromNtStatus(status); 249 } 250 /* Sum up values accross all processors */ 251 *user = *kernel = *idle = 0; 252 for (unsigned i = 0; i < ulReturned / sizeof(sppi[0]); ++i) 253 { 254 *idle += sppi[i].IdleTime.QuadPart; 255 *kernel += sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart; 256 *user += sppi[i].UserTime.QuadPart; 257 } 258 } 176 259 177 260 LogFlowThisFunc(("user=%lu kernel=%lu idle=%lu\n", *user, *kernel, *idle));
Note:
See TracChangeset
for help on using the changeset viewer.