Changeset 12400 in vbox
- Timestamp:
- Sep 11, 2008 10:34:58 AM (16 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HostImpl.cpp
r12338 r12400 2879 2879 void Host::registerMetrics (PerformanceCollector *aCollector) 2880 2880 { 2881 pm:: MetricFactory *metricFactory = aCollector->getMetricFactory();2881 pm::CollectorHAL *hal = aCollector->getHAL(); 2882 2882 /* Create sub metrics */ 2883 2883 pm::SubMetric *cpuLoadUser = new pm::SubMetric ("CPU/Load/User", … … 2899 2899 ComObjPtr <Host> tmp = this; 2900 2900 tmp.queryInterfaceTo (&objptr); 2901 pm::BaseMetric *cpuLoad = 2902 metricFactory->createHostCpuLoad (objptr, cpuLoadUser, cpuLoadKernel, 2901 pm::BaseMetric *cpuLoad = new pm::HostCpuLoadRaw (hal, objptr, cpuLoadUser, cpuLoadKernel, 2903 2902 cpuLoadIdle); 2904 2903 aCollector->registerBaseMetric (cpuLoad); 2905 pm::BaseMetric *cpuMhz = 2906 metricFactory->createHostCpuMHz (objptr, cpuMhzSM); 2904 pm::BaseMetric *cpuMhz = new pm::HostCpuMhz (hal, objptr, cpuMhzSM); 2907 2905 aCollector->registerBaseMetric (cpuMhz); 2908 pm::BaseMetric *ramUsage = 2909 metricFactory->createHostRamUsage (objptr, ramUsageTotal, ramUsageUsed, 2906 pm::BaseMetric *ramUsage = new pm::HostRamUsage (hal, objptr, ramUsageTotal, ramUsageUsed, 2910 2907 ramUsageFree); 2911 2908 aCollector->registerBaseMetric (ramUsage); -
trunk/src/VBox/Main/MachineImpl.cpp
r12066 r12400 7612 7612 void Machine::registerMetrics (PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid) 7613 7613 { 7614 pm:: MetricFactory *metricFactory = aCollector->getMetricFactory();7614 pm::CollectorHAL *hal = aCollector->getHAL(); 7615 7615 /* Create sub metrics */ 7616 7616 pm::SubMetric *cpuLoadUser = new pm::SubMetric ("CPU/Load/User", … … 7625 7625 ComObjPtr<Machine> tmp = aMachine; 7626 7626 tmp.queryInterfaceTo (&objptr); 7627 pm::BaseMetric *cpuLoad = 7628 metricFactory->createMachineCpuLoad (objptr, pid, 7627 pm::BaseMetric *cpuLoad = new pm::MachineCpuLoadRaw (hal, objptr, pid, 7629 7628 cpuLoadUser, cpuLoadKernel); 7630 7629 aCollector->registerBaseMetric (cpuLoad); 7631 pm::BaseMetric *ramUsage = 7632 metricFactory->createMachineRamUsage (objptr, pid,ramUsageUsed);7630 pm::BaseMetric *ramUsage = new pm::MachineRamUsage (hal, objptr, pid, 7631 ramUsageUsed); 7633 7632 aCollector->registerBaseMetric (ramUsage); 7634 7633 -
trunk/src/VBox/Main/Performance.cpp
r12024 r12400 36 36 #include <iprt/cpuset.h> 37 37 38 #include <algorithm> 39 38 40 #include "Logging.h" 39 41 #include "Performance.h" 40 42 41 43 using namespace pm; 42 43 // Default factory44 45 BaseMetric *MetricFactory::createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)46 {47 Assert(mHAL);48 return new HostCpuLoadRaw(mHAL, object, user, kernel, idle);49 }50 BaseMetric *MetricFactory::createHostCpuMHz(ComPtr<IUnknown> object, SubMetric *mhz)51 {52 Assert(mHAL);53 return new HostCpuMhz(mHAL, object, mhz);54 }55 BaseMetric *MetricFactory::createHostRamUsage(ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)56 {57 Assert(mHAL);58 return new HostRamUsage(mHAL, object, total, used, available);59 }60 BaseMetric *MetricFactory::createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)61 {62 Assert(mHAL);63 return new MachineCpuLoadRaw(mHAL, object, process, user, kernel);64 }65 BaseMetric *MetricFactory::createMachineRamUsage(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)66 {67 Assert(mHAL);68 return new MachineRamUsage(mHAL, object, process, used);69 }70 44 71 45 // Stubs for non-pure virtual methods … … 126 100 } 127 101 128 voidBaseMetric::collectorBeat(uint64_t nowAt)102 bool BaseMetric::collectorBeat(uint64_t nowAt) 129 103 { 130 104 if (isEnabled()) … … 135 109 Log4(("{%p} " LOG_FN_FMT ": Collecting %s for obj(%p)...\n", 136 110 this, __PRETTY_FUNCTION__, getName(), (void *)mObject)); 137 collect(); 138 } 139 } 111 return true; 112 } 113 } 114 return false; 140 115 } 141 116 … … 165 140 mIdle->put(idle); 166 141 } 142 } 143 144 void HostCpuLoadRaw::preCollect(CollectorHints& hints) 145 { 146 hints.collectHostCpuLoad(); 167 147 } 168 148 … … 226 206 } 227 207 208 void HostRamUsage::preCollect(CollectorHints& hints) 209 { 210 hints.collectHostRamUsage(); 211 } 212 228 213 void HostRamUsage::collect() 229 214 { … … 259 244 } 260 245 246 void MachineCpuLoadRaw::preCollect(CollectorHints& hints) 247 { 248 hints.collectProcessCpuLoad(mProcess); 249 } 250 261 251 void MachineCpuLoadRaw::collect() 262 252 { … … 289 279 mLength = length; 290 280 mUsed->init(mLength); 281 } 282 283 void MachineRamUsage::preCollect(CollectorHints& hints) 284 { 285 hints.collectProcessRamUsage(mProcess); 291 286 } 292 287 -
trunk/src/VBox/Main/PerformanceImpl.cpp
r11583 r12400 108 108 HRESULT rc = S_OK; 109 109 110 /* @todo Obviously other platforms must be added as well. */ 111 #ifdef RT_OS_SOLARIS 112 m.factory = new pm::MetricFactorySolaris(); 113 #endif 114 #ifdef RT_OS_LINUX 115 m.factory = new pm::MetricFactoryLinux(); 116 #endif 117 #ifdef RT_OS_WINDOWS 118 m.factory = new pm::MetricFactoryWin(); 119 #endif 120 #ifdef RT_OS_OS2 121 m.factory = new pm::MetricFactoryOS2(); 122 #endif 123 #ifdef RT_OS_DARWIN 124 m.factory = new pm::MetricFactoryDarwin(); 125 #endif 110 m.hal = pm::createHAL(); 126 111 127 112 /* Let the sampler know it gets a valid collector. */ … … 170 155 m.sampler = NULL; 171 156 172 delete m.factory; 173 m.factory = NULL; 157 //delete m.factory; 158 //m.factory = NULL; 159 160 delete m.hal; 161 m.hal = NULL; 174 162 175 163 LogFlowThisFuncLeave(); … … 469 457 AutoWriteLock alock (this); 470 458 459 pm::CollectorHints hints; 471 460 uint64_t timestamp = RTTimeMilliTS(); 461 BaseMetricList toBeCollected; 462 BaseMetricList::iterator it; 463 /* Compose the list of metrics being collected at this moment */ 464 for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); it++) 465 if ((*it)->collectorBeat(timestamp)) 466 { 467 (*it)->preCollect(hints); 468 toBeCollected.push_back(*it); 469 } 470 471 /* Let know the platform specific code what is being collected */ 472 m.hal->preCollect(hints); 473 474 /* Finally, collect the data */ 472 475 std::for_each (m.baseMetrics.begin(), m.baseMetrics.end(), 473 std::bind2nd (std::mem_fun (&pm::BaseMetric::collectorBeat), 474 timestamp)); 476 std::mem_fun (&pm::BaseMetric::collect)); 475 477 Log4(("{%p} " LOG_FN_FMT ": LEAVE\n", this, __PRETTY_FUNCTION__)); 476 478 } -
trunk/src/VBox/Main/darwin/PerformanceDarwin.cpp
r12133 r12400 74 74 }; 75 75 76 MetricFactoryDarwin::MetricFactoryDarwin()76 CollectorHAL *createHAL() 77 77 { 78 mHAL = new CollectorDarwin(); 79 Assert(mHAL); 78 return new CollectorDarwin(); 80 79 } 81 80 -
trunk/src/VBox/Main/include/Performance.h
r11583 r12400 26 26 #include <VBox/com/defs.h> 27 27 #include <VBox/com/ptr.h> 28 #include <algorithm> 28 29 #include <list> 29 30 #include <string> 31 #include <vector> 30 32 31 33 namespace pm … … 65 67 66 68 /* Collector Hardware Abstraction Layer *********************************/ 69 enum { 70 COLLECT_NONE = 0x0, 71 COLLECT_CPU_LOAD = 0x1, 72 COLLECT_RAM_USAGE = 0x2 73 }; 74 typedef int HintFlags; 75 typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair; 76 77 inline bool processEqual(ProcessFlagsPair pair, RTPROCESS process) 78 { 79 return pair.first == process; 80 } 81 82 class CollectorHints 83 { 84 typedef std::list<ProcessFlagsPair> ProcessList; 85 86 HintFlags mHostFlags; 87 ProcessList mProcesses; 88 89 ProcessFlagsPair& findProcess(RTPROCESS process) 90 { 91 ProcessList::iterator it; 92 93 it = std::find_if(mProcesses.begin(), 94 mProcesses.end(), 95 std::bind2nd(std::ptr_fun(processEqual), process)); 96 97 if (it != mProcesses.end()) 98 return *it; 99 100 /* Not found -- add new */ 101 mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE)); 102 return mProcesses.back(); 103 } 104 105 public: 106 CollectorHints() : mHostFlags(COLLECT_NONE) {} 107 void collectHostCpuLoad() { mHostFlags |= COLLECT_CPU_LOAD; } 108 void collectHostRamUsage() { mHostFlags |= COLLECT_RAM_USAGE; } 109 void collectProcessCpuLoad(RTPROCESS process) 110 { 111 findProcess(process).second |= COLLECT_CPU_LOAD; 112 } 113 void collectProcessRamUsage(RTPROCESS process) 114 { 115 findProcess(process).second |= COLLECT_RAM_USAGE; 116 } 117 bool isHostCpuLoadCollected() { return (mHostFlags & COLLECT_CPU_LOAD) != 0; } 118 bool isHostRamUsageCollected() { return (mHostFlags & COLLECT_RAM_USAGE) != 0; } 119 bool isProcessCpuLoadCollected(RTPROCESS process) 120 { 121 return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; 122 } 123 bool isProcessRamUsageCollected(RTPROCESS process) 124 { 125 return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; 126 } 127 void getProcesses(std::vector<RTPROCESS>& processes) const 128 { 129 processes.clear(); 130 processes.reserve(mProcesses.size()); 131 for (ProcessList::const_iterator it = mProcesses.begin(); it != mProcesses.end(); it++) 132 processes.push_back(it->first); 133 } 134 }; 135 67 136 class CollectorHAL 68 137 { 69 138 public: 139 virtual int preCollect(const CollectorHints& hints) { return VINF_SUCCESS; } 70 140 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle); 71 141 virtual int getHostCpuMHz(ULONG *mhz); … … 78 148 }; 79 149 150 extern CollectorHAL *createHAL(); 151 80 152 /* Base Metrics *********************************************************/ 81 153 class BaseMetric … … 86 158 87 159 virtual void init(ULONG period, ULONG length) = 0; 160 virtual void preCollect(CollectorHints& hints) = 0; 88 161 virtual void collect() = 0; 89 162 virtual const char *getUnit() = 0; … … 91 164 virtual ULONG getMaxValue() = 0; 92 165 93 voidcollectorBeat(uint64_t nowAt);166 bool collectorBeat(uint64_t nowAt); 94 167 95 168 void enable() { mEnabled = true; }; … … 137 210 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {}; 138 211 212 void preCollect(CollectorHints& hints); 139 213 void collect(); 140 214 private: … … 151 225 152 226 void init(ULONG period, ULONG length); 227 void preCollect(CollectorHints& hints) {} 153 228 void collect(); 154 229 const char *getUnit() { return "MHz"; }; … … 166 241 167 242 void init(ULONG period, ULONG length); 243 void preCollect(CollectorHints& hints); 168 244 void collect(); 169 245 const char *getUnit() { return "kB"; }; … … 199 275 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {}; 200 276 277 void preCollect(CollectorHints& hints); 201 278 void collect(); 202 279 private: … … 213 290 214 291 void init(ULONG period, ULONG length); 292 void preCollect(CollectorHints& hints); 215 293 void collect(); 216 294 const char *getUnit() { return "kB"; }; … … 290 368 }; 291 369 292 /* Metric Factories *****************************************************/ 293 class MetricFactory 294 { 295 public: 296 MetricFactory() : mHAL(0) {}; 297 ~MetricFactory() { delete mHAL; }; 298 299 virtual BaseMetric *createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle); 300 virtual BaseMetric *createHostCpuMHz(ComPtr<IUnknown> object, SubMetric *mhz); 301 virtual BaseMetric *createHostRamUsage(ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available); 302 virtual BaseMetric *createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel); 303 virtual BaseMetric *createMachineRamUsage(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used); 304 protected: 305 CollectorHAL *mHAL; 306 }; 307 308 class MetricFactorySolaris : public MetricFactory 309 { 310 public: 311 MetricFactorySolaris(); 312 // Nothing else to do here (yet) 313 }; 314 315 class MetricFactoryLinux : public MetricFactory 316 { 317 public: 318 MetricFactoryLinux(); 319 // Nothing else to do here (yet) 320 }; 321 322 class MetricFactoryWin : public MetricFactory 323 { 324 public: 325 MetricFactoryWin(); 326 // Nothing else to do here (yet) 327 }; 328 329 class MetricFactoryOS2 : public MetricFactory 330 { 331 public: 332 MetricFactoryOS2(); 333 // Nothing else to do here (yet) 334 }; 335 336 class MetricFactoryDarwin : public MetricFactory 337 { 338 public: 339 MetricFactoryDarwin(); 340 // Nothing else to do here (yet) 341 }; 370 /* Filter Class *********************************************************/ 342 371 343 372 class Filter -
trunk/src/VBox/Main/include/PerformanceImpl.h
r11583 r12400 34 34 35 35 #include <list> 36 #include <set>36 //#include <set> 37 37 38 38 #include "Performance.h" … … 107 107 }; 108 108 109 110 #if 0111 class ATL_NO_VTABLE PerformanceData :112 public VirtualBoxBaseNEXT,113 public VirtualBoxSupportTranslation <PerformanceData>,114 public IPerformanceData115 {116 private:117 118 struct Data119 {120 /* Constructor. */121 Data() { }122 123 bool operator== (const Data &that) const124 {125 return this == &that;126 }127 };128 129 public:130 131 VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (PerformanceData)132 133 DECLARE_NOT_AGGREGATABLE (PerformanceData)134 135 DECLARE_PROTECT_FINAL_CONSTRUCT()136 137 BEGIN_COM_MAP(PerformanceData)138 COM_INTERFACE_ENTRY (ISupportErrorInfo)139 COM_INTERFACE_ENTRY (IPerformanceData)140 END_COM_MAP()141 142 NS_DECL_ISUPPORTS143 144 DECLARE_EMPTY_CTOR_DTOR (PerformanceData)145 146 HRESULT FinalConstruct();147 void FinalRelease();148 149 // public initializer/uninitializer for internal purposes only150 HRESULT init (cosnt BSTR aMetricName, IUnknown *anObject,151 ULONG *data, ULONG aLength);152 void uninit();153 154 // IPerformanceData properties155 STDMETHOD(COMGETTER(MetricName)) (BSTR *aMetricName);156 STDMETHOD(COMGETTER(Object)) (IUnknown **anObject);157 STDMETHOD(COMGETTER(Values)) (ComSafeArrayOut (LONG, values));158 159 // IPerformanceData methods160 161 // public methods only for internal purposes162 163 private:164 165 Bstr mMetricName;166 IUnknown *mObject;167 ULONG *mData;168 ULONG mLength;169 };170 #endif171 109 172 110 class ATL_NO_VTABLE PerformanceCollector : … … 232 170 // (ensure there is a caller and a read lock before calling them!) 233 171 234 pm:: MetricFactory *getMetricFactory() { return m.factory; };172 pm::CollectorHAL *getHAL() { return m.hal; }; 235 173 236 174 // for VirtualBoxSupportErrorInfoImpl … … 254 192 struct Data 255 193 { 256 Data() : factory(0) {};194 Data() : hal(0) {}; 257 195 258 196 BaseMetricList baseMetrics; 259 197 MetricList metrics; 260 198 RTTIMERLR sampler; 261 pm:: MetricFactory *factory;199 pm::CollectorHAL *hal; 262 200 }; 263 201 -
trunk/src/VBox/Main/linux/PerformanceLinux.cpp
r11498 r12400 43 43 }; 44 44 45 // Linux Metric factory 46 47 MetricFactoryLinux::MetricFactoryLinux() 45 CollectorHAL *createHAL() 48 46 { 49 mHAL = new CollectorLinux(); 50 Assert(mHAL); 47 return new CollectorLinux(); 51 48 } 52 49 -
trunk/src/VBox/Main/os2/PerformanceOs2.cpp
r11180 r12400 37 37 38 38 39 MetricFactoryOS2::MetricFactoryOS2()39 CollectorHAL *createHAL() 40 40 { 41 mHAL = new CollectorOS2(); 42 Assert(mHAL); 41 return new CollectorOS2(); 43 42 } 44 43 -
trunk/src/VBox/Main/solaris/PerformanceSolaris.cpp
r11501 r12400 55 55 }; 56 56 57 // Solaris Metric factory 58 59 MetricFactorySolaris::MetricFactorySolaris() 60 { 61 mHAL = new CollectorSolaris(); 62 Assert(mHAL); 57 CollectorHAL *createHAL() 58 { 59 return new CollectorSolaris(); 63 60 } 64 61 -
trunk/src/VBox/Main/testcase/tstCollector.cpp
r12136 r12400 24 24 #include <iprt/runtime.h> 25 25 #include <iprt/stream.h> 26 #include <iprt/env.h> 26 27 #include <iprt/err.h> 27 28 #include <iprt/process.h> … … 66 67 } 67 68 68 #define CALLS_PER_SECOND(n,fn) \ 69 #define RUN_TIME_MS 1000 70 71 #define N_CALLS(n, fn) \ 72 for (int call = 0; call < n; ++call) \ 73 rc = collector->fn; \ 74 if (RT_FAILURE(rc)) \ 75 RTPrintf("tstCollector: "#fn" -> %Vrc\n", rc) 76 77 #define CALLS_PER_SECOND(fn) \ 69 78 nCalls = 0; \ 70 79 start = RTTimeMilliTS(); \ … … 72 81 rc = collector->fn; \ 73 82 ++nCalls; \ 74 } while(RTTimeMilliTS() - start < 1000); \83 } while(RTTimeMilliTS() - start < RUN_TIME_MS); \ 75 84 if (RT_FAILURE(rc)) \ 76 85 { \ … … 78 87 } \ 79 88 else \ 80 RTPrintf("%50s -- %u calls per second\n", #fn, nCalls); \ 81 totalTime += n * 1000000 / nCalls 89 RTPrintf("%70s -- %u calls per second\n", #fn, nCalls) 90 91 void measurePerformance(pm::CollectorHAL *collector, const char *pszName, int cVMs) 92 { 93 94 static const char * const args[] = { pszName, "-child", NULL }; 95 pm::CollectorHints hints; 96 std::vector<RTPROCESS> processes; 97 98 hints.collectHostCpuLoad(); 99 hints.collectHostRamUsage(); 100 /* Start fake VMs */ 101 for (int i = 0; i < cVMs; ++i) 102 { 103 RTPROCESS pid; 104 int rc = RTProcCreate(pszName, args, RTENV_DEFAULT, 0, &pid); 105 if (RT_FAILURE(rc)) 106 { 107 hints.getProcesses(processes); 108 std::for_each(processes.begin(), processes.end(), std::ptr_fun(RTProcTerminate)); 109 RTPrintf("tstCollector: RTProcCreate() -> %Vrc\n", rc); 110 return; 111 } 112 hints.collectProcessCpuLoad(pid); 113 hints.collectProcessRamUsage(pid); 114 } 115 116 hints.getProcesses(processes); 117 RTThreadSleep(30000); // Let children settle for half a minute 118 119 int rc; 120 ULONG tmp; 121 uint64_t tmp64; 122 uint64_t start; 123 unsigned int nCalls; 124 uint32_t totalTime = 0; 125 /* Pre-collect */ 126 CALLS_PER_SECOND(preCollect(hints)); 127 /* Host CPU load */ 128 CALLS_PER_SECOND(getRawHostCpuLoad(&tmp64, &tmp64, &tmp64)); 129 /* Process CPU load */ 130 CALLS_PER_SECOND(getRawProcessCpuLoad(processes[nCalls%cVMs], &tmp64, &tmp64, &tmp64)); 131 /* Host CPU speed */ 132 CALLS_PER_SECOND(getHostCpuMHz(&tmp)); 133 /* Host RAM usage */ 134 CALLS_PER_SECOND(getHostMemoryUsage(&tmp, &tmp, &tmp)); 135 /* Process RAM usage */ 136 CALLS_PER_SECOND(getProcessMemoryUsage(processes[nCalls%cVMs], &tmp)); 137 138 start = RTTimeNanoTS(); 139 140 for (int times = 0; times < 100; times++) 141 { 142 /* Pre-collect */ 143 N_CALLS(1, preCollect(hints)); 144 /* Host CPU load */ 145 N_CALLS(1, getRawHostCpuLoad(&tmp64, &tmp64, &tmp64)); 146 /* Host CPU speed */ 147 N_CALLS(1, getHostCpuMHz(&tmp)); 148 /* Host RAM usage */ 149 N_CALLS(1, getHostMemoryUsage(&tmp, &tmp, &tmp)); 150 /* Process CPU load */ 151 N_CALLS(cVMs, getRawProcessCpuLoad(processes[call], &tmp64, &tmp64, &tmp64)); 152 /* Process RAM usage */ 153 N_CALLS(cVMs, getProcessMemoryUsage(processes[call], &tmp)); 154 } 155 printf("\n%u VMs -- %.2f%% of CPU time\n", cVMs, (RTTimeNanoTS() - start) / 10000000. / times); 156 157 /* Shut down fake VMs */ 158 std::for_each(processes.begin(), processes.end(), std::ptr_fun(RTProcTerminate)); 159 } 82 160 83 161 int main(int argc, char *argv[]) … … 91 169 { 92 170 RTPrintf("tstCollector: RTR3Init() -> %d\n", rc); 171 return 1; 172 } 173 if (argc > 1 && !strcmp(argv[1], "-child")) 174 { 175 /* We have spawned ourselves as a child process -- scratch the leg */ 176 RTThreadSleep(1000000); 93 177 return 1; 94 178 } … … 108 192 #endif 109 193 110 uint64_t start;111 112 194 pm::CollectorHAL *collector = createCollector(); 113 195 if (!collector) … … 116 198 return 1; 117 199 } 118 #if 1 200 #if 0 201 uint64_t start; 202 119 203 uint64_t hostUserStart, hostKernelStart, hostIdleStart; 120 204 uint64_t hostUserStop, hostKernelStop, hostIdleStop, hostTotal; … … 219 303 #endif 220 304 RTPrintf("\ntstCollector: TESTING - Performance\n\n"); 221 unsigned nCalls; 222 ULONG tmp; 223 uint64_t tmp64; 224 uint32_t totalTime = 0; 225 RTPROCESS pid = RTProcSelf(); 226 /* Host CPU load */ 227 CALLS_PER_SECOND(1, getRawHostCpuLoad(&tmp64, &tmp64, &tmp64)); 228 /* Process CPU load */ 229 CALLS_PER_SECOND(100, getRawProcessCpuLoad(pid, &tmp64, &tmp64, &tmp64)); 230 /* Host CPU speed */ 231 CALLS_PER_SECOND(1, getHostCpuMHz(&tmp)); 232 /* Host RAM usage */ 233 CALLS_PER_SECOND(1, getHostMemoryUsage(&tmp, &tmp, &tmp)); 234 /* Process RAM usage */ 235 CALLS_PER_SECOND(100, getProcessMemoryUsage(pid, &tmp)); 236 237 printf("%.2f%% of CPU time\n", totalTime / 10000.); 305 306 measurePerformance(collector, argv[0], 100); 238 307 239 308 delete collector; -
trunk/src/VBox/Main/win/PerformanceWin.cpp
r11467 r12400 29 29 #include <iprt/mp.h> 30 30 31 #include <map> 32 31 33 #include "Logging.h" 32 34 #include "Performance.h" … … 40 42 ~CollectorWin(); 41 43 44 virtual int preCollect(const CollectorHints& hints); 42 45 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle); 43 46 virtual int getHostCpuMHz(ULONG *mhz); … … 69 72 long mProcessCpuLoadTimestampHandle; 70 73 long mProcessMemoryUsedHandle; 74 75 struct VMProcessStats 76 { 77 uint64_t cpuUser; 78 uint64_t cpuKernel; 79 uint64_t cpuTotal; 80 uint64_t ramUsed; 81 }; 82 83 typedef std::map<RTPROCESS, VMProcessStats> VMProcessMap; 84 85 VMProcessMap mProcessStats; 71 86 }; 72 87 73 MetricFactoryWin::MetricFactoryWin() 74 { 75 mHAL = new CollectorWin(); 76 Assert(mHAL); 88 CollectorHAL *createHAL() 89 { 90 return new CollectorWin(); 77 91 } 78 92 … … 265 279 } 266 280 267 int CollectorWin::getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle) 268 { 269 return VERR_NOT_IMPLEMENTED; 270 } 271 272 int CollectorWin::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle) 273 { 281 int CollectorWin::preCollect(const CollectorHints& hints) 282 { 283 284 std::vector<RTPROCESS> processes; 285 hints.getProcesses(processes); 286 274 287 HRESULT hr; 275 288 IWbemObjectAccess **apEnumAccess = NULL; … … 283 296 return VERR_INTERNAL_ERROR; 284 297 } 298 299 int rc = getObjects(mEnumProcess, &apEnumAccess, &dwNumReturned); 300 if (RT_FAILURE(rc)) 301 return rc; 302 303 rc = VERR_NOT_FOUND; 304 305 for (unsigned i = 0; i < dwNumReturned; i++) 306 { 307 DWORD dwIDProcess; 308 309 if (FAILED (hr = apEnumAccess[i]->ReadDWORD( 310 mProcessPIDHandle, 311 &dwIDProcess))) 312 { 313 Log (("Failed to read 'IDProcess' property. HR = %x\n", hr)); 314 return VERR_INTERNAL_ERROR; 315 } 316 LogFlowThisFunc (("Matching process %x against the list of machines...\n", dwIDProcess)); 317 if (std::find(processes.begin(), processes.end(), dwIDProcess) != processes.end()) 318 { 319 VMProcessStats vmStats; 320 321 LogFlowThisFunc (("Match found.\n")); 322 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 323 mProcessCpuLoadUserHandle, 324 &vmStats.cpuUser))) 325 { 326 Log (("Failed to read 'PercentUserTime' property. HR = %x\n", hr)); 327 return VERR_INTERNAL_ERROR; 328 } 329 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 330 mProcessCpuLoadKernelHandle, 331 &vmStats.cpuKernel))) 332 { 333 Log (("Failed to read 'PercentPrivilegedTime' property. HR = %x\n", hr)); 334 return VERR_INTERNAL_ERROR; 335 } 336 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 337 mProcessCpuLoadTimestampHandle, 338 &vmStats.cpuTotal))) 339 { 340 Log (("Failed to read 'Timestamp_Sys100NS' property. HR = %x\n", hr)); 341 return VERR_INTERNAL_ERROR; 342 } 343 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 344 mProcessMemoryUsedHandle, 345 &vmStats.ramUsed))) 346 { 347 Log (("Failed to read 'WorkingSet' property. HR = %x\n", hr)); 348 return VERR_INTERNAL_ERROR; 349 } 350 351 mProcessStats[dwIDProcess] = vmStats; 352 LogFlowThisFunc(("process=%x user=%lu kernel=%lu total=%lu\n", dwIDProcess, vmStats.cpuUser, vmStats.cpuKernel, vmStats.cpuTotal)); 353 rc = VINF_SUCCESS; 354 } 355 apEnumAccess[i]->Release(); 356 apEnumAccess[i] = NULL; 357 } 358 delete [] apEnumAccess; 359 360 LogFlowThisFuncLeave(); 361 362 return rc; 363 } 364 365 int CollectorWin::getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle) 366 { 367 return VERR_NOT_IMPLEMENTED; 368 } 369 370 int CollectorWin::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle) 371 { 372 HRESULT hr; 373 IWbemObjectAccess **apEnumAccess = NULL; 374 DWORD dwNumReturned = 0; 375 376 LogFlowThisFuncEnter(); 285 377 286 378 int rc = getObjects(mEnumProcessor, &apEnumAccess, &dwNumReturned); … … 395 487 int CollectorWin::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total) 396 488 { 397 HRESULT hr; 398 IWbemObjectAccess **apEnumAccess = NULL; 399 DWORD dwNumReturned = 0; 400 401 LogFlowThisFuncEnter(); 402 403 if (FAILED (hr = mRefresher->Refresh(0L))) 404 { 405 Log (("Refresher failed. HR = %x\n", hr)); 489 VMProcessMap::const_iterator it = mProcessStats.find(process); 490 491 if (it == mProcessStats.end()) 492 { 493 Log (("No stats pre-collected for process %x\n", process)); 406 494 return VERR_INTERNAL_ERROR; 407 495 } 408 409 int rc = getObjects(mEnumProcess, &apEnumAccess, &dwNumReturned); 410 if (RT_FAILURE(rc)) 411 return rc; 412 413 rc = VERR_NOT_FOUND; 414 415 for (unsigned i = 0; i < dwNumReturned; i++) 416 { 417 DWORD dwIDProcess; 418 419 if (FAILED (hr = apEnumAccess[i]->ReadDWORD( 420 mProcessPIDHandle, 421 &dwIDProcess))) 422 { 423 Log (("Failed to read 'IDProcess' property. HR = %x\n", hr)); 424 return VERR_INTERNAL_ERROR; 425 } 426 LogFlowThisFunc (("Matching machine process %x against %x...\n", process, dwIDProcess)); 427 if (dwIDProcess == process) 428 { 429 LogFlowThisFunc (("Match found.\n")); 430 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 431 mProcessCpuLoadUserHandle, 432 user))) 433 { 434 Log (("Failed to read 'PercentUserTime' property. HR = %x\n", hr)); 435 return VERR_INTERNAL_ERROR; 436 } 437 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 438 mProcessCpuLoadKernelHandle, 439 kernel))) 440 { 441 Log (("Failed to read 'PercentPrivilegedTime' property. HR = %x\n", hr)); 442 return VERR_INTERNAL_ERROR; 443 } 444 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 445 mProcessCpuLoadTimestampHandle, 446 total))) 447 { 448 Log (("Failed to read 'Timestamp_Sys100NS' property. HR = %x\n", hr)); 449 return VERR_INTERNAL_ERROR; 450 } 451 rc = VINF_SUCCESS; 452 } 453 apEnumAccess[i]->Release(); 454 apEnumAccess[i] = NULL; 455 } 456 delete [] apEnumAccess; 457 458 LogFlowThisFunc(("user=%lu kernel=%lu total=%lu\n", *user, *kernel, *total)); 459 LogFlowThisFuncLeave(); 460 461 return rc; 496 *user = it->second.cpuUser; 497 *kernel = it->second.cpuKernel; 498 *total = it->second.cpuTotal; 499 return VINF_SUCCESS; 462 500 } 463 501 464 502 int CollectorWin::getProcessMemoryUsage(RTPROCESS process, ULONG *used) 465 503 { 466 HRESULT hr; 467 IWbemObjectAccess **apEnumAccess = NULL; 468 DWORD dwNumReturned = 0; 469 470 LogFlowThisFuncEnter(); 471 472 if (FAILED (hr = mRefresher->Refresh(0L))) 473 { 474 Log (("Refresher failed. HR = %x\n", hr)); 504 VMProcessMap::const_iterator it = mProcessStats.find(process); 505 506 if (it == mProcessStats.end()) 507 { 508 Log (("No stats pre-collected for process %x\n", process)); 475 509 return VERR_INTERNAL_ERROR; 476 510 } 477 478 int rc = getObjects(mEnumProcess, &apEnumAccess, &dwNumReturned); 479 if (RT_FAILURE(rc)) 480 return rc; 481 482 rc = VERR_NOT_FOUND; 483 484 for (unsigned i = 0; i < dwNumReturned; i++) 485 { 486 DWORD dwIDProcess; 487 488 if (FAILED (hr = apEnumAccess[i]->ReadDWORD( 489 mProcessPIDHandle, 490 &dwIDProcess))) 491 { 492 Log (("Failed to read 'IDProcess' property. HR = %x\n", hr)); 493 return VERR_INTERNAL_ERROR; 494 } 495 if (dwIDProcess == process) 496 { 497 uint64_t u64used = 0; 498 499 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 500 mProcessMemoryUsedHandle, 501 &u64used))) 502 { 503 Log (("Failed to read 'WorkingSet' property. HR = %x\n", hr)); 504 return VERR_INTERNAL_ERROR; 505 } 506 *used = (ULONG)(u64used / 1024); 507 rc = VINF_SUCCESS; 508 } 509 apEnumAccess[i]->Release(); 510 apEnumAccess[i] = NULL; 511 } 512 delete [] apEnumAccess; 513 514 LogFlowThisFunc(("used=%lu\n", *used)); 515 LogFlowThisFuncLeave(); 516 517 return rc; 518 } 519 520 } 511 *used = (ULONG)(it->second.ramUsed / 1024); 512 return VINF_SUCCESS; 513 } 514 515 }
Note:
See TracChangeset
for help on using the changeset viewer.