VirtualBox

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

Last change on this file since 40358 was 40358, checked in by vboxsync, 13 years ago

Main/Metrics: All calls to VM processes are done in separate thread (#6029)

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