VirtualBox

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

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

Main/Metrics: Linux fs/disk metrics, VBoxManage filtering + minor fixes (#6345)

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