void measurePerformance(pm::CollectorHAL *collector, const char *pszName, int cVMs) { static const char * const args[] = { pszName, "-child", NULL }; pm::CollectorHints hints; std::vector<RTPROCESS> processes; hints.collectHostCpuLoad(); hints.collectHostRamUsage(); /* Start fake VMs */ for (int i = 0; i < cVMs; ++i) { RTPROCESS pid; int rc = RTProcCreate(pszName, args, RTENV_DEFAULT, 0, &pid); if (RT_FAILURE(rc)) { hints.getProcesses(processes); std::for_each(processes.begin(), processes.end(), std::ptr_fun(RTProcTerminate)); RTPrintf("tstCollector: RTProcCreate() -> %Rrc\n", rc); return; } hints.collectProcessCpuLoad(pid); hints.collectProcessRamUsage(pid); } hints.getProcesses(processes); RTThreadSleep(30000); // Let children settle for half a minute int rc; ULONG tmp; uint64_t tmp64; uint64_t start; unsigned int nCalls; /* Pre-collect */ CALLS_PER_SECOND(preCollect(hints, 0)); /* Host CPU load */ CALLS_PER_SECOND(getRawHostCpuLoad(&tmp64, &tmp64, &tmp64)); /* Process CPU load */ CALLS_PER_SECOND(getRawProcessCpuLoad(processes[nCalls%cVMs], &tmp64, &tmp64, &tmp64)); /* Host CPU speed */ CALLS_PER_SECOND(getHostCpuMHz(&tmp)); /* Host RAM usage */ CALLS_PER_SECOND(getHostMemoryUsage(&tmp, &tmp, &tmp)); /* Process RAM usage */ CALLS_PER_SECOND(getProcessMemoryUsage(processes[nCalls%cVMs], &tmp)); start = RTTimeNanoTS(); int times; for (times = 0; times < 100; times++) { /* Pre-collect */ N_CALLS(1, preCollect(hints, 0)); /* Host CPU load */ N_CALLS(1, getRawHostCpuLoad(&tmp64, &tmp64, &tmp64)); /* Host CPU speed */ N_CALLS(1, getHostCpuMHz(&tmp)); /* Host RAM usage */ N_CALLS(1, getHostMemoryUsage(&tmp, &tmp, &tmp)); /* Process CPU load */ N_CALLS(cVMs, getRawProcessCpuLoad(processes[call], &tmp64, &tmp64, &tmp64)); /* Process RAM usage */ N_CALLS(cVMs, getProcessMemoryUsage(processes[call], &tmp)); } printf("\n%u VMs -- %.2f%% of CPU time\n", cVMs, (RTTimeNanoTS() - start) / 10000000. / times); /* Shut down fake VMs */ std::for_each(processes.begin(), processes.end(), std::ptr_fun(RTProcTerminate)); }
int CollectorWin::preCollect(const CollectorHints& hints, uint64_t /* iTick */) { LogFlowThisFuncEnter(); uint64_t user, kernel, idle, total; int rc = getRawHostCpuLoad(&user, &kernel, &idle); if (RT_FAILURE(rc)) return rc; total = user + kernel + idle; DWORD dwError; const CollectorHints::ProcessList& processes = hints.getProcessFlags(); CollectorHints::ProcessList::const_iterator it; mProcessStats.clear(); for (it = processes.begin(); it != processes.end() && RT_SUCCESS(rc); it++) { RTPROCESS process = it->first; HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process); if (!h) { dwError = GetLastError(); Log (("OpenProcess() -> 0x%x\n", dwError)); rc = RTErrConvertFromWin32(dwError); break; } VMProcessStats vmStats; if ((it->second & COLLECT_CPU_LOAD) != 0) { FILETIME ftCreate, ftExit, ftKernel, ftUser; if (!GetProcessTimes(h, &ftCreate, &ftExit, &ftKernel, &ftUser)) { dwError = GetLastError(); Log (("GetProcessTimes() -> 0x%x\n", dwError)); rc = RTErrConvertFromWin32(dwError); } else { vmStats.cpuKernel = FILETTIME_TO_100NS(ftKernel); vmStats.cpuUser = FILETTIME_TO_100NS(ftUser); vmStats.cpuTotal = total; } } if (RT_SUCCESS(rc) && (it->second & COLLECT_RAM_USAGE) != 0) { PROCESS_MEMORY_COUNTERS pmc; if (!GetProcessMemoryInfo(h, &pmc, sizeof(pmc))) { dwError = GetLastError(); Log (("GetProcessMemoryInfo() -> 0x%x\n", dwError)); rc = RTErrConvertFromWin32(dwError); } else vmStats.ramUsed = pmc.WorkingSetSize; } CloseHandle(h); mProcessStats[process] = vmStats; } LogFlowThisFuncLeave(); return rc; }