VirtualBox

source: vbox/trunk/src/VBox/Main/include/Performance.h@ 43456

Last change on this file since 43456 was 43456, checked in by vboxsync, 12 years ago

Main/Metrics: Missing interface detection (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.2 KB
Line 
1/* $Id: Performance.h 43456 2012-09-28 06:36:09Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Performance Classes declaration.
4 */
5
6/*
7 * Copyright (C) 2008 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#ifndef ___performance_h
18#define ___performance_h
19
20#include <VBox/com/defs.h>
21#include <VBox/com/ptr.h>
22#include <VBox/com/string.h>
23#include <VBox/com/VirtualBox.h>
24
25#include <iprt/types.h>
26#include <iprt/err.h>
27#include <iprt/cpp/lock.h>
28
29#include <algorithm>
30#include <functional> /* For std::fun_ptr in testcase */
31#include <list>
32#include <vector>
33#include <queue>
34
35/* Forward decl. */
36class Machine;
37
38namespace pm
39{
40 /* CPU load is measured in 1/1000 of per cent. */
41 const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000);
42 /* Network load is measured in 1/1000 of per cent. */
43 const uint64_t PM_NETWORK_LOAD_MULTIPLIER = UINT64_C(100000);
44 /* Sampler precision in milliseconds. */
45 const uint64_t PM_SAMPLER_PRECISION_MS = 50;
46
47 /* Sub Metrics **********************************************************/
48 class CircularBuffer
49 {
50 public:
51 CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
52 ~CircularBuffer() { if (mData) RTMemFree(mData); };
53 void init(ULONG length);
54 ULONG length();
55 ULONG getSequenceNumber() { return mSequenceNumber; }
56 void put(ULONG value);
57 void copyTo(ULONG *data);
58 private:
59 ULONG *mData;
60 ULONG mLength;
61 ULONG mEnd;
62 ULONG mSequenceNumber;
63 bool mWrapped;
64 };
65
66 class SubMetric : public CircularBuffer
67 {
68 public:
69 SubMetric(com::Utf8Str name, const char *description)
70 : mName(name), mDescription(description) {};
71 void query(ULONG *data);
72 const char *getName() { return mName.c_str(); };
73 const char *getDescription() { return mDescription; };
74 private:
75 const com::Utf8Str mName;
76 const char *mDescription;
77 };
78
79
80 enum {
81 COLLECT_NONE = 0x0,
82 COLLECT_CPU_LOAD = 0x1,
83 COLLECT_RAM_USAGE = 0x2,
84 COLLECT_GUEST_STATS = 0x4
85 };
86 typedef int HintFlags;
87 typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair;
88
89 class CollectorHints
90 {
91 public:
92 typedef std::list<ProcessFlagsPair> ProcessList;
93
94 CollectorHints() : mHostFlags(COLLECT_NONE) {}
95 void collectHostCpuLoad()
96 { mHostFlags |= COLLECT_CPU_LOAD; }
97 void collectHostRamUsage()
98 { mHostFlags |= COLLECT_RAM_USAGE; }
99 void collectHostRamVmm()
100 { mHostFlags |= COLLECT_GUEST_STATS; }
101 void collectProcessCpuLoad(RTPROCESS process)
102 { findProcess(process).second |= COLLECT_CPU_LOAD; }
103 void collectProcessRamUsage(RTPROCESS process)
104 { findProcess(process).second |= COLLECT_RAM_USAGE; }
105 void collectGuestStats(RTPROCESS process)
106 { findProcess(process).second |= COLLECT_GUEST_STATS; }
107 bool isHostCpuLoadCollected() const
108 { return (mHostFlags & COLLECT_CPU_LOAD) != 0; }
109 bool isHostRamUsageCollected() const
110 { return (mHostFlags & COLLECT_RAM_USAGE) != 0; }
111 bool isHostRamVmmCollected() const
112 { return (mHostFlags & COLLECT_GUEST_STATS) != 0; }
113 bool isProcessCpuLoadCollected(RTPROCESS process)
114 { return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; }
115 bool isProcessRamUsageCollected(RTPROCESS process)
116 { return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; }
117 bool isGuestStatsCollected(RTPROCESS process)
118 { return (findProcess(process).second & COLLECT_GUEST_STATS) != 0; }
119 void getProcesses(std::vector<RTPROCESS>& processes) const
120 {
121 processes.clear();
122 processes.reserve(mProcesses.size());
123 for (ProcessList::const_iterator it = mProcesses.begin(); it != mProcesses.end(); it++)
124 processes.push_back(it->first);
125 }
126 const ProcessList& getProcessFlags() const
127 {
128 return mProcesses;
129 }
130 private:
131 HintFlags mHostFlags;
132 ProcessList mProcesses;
133
134 ProcessFlagsPair& findProcess(RTPROCESS process)
135 {
136 ProcessList::iterator it;
137 for (it = mProcesses.begin(); it != mProcesses.end(); it++)
138 if (it->first == process)
139 return *it;
140
141 /* Not found -- add new */
142 mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE));
143 return mProcesses.back();
144 }
145 };
146
147 /* Guest Collector Classes *********************************/
148 /*
149 * WARNING! The bits in the following masks must correspond to parameters
150 * of CollectorGuest::updateStats().
151 */
152 typedef enum
153 {
154 GUESTSTATMASK_NONE = 0x00000000,
155 GUESTSTATMASK_CPUUSER = 0x00000001,
156 GUESTSTATMASK_CPUKERNEL = 0x00000002,
157 GUESTSTATMASK_CPUIDLE = 0x00000004,
158 GUESTSTATMASK_MEMTOTAL = 0x00000008,
159 GUESTSTATMASK_MEMFREE = 0x00000010,
160 GUESTSTATMASK_MEMBALLOON = 0x00000020,
161 GUESTSTATMASK_MEMSHARED = 0x00000040,
162 GUESTSTATMASK_MEMCACHE = 0x00000080,
163 GUESTSTATMASK_PAGETOTAL = 0x00000100,
164 GUESTSTATMASK_ALLOCVMM = 0x00000200,
165 GUESTSTATMASK_FREEVMM = 0x00000400,
166 GUESTSTATMASK_BALOONVMM = 0x00000800,
167 GUESTSTATMASK_SHAREDVMM = 0x00001000
168 } GUESTSTATMASK;
169
170 const ULONG GUESTSTATS_CPULOAD =
171 GUESTSTATMASK_CPUUSER|GUESTSTATMASK_CPUKERNEL|GUESTSTATMASK_CPUIDLE;
172 const ULONG GUESTSTATS_RAMUSAGE =
173 GUESTSTATMASK_MEMTOTAL|GUESTSTATMASK_MEMFREE|GUESTSTATMASK_MEMBALLOON|
174 GUESTSTATMASK_MEMSHARED|GUESTSTATMASK_MEMCACHE|
175 GUESTSTATMASK_PAGETOTAL;
176 const ULONG GUESTSTATS_VMMRAM =
177 GUESTSTATMASK_ALLOCVMM|GUESTSTATMASK_FREEVMM|
178 GUESTSTATMASK_BALOONVMM|GUESTSTATMASK_SHAREDVMM;
179 const ULONG GUESTSTATS_ALL = GUESTSTATS_CPULOAD|GUESTSTATS_RAMUSAGE|GUESTSTATS_VMMRAM;
180
181 class CollectorGuest;
182
183 class CollectorGuestRequest
184 {
185 public:
186 CollectorGuestRequest()
187 : mCGuest(0) {};
188 virtual ~CollectorGuestRequest() {};
189 void setGuest(CollectorGuest *aGuest) { mCGuest = aGuest; };
190 CollectorGuest *getGuest() { return mCGuest; };
191 virtual int execute() = 0;
192
193 virtual void debugPrint(void *aObject, const char *aFunction, const char *aText) = 0;
194 protected:
195 CollectorGuest *mCGuest;
196 const char *mDebugName;
197 };
198
199 class CGRQEnable : public CollectorGuestRequest
200 {
201 public:
202 CGRQEnable(ULONG aMask)
203 : mMask(aMask) {};
204 int execute();
205
206 void debugPrint(void *aObject, const char *aFunction, const char *aText);
207 private:
208 ULONG mMask;
209 };
210
211 class CGRQDisable : public CollectorGuestRequest
212 {
213 public:
214 CGRQDisable(ULONG aMask)
215 : mMask(aMask) {};
216 int execute();
217
218 void debugPrint(void *aObject, const char *aFunction, const char *aText);
219 private:
220 ULONG mMask;
221 };
222
223 class CGRQAbort : public CollectorGuestRequest
224 {
225 public:
226 CGRQAbort() {};
227 int execute();
228
229 void debugPrint(void *aObject, const char *aFunction, const char *aText);
230 };
231
232 class CollectorGuestQueue
233 {
234 public:
235 CollectorGuestQueue();
236 ~CollectorGuestQueue();
237 void push(CollectorGuestRequest* rq);
238 CollectorGuestRequest* pop();
239 private:
240 RTCLockMtx mLockMtx;
241 RTSEMEVENT mEvent;
242 std::queue<CollectorGuestRequest*> mQueue;
243 };
244
245 class CollectorGuestManager;
246
247 class CollectorGuest
248 {
249 public:
250 CollectorGuest(Machine *machine, RTPROCESS process);
251 ~CollectorGuest();
252
253 void setManager(CollectorGuestManager *aManager)
254 { mManager = aManager; };
255 bool isUnregistered() { return mUnregistered; };
256 bool isEnabled() { return mEnabled != 0; };
257 bool isValid(ULONG mask) { return (mValid & mask) == mask; };
258 void invalidate(ULONG mask) { mValid &= ~mask; };
259 void unregister() { mUnregistered = true; };
260 void updateStats(ULONG aValidStats, ULONG aCpuUser,
261 ULONG aCpuKernel, ULONG aCpuIdle,
262 ULONG aMemTotal, ULONG aMemFree,
263 ULONG aMemBalloon, ULONG aMemShared,
264 ULONG aMemCache, ULONG aPageTotal,
265 ULONG aAllocVMM, ULONG aFreeVMM,
266 ULONG aBalloonedVMM, ULONG aSharedVMM);
267 int enable(ULONG mask);
268 int disable(ULONG mask);
269
270 int enqueueRequest(CollectorGuestRequest *aRequest);
271 int enableInternal(ULONG mask);
272 int disableInternal(ULONG mask);
273
274 const com::Utf8Str& getVMName() const { return mMachineName; };
275
276 RTPROCESS getProcess() { return mProcess; };
277 ULONG getCpuUser() { return mCpuUser; };
278 ULONG getCpuKernel() { return mCpuKernel; };
279 ULONG getCpuIdle() { return mCpuIdle; };
280 ULONG getMemTotal() { return mMemTotal; };
281 ULONG getMemFree() { return mMemFree; };
282 ULONG getMemBalloon() { return mMemBalloon; };
283 ULONG getMemShared() { return mMemShared; };
284 ULONG getMemCache() { return mMemCache; };
285 ULONG getPageTotal() { return mPageTotal; };
286 ULONG getAllocVMM() { return mAllocVMM; };
287 ULONG getFreeVMM() { return mFreeVMM; };
288 ULONG getBalloonedVMM() { return mBalloonedVMM; };
289 ULONG getSharedVMM() { return mSharedVMM; };
290
291 private:
292 int enableVMMStats(bool mCollectVMMStats);
293
294 CollectorGuestManager *mManager;
295
296 bool mUnregistered;
297 ULONG mEnabled;
298 ULONG mValid;
299 Machine *mMachine;
300 com::Utf8Str mMachineName;
301 RTPROCESS mProcess;
302 ComPtr<IConsole> mConsole;
303 ComPtr<IGuest> mGuest;
304 ULONG mCpuUser;
305 ULONG mCpuKernel;
306 ULONG mCpuIdle;
307 ULONG mMemTotal;
308 ULONG mMemFree;
309 ULONG mMemBalloon;
310 ULONG mMemShared;
311 ULONG mMemCache;
312 ULONG mPageTotal;
313 ULONG mAllocVMM;
314 ULONG mFreeVMM;
315 ULONG mBalloonedVMM;
316 ULONG mSharedVMM;
317 };
318
319 typedef std::list<CollectorGuest*> CollectorGuestList;
320 class CollectorGuestManager
321 {
322 public:
323 CollectorGuestManager();
324 ~CollectorGuestManager();
325 void registerGuest(CollectorGuest* pGuest);
326 void unregisterGuest(CollectorGuest* pGuest);
327 CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; };
328 void preCollect(CollectorHints& hints, uint64_t iTick);
329 void destroyUnregistered();
330 int enqueueRequest(CollectorGuestRequest *aRequest);
331
332 CollectorGuest *getBlockedGuest() { return mGuestBeingCalled; };
333
334 static DECLCALLBACK(int) requestProcessingThread(RTTHREAD aThread, void *pvUser);
335 private:
336 RTTHREAD mThread;
337 CollectorGuestList mGuests;
338 CollectorGuest *mVMMStatsProvider;
339 CollectorGuestQueue mQueue;
340 CollectorGuest *mGuestBeingCalled;
341 };
342
343 /* Collector Hardware Abstraction Layer *********************************/
344 class CollectorHAL
345 {
346 public:
347 CollectorHAL() {};
348 virtual ~CollectorHAL() { };
349 virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
350 /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
351 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
352 /** Returns the average frequency in MHz across all host's CPUs. */
353 virtual int getHostCpuMHz(ULONG *mhz);
354 /** Returns the amount of physical memory in kilobytes. */
355 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
356 /** Returns CPU usage in 1/1000th per cent by a particular process. */
357 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
358 /** Returns the amount of memory used by a process in kilobytes. */
359 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
360
361 /** Returns CPU usage counters in platform-specific units. */
362 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
363 /** Returns received and transmitted bytes as well as link speed. */
364 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx, uint64_t *speed);
365 /** Returns process' CPU usage counter in platform-specific units. */
366 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
367 };
368
369 extern CollectorHAL *createHAL();
370
371 /* Base Metrics *********************************************************/
372 class BaseMetric
373 {
374 public:
375 BaseMetric(CollectorHAL *hal, const com::Utf8Str name, ComPtr<IUnknown> object)
376 : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object),
377 mLastSampleTaken(0), mEnabled(false), mUnregistered(false) {};
378 virtual ~BaseMetric() {};
379
380 virtual void init(ULONG period, ULONG length) = 0;
381 virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
382 virtual void collect() = 0;
383 virtual const char *getUnit() = 0;
384 virtual ULONG getMinValue() = 0;
385 virtual ULONG getMaxValue() = 0;
386 virtual ULONG getScale() = 0;
387
388 bool collectorBeat(uint64_t nowAt);
389
390 virtual int enable() { mEnabled = true; return S_OK; };
391 virtual int disable() { mEnabled = false; return S_OK; };
392 void unregister() { mUnregistered = true; };
393
394 bool isUnregistered() { return mUnregistered; };
395 bool isEnabled() { return mEnabled; };
396 ULONG getPeriod() { return mPeriod; };
397 ULONG getLength() { return mLength; };
398 const char *getName() { return mName.c_str(); };
399 ComPtr<IUnknown> getObject() { return mObject; };
400 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
401
402 protected:
403 ULONG mPeriod;
404 ULONG mLength;
405 CollectorHAL *mHAL;
406 const com::Utf8Str mName;
407 ComPtr<IUnknown> mObject;
408 uint64_t mLastSampleTaken;
409 bool mEnabled;
410 bool mUnregistered;
411 };
412
413 class BaseGuestMetric : public BaseMetric
414 {
415 public:
416 BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
417 : BaseMetric(NULL, name, object), mCGuest(cguest) {};
418 protected:
419 CollectorGuest *mCGuest;
420 };
421
422 class HostCpuLoad : public BaseMetric
423 {
424 public:
425 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
426 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
427 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
428
429 void init(ULONG period, ULONG length);
430
431 void collect();
432 const char *getUnit() { return "%"; };
433 ULONG getMinValue() { return 0; };
434 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
435 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
436
437 protected:
438 SubMetric *mUser;
439 SubMetric *mKernel;
440 SubMetric *mIdle;
441 };
442
443 class HostCpuLoadRaw : public HostCpuLoad
444 {
445 public:
446 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
447 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
448
449 void preCollect(CollectorHints& hints, uint64_t iTick);
450 void collect();
451 private:
452 uint64_t mUserPrev;
453 uint64_t mKernelPrev;
454 uint64_t mIdlePrev;
455 };
456
457 class HostCpuMhz : public BaseMetric
458 {
459 public:
460 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
461 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
462 ~HostCpuMhz() { delete mMHz; };
463
464 void init(ULONG period, ULONG length);
465 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
466 void collect();
467 const char *getUnit() { return "MHz"; };
468 ULONG getMinValue() { return 0; };
469 ULONG getMaxValue() { return INT32_MAX; };
470 ULONG getScale() { return 1; }
471 private:
472 SubMetric *mMHz;
473 };
474
475 class HostRamUsage : public BaseMetric
476 {
477 public:
478 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
479 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
480 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
481
482 void init(ULONG period, ULONG length);
483 void preCollect(CollectorHints& hints, uint64_t iTick);
484 void collect();
485 const char *getUnit() { return "kB"; };
486 ULONG getMinValue() { return 0; };
487 ULONG getMaxValue() { return INT32_MAX; };
488 ULONG getScale() { return 1; }
489 private:
490 SubMetric *mTotal;
491 SubMetric *mUsed;
492 SubMetric *mAvailable;
493 };
494
495 class HostNetworkLoadRaw : public BaseMetric
496 {
497 public:
498 HostNetworkLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str ifname, SubMetric *rx, SubMetric *tx)
499 : BaseMetric(hal, name, object), mInterfaceName(ifname), mRx(rx), mTx(tx), mRxPrev(0), mTxPrev(0), mRc(VINF_SUCCESS) {};
500 ~HostNetworkLoadRaw() { delete mRx; delete mTx; };
501
502 void init(ULONG period, ULONG length);
503
504 void preCollect(CollectorHints& hints, uint64_t iTick);
505 void collect();
506 const char *getUnit() { return "%"; };
507 ULONG getMinValue() { return 0; };
508 ULONG getMaxValue() { return PM_NETWORK_LOAD_MULTIPLIER; };
509 ULONG getScale() { return PM_NETWORK_LOAD_MULTIPLIER / 100; }
510
511 private:
512 com::Utf8Str mInterfaceName;
513 SubMetric *mRx;
514 SubMetric *mTx;
515 uint64_t mRxPrev;
516 uint64_t mTxPrev;
517 int mRc;
518 };
519
520
521#ifndef VBOX_COLLECTOR_TEST_CASE
522 class HostRamVmm : public BaseMetric
523 {
524 public:
525 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
526 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
527 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
528 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
529 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
530
531 void init(ULONG period, ULONG length);
532 void preCollect(CollectorHints& hints, uint64_t iTick);
533 void collect();
534 int enable();
535 int disable();
536 const char *getUnit() { return "kB"; };
537 ULONG getMinValue() { return 0; };
538 ULONG getMaxValue() { return INT32_MAX; };
539 ULONG getScale() { return 1; }
540
541 private:
542 CollectorGuestManager *mCollectorGuestManager;
543 SubMetric *mAllocVMM;
544 SubMetric *mFreeVMM;
545 SubMetric *mBalloonVMM;
546 SubMetric *mSharedVMM;
547 ULONG mAllocCurrent;
548 ULONG mFreeCurrent;
549 ULONG mBalloonedCurrent;
550 ULONG mSharedCurrent;
551 };
552#endif /* VBOX_COLLECTOR_TEST_CASE */
553
554 class MachineCpuLoad : public BaseMetric
555 {
556 public:
557 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
558 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
559 ~MachineCpuLoad() { delete mUser; delete mKernel; };
560
561 void init(ULONG period, ULONG length);
562 void collect();
563 const char *getUnit() { return "%"; };
564 ULONG getMinValue() { return 0; };
565 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
566 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
567 protected:
568 RTPROCESS mProcess;
569 SubMetric *mUser;
570 SubMetric *mKernel;
571 };
572
573 class MachineCpuLoadRaw : public MachineCpuLoad
574 {
575 public:
576 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
577 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
578
579 void preCollect(CollectorHints& hints, uint64_t iTick);
580 void collect();
581 private:
582 uint64_t mHostTotalPrev;
583 uint64_t mProcessUserPrev;
584 uint64_t mProcessKernelPrev;
585 };
586
587 class MachineRamUsage : public BaseMetric
588 {
589 public:
590 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
591 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
592 ~MachineRamUsage() { delete mUsed; };
593
594 void init(ULONG period, ULONG length);
595 void preCollect(CollectorHints& hints, uint64_t iTick);
596 void collect();
597 const char *getUnit() { return "kB"; };
598 ULONG getMinValue() { return 0; };
599 ULONG getMaxValue() { return INT32_MAX; };
600 ULONG getScale() { return 1; }
601 private:
602 RTPROCESS mProcess;
603 SubMetric *mUsed;
604 };
605
606
607#ifndef VBOX_COLLECTOR_TEST_CASE
608 class GuestCpuLoad : public BaseGuestMetric
609 {
610 public:
611 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
612 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
613 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
614
615 void init(ULONG period, ULONG length);
616 void preCollect(CollectorHints& hints, uint64_t iTick);
617 void collect();
618 int enable();
619 int disable();
620 const char *getUnit() { return "%"; };
621 ULONG getMinValue() { return 0; };
622 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
623 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
624 protected:
625 SubMetric *mUser;
626 SubMetric *mKernel;
627 SubMetric *mIdle;
628 };
629
630 class GuestRamUsage : public BaseGuestMetric
631 {
632 public:
633 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
634 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
635 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
636
637 void init(ULONG period, ULONG length);
638 void preCollect(CollectorHints& hints, uint64_t iTick);
639 void collect();
640 int enable();
641 int disable();
642 const char *getUnit() { return "kB"; };
643 ULONG getMinValue() { return 0; };
644 ULONG getMaxValue() { return INT32_MAX; };
645 ULONG getScale() { return 1; }
646 private:
647 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
648 };
649#endif /* VBOX_COLLECTOR_TEST_CASE */
650
651 /* Aggregate Functions **************************************************/
652 class Aggregate
653 {
654 public:
655 virtual ULONG compute(ULONG *data, ULONG length) = 0;
656 virtual const char *getName() = 0;
657 };
658
659 class AggregateAvg : public Aggregate
660 {
661 public:
662 virtual ULONG compute(ULONG *data, ULONG length);
663 virtual const char *getName();
664 };
665
666 class AggregateMin : public Aggregate
667 {
668 public:
669 virtual ULONG compute(ULONG *data, ULONG length);
670 virtual const char *getName();
671 };
672
673 class AggregateMax : public Aggregate
674 {
675 public:
676 virtual ULONG compute(ULONG *data, ULONG length);
677 virtual const char *getName();
678 };
679
680 /* Metric Class *********************************************************/
681 class Metric
682 {
683 public:
684 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
685 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
686 {
687 if (mAggregate)
688 {
689 mName.append(":");
690 mName.append(mAggregate->getName());
691 }
692 }
693
694 ~Metric()
695 {
696 delete mAggregate;
697 }
698 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
699
700 const char *getName() { return mName.c_str(); };
701 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
702 const char *getDescription()
703 { return mAggregate ? "" : mSubMetric->getDescription(); };
704 const char *getUnit() { return mBaseMetric->getUnit(); };
705 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
706 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
707 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
708 ULONG getLength()
709 { return mAggregate ? 1 : mBaseMetric->getLength(); };
710 ULONG getScale() { return mBaseMetric->getScale(); }
711 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
712
713 private:
714 RTCString mName;
715 BaseMetric *mBaseMetric;
716 SubMetric *mSubMetric;
717 Aggregate *mAggregate;
718 };
719
720 /* Filter Class *********************************************************/
721
722 class Filter
723 {
724 public:
725 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
726 ComSafeArrayIn(IUnknown * , objects));
727 Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
728 static bool patternMatch(const char *pszPat, const char *pszName,
729 bool fSeenColon = false);
730 bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
731 private:
732 void init(ComSafeArrayIn(IN_BSTR, metricNames),
733 ComSafeArrayIn(IUnknown * , objects));
734
735 typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
736 typedef std::list<FilterElement> ElementList;
737
738 ElementList mElements;
739
740 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
741 };
742}
743#endif /* ___performance_h */
744/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette