VirtualBox

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

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

Main/Metrics: Alternative way to get link speed for old kernels (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.3 KB
Line 
1/* $Id: Performance.h 43507 2012-10-02 13:22:31Z 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. */
364 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx);
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, uint32_t speed, SubMetric *rx, SubMetric *tx)
499 : BaseMetric(hal, name, object), mInterfaceName(ifname), mRx(rx), mTx(tx), mRxPrev(0), mTxPrev(0), mRc(VINF_SUCCESS) { mSpeed = (uint64_t)speed * (1000000/8); /* Convert to bytes/sec */ };
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 uint64_t mSpeed;
518 int mRc;
519 };
520
521
522#ifndef VBOX_COLLECTOR_TEST_CASE
523 class HostRamVmm : public BaseMetric
524 {
525 public:
526 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
527 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
528 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
529 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
530 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
531
532 void init(ULONG period, ULONG length);
533 void preCollect(CollectorHints& hints, uint64_t iTick);
534 void collect();
535 int enable();
536 int disable();
537 const char *getUnit() { return "kB"; };
538 ULONG getMinValue() { return 0; };
539 ULONG getMaxValue() { return INT32_MAX; };
540 ULONG getScale() { return 1; }
541
542 private:
543 CollectorGuestManager *mCollectorGuestManager;
544 SubMetric *mAllocVMM;
545 SubMetric *mFreeVMM;
546 SubMetric *mBalloonVMM;
547 SubMetric *mSharedVMM;
548 ULONG mAllocCurrent;
549 ULONG mFreeCurrent;
550 ULONG mBalloonedCurrent;
551 ULONG mSharedCurrent;
552 };
553#endif /* VBOX_COLLECTOR_TEST_CASE */
554
555 class MachineCpuLoad : public BaseMetric
556 {
557 public:
558 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
559 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
560 ~MachineCpuLoad() { delete mUser; delete mKernel; };
561
562 void init(ULONG period, ULONG length);
563 void collect();
564 const char *getUnit() { return "%"; };
565 ULONG getMinValue() { return 0; };
566 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
567 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
568 protected:
569 RTPROCESS mProcess;
570 SubMetric *mUser;
571 SubMetric *mKernel;
572 };
573
574 class MachineCpuLoadRaw : public MachineCpuLoad
575 {
576 public:
577 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
578 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
579
580 void preCollect(CollectorHints& hints, uint64_t iTick);
581 void collect();
582 private:
583 uint64_t mHostTotalPrev;
584 uint64_t mProcessUserPrev;
585 uint64_t mProcessKernelPrev;
586 };
587
588 class MachineRamUsage : public BaseMetric
589 {
590 public:
591 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
592 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
593 ~MachineRamUsage() { delete mUsed; };
594
595 void init(ULONG period, ULONG length);
596 void preCollect(CollectorHints& hints, uint64_t iTick);
597 void collect();
598 const char *getUnit() { return "kB"; };
599 ULONG getMinValue() { return 0; };
600 ULONG getMaxValue() { return INT32_MAX; };
601 ULONG getScale() { return 1; }
602 private:
603 RTPROCESS mProcess;
604 SubMetric *mUsed;
605 };
606
607
608#ifndef VBOX_COLLECTOR_TEST_CASE
609 class GuestCpuLoad : public BaseGuestMetric
610 {
611 public:
612 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
613 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
614 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
615
616 void init(ULONG period, ULONG length);
617 void preCollect(CollectorHints& hints, uint64_t iTick);
618 void collect();
619 int enable();
620 int disable();
621 const char *getUnit() { return "%"; };
622 ULONG getMinValue() { return 0; };
623 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
624 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
625 protected:
626 SubMetric *mUser;
627 SubMetric *mKernel;
628 SubMetric *mIdle;
629 };
630
631 class GuestRamUsage : public BaseGuestMetric
632 {
633 public:
634 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
635 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
636 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
637
638 void init(ULONG period, ULONG length);
639 void preCollect(CollectorHints& hints, uint64_t iTick);
640 void collect();
641 int enable();
642 int disable();
643 const char *getUnit() { return "kB"; };
644 ULONG getMinValue() { return 0; };
645 ULONG getMaxValue() { return INT32_MAX; };
646 ULONG getScale() { return 1; }
647 private:
648 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
649 };
650#endif /* VBOX_COLLECTOR_TEST_CASE */
651
652 /* Aggregate Functions **************************************************/
653 class Aggregate
654 {
655 public:
656 virtual ULONG compute(ULONG *data, ULONG length) = 0;
657 virtual const char *getName() = 0;
658 };
659
660 class AggregateAvg : public Aggregate
661 {
662 public:
663 virtual ULONG compute(ULONG *data, ULONG length);
664 virtual const char *getName();
665 };
666
667 class AggregateMin : public Aggregate
668 {
669 public:
670 virtual ULONG compute(ULONG *data, ULONG length);
671 virtual const char *getName();
672 };
673
674 class AggregateMax : public Aggregate
675 {
676 public:
677 virtual ULONG compute(ULONG *data, ULONG length);
678 virtual const char *getName();
679 };
680
681 /* Metric Class *********************************************************/
682 class Metric
683 {
684 public:
685 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
686 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
687 {
688 if (mAggregate)
689 {
690 mName.append(":");
691 mName.append(mAggregate->getName());
692 }
693 }
694
695 ~Metric()
696 {
697 delete mAggregate;
698 }
699 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
700
701 const char *getName() { return mName.c_str(); };
702 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
703 const char *getDescription()
704 { return mAggregate ? "" : mSubMetric->getDescription(); };
705 const char *getUnit() { return mBaseMetric->getUnit(); };
706 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
707 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
708 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
709 ULONG getLength()
710 { return mAggregate ? 1 : mBaseMetric->getLength(); };
711 ULONG getScale() { return mBaseMetric->getScale(); }
712 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
713
714 private:
715 RTCString mName;
716 BaseMetric *mBaseMetric;
717 SubMetric *mSubMetric;
718 Aggregate *mAggregate;
719 };
720
721 /* Filter Class *********************************************************/
722
723 class Filter
724 {
725 public:
726 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
727 ComSafeArrayIn(IUnknown * , objects));
728 Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
729 static bool patternMatch(const char *pszPat, const char *pszName,
730 bool fSeenColon = false);
731 bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
732 private:
733 void init(ComSafeArrayIn(IN_BSTR, metricNames),
734 ComSafeArrayIn(IUnknown * , objects));
735
736 typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
737 typedef std::list<FilterElement> ElementList;
738
739 ElementList mElements;
740
741 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
742 };
743}
744#endif /* ___performance_h */
745/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

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