VirtualBox

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

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

Main/Metrics: Disk and filesystem metrics for Solaris (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.7 KB
Line 
1/* $Id: Performance.h 43831 2012-11-07 13:11:51Z 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 typedef std::list<RTCString> DiskList;
347
348 class CollectorHAL
349 {
350 public:
351 CollectorHAL() {};
352 virtual ~CollectorHAL() { };
353 virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
354 /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
355 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
356 /** Returns the average frequency in MHz across all host's CPUs. */
357 virtual int getHostCpuMHz(ULONG *mhz);
358 /** Returns the amount of physical memory in kilobytes. */
359 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
360 /** Returns file system counters in megabytes. */
361 virtual int getHostFilesystemUsage(const char *name, ULONG *total, ULONG *used, ULONG *available);
362 /** Returns CPU usage in 1/1000th per cent by a particular process. */
363 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
364 /** Returns the amount of memory used by a process in kilobytes. */
365 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
366
367 /** Returns CPU usage counters in platform-specific units. */
368 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
369 /** Returns received and transmitted bytes. */
370 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx);
371 /** Returns disk usage counters in platform-specific units. */
372 virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms);
373 /** Returns process' CPU usage counter in platform-specific units. */
374 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
375
376 /** Returns the list of disks used by the specified file system. */
377 virtual int getDiskListByFs(const char *name, DiskList& list);
378 };
379
380 extern CollectorHAL *createHAL();
381
382 /* Base Metrics *********************************************************/
383 class BaseMetric
384 {
385 public:
386 BaseMetric(CollectorHAL *hal, const com::Utf8Str name, ComPtr<IUnknown> object)
387 : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object),
388 mLastSampleTaken(0), mEnabled(false), mUnregistered(false) {};
389 virtual ~BaseMetric() {};
390
391 virtual void init(ULONG period, ULONG length) = 0;
392 virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
393 virtual void collect() = 0;
394 virtual const char *getUnit() = 0;
395 virtual ULONG getMinValue() = 0;
396 virtual ULONG getMaxValue() = 0;
397 virtual ULONG getScale() = 0;
398
399 bool collectorBeat(uint64_t nowAt);
400
401 virtual int enable() { mEnabled = true; return S_OK; };
402 virtual int disable() { mEnabled = false; return S_OK; };
403 void unregister() { mUnregistered = true; };
404
405 bool isUnregistered() { return mUnregistered; };
406 bool isEnabled() { return mEnabled; };
407 ULONG getPeriod() { return mPeriod; };
408 ULONG getLength() { return mLength; };
409 const char *getName() { return mName.c_str(); };
410 ComPtr<IUnknown> getObject() { return mObject; };
411 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
412
413 protected:
414 ULONG mPeriod;
415 ULONG mLength;
416 CollectorHAL *mHAL;
417 const com::Utf8Str mName;
418 ComPtr<IUnknown> mObject;
419 uint64_t mLastSampleTaken;
420 bool mEnabled;
421 bool mUnregistered;
422 };
423
424 class BaseGuestMetric : public BaseMetric
425 {
426 public:
427 BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
428 : BaseMetric(NULL, name, object), mCGuest(cguest) {};
429 protected:
430 CollectorGuest *mCGuest;
431 };
432
433 class HostCpuLoad : public BaseMetric
434 {
435 public:
436 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
437 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
438 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
439
440 void init(ULONG period, ULONG length);
441
442 void collect();
443 const char *getUnit() { return "%"; };
444 ULONG getMinValue() { return 0; };
445 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
446 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
447
448 protected:
449 SubMetric *mUser;
450 SubMetric *mKernel;
451 SubMetric *mIdle;
452 };
453
454 class HostCpuLoadRaw : public HostCpuLoad
455 {
456 public:
457 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
458 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
459
460 void preCollect(CollectorHints& hints, uint64_t iTick);
461 void collect();
462 private:
463 uint64_t mUserPrev;
464 uint64_t mKernelPrev;
465 uint64_t mIdlePrev;
466 };
467
468 class HostCpuMhz : public BaseMetric
469 {
470 public:
471 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
472 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
473 ~HostCpuMhz() { delete mMHz; };
474
475 void init(ULONG period, ULONG length);
476 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
477 void collect();
478 const char *getUnit() { return "MHz"; };
479 ULONG getMinValue() { return 0; };
480 ULONG getMaxValue() { return INT32_MAX; };
481 ULONG getScale() { return 1; }
482 private:
483 SubMetric *mMHz;
484 };
485
486 class HostRamUsage : public BaseMetric
487 {
488 public:
489 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
490 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
491 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
492
493 void init(ULONG period, ULONG length);
494 void preCollect(CollectorHints& hints, uint64_t iTick);
495 void collect();
496 const char *getUnit() { return "kB"; };
497 ULONG getMinValue() { return 0; };
498 ULONG getMaxValue() { return INT32_MAX; };
499 ULONG getScale() { return 1; }
500 private:
501 SubMetric *mTotal;
502 SubMetric *mUsed;
503 SubMetric *mAvailable;
504 };
505
506 class HostNetworkLoadRaw : public BaseMetric
507 {
508 public:
509 HostNetworkLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str ifname, uint32_t speed, SubMetric *rx, SubMetric *tx)
510 : 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 */ };
511 ~HostNetworkLoadRaw() { delete mRx; delete mTx; };
512
513 void init(ULONG period, ULONG length);
514
515 void preCollect(CollectorHints& hints, uint64_t iTick);
516 void collect();
517 const char *getUnit() { return "%"; };
518 ULONG getMinValue() { return 0; };
519 ULONG getMaxValue() { return PM_NETWORK_LOAD_MULTIPLIER; };
520 ULONG getScale() { return PM_NETWORK_LOAD_MULTIPLIER / 100; }
521
522 private:
523 com::Utf8Str mShortName;
524 com::Utf8Str mInterfaceName;
525 SubMetric *mRx;
526 SubMetric *mTx;
527 uint64_t mRxPrev;
528 uint64_t mTxPrev;
529 uint64_t mSpeed;
530 int mRc;
531 };
532
533 class HostFilesystemUsage : public BaseMetric
534 {
535 public:
536 HostFilesystemUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str fsname, SubMetric *total, SubMetric *used, SubMetric *available)
537 : BaseMetric(hal, name, object), mFsName(fsname), mTotal(total), mUsed(used), mAvailable(available) {};
538 ~HostFilesystemUsage() { delete mTotal; delete mUsed; delete mAvailable; };
539
540 void init(ULONG period, ULONG length);
541 void preCollect(CollectorHints& hints, uint64_t iTick);
542 void collect();
543 const char *getUnit() { return "mB"; };
544 ULONG getMinValue() { return 0; };
545 ULONG getMaxValue() { return INT32_MAX; };
546 ULONG getScale() { return 1; }
547 private:
548 com::Utf8Str mFsName;
549 SubMetric *mTotal;
550 SubMetric *mUsed;
551 SubMetric *mAvailable;
552 };
553
554 class HostDiskLoadRaw : public BaseMetric
555 {
556 public:
557 HostDiskLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *util)
558 : BaseMetric(hal, name, object), mDiskName(diskname), mUtil(util), mDiskPrev(0), mTotalPrev(0) {};
559 ~HostDiskLoadRaw() { delete mUtil; };
560
561 void init(ULONG period, ULONG length);
562
563 void preCollect(CollectorHints& hints, uint64_t iTick);
564 void collect();
565 const char *getUnit() { return "%"; };
566 ULONG getMinValue() { return 0; };
567 ULONG getMaxValue() { return PM_DISK_LOAD_MULTIPLIER; };
568 ULONG getScale() { return PM_DISK_LOAD_MULTIPLIER / 100; }
569
570 private:
571 com::Utf8Str mDiskName;
572 SubMetric *mUtil;
573 uint64_t mDiskPrev;
574 uint64_t mTotalPrev;
575 };
576
577
578#ifndef VBOX_COLLECTOR_TEST_CASE
579 class HostRamVmm : public BaseMetric
580 {
581 public:
582 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
583 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
584 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
585 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
586 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
587
588 void init(ULONG period, ULONG length);
589 void preCollect(CollectorHints& hints, uint64_t iTick);
590 void collect();
591 int enable();
592 int disable();
593 const char *getUnit() { return "kB"; };
594 ULONG getMinValue() { return 0; };
595 ULONG getMaxValue() { return INT32_MAX; };
596 ULONG getScale() { return 1; }
597
598 private:
599 CollectorGuestManager *mCollectorGuestManager;
600 SubMetric *mAllocVMM;
601 SubMetric *mFreeVMM;
602 SubMetric *mBalloonVMM;
603 SubMetric *mSharedVMM;
604 ULONG mAllocCurrent;
605 ULONG mFreeCurrent;
606 ULONG mBalloonedCurrent;
607 ULONG mSharedCurrent;
608 };
609#endif /* VBOX_COLLECTOR_TEST_CASE */
610
611 class MachineCpuLoad : public BaseMetric
612 {
613 public:
614 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
615 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
616 ~MachineCpuLoad() { delete mUser; delete mKernel; };
617
618 void init(ULONG period, ULONG length);
619 void collect();
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 RTPROCESS mProcess;
626 SubMetric *mUser;
627 SubMetric *mKernel;
628 };
629
630 class MachineCpuLoadRaw : public MachineCpuLoad
631 {
632 public:
633 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
634 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
635
636 void preCollect(CollectorHints& hints, uint64_t iTick);
637 void collect();
638 private:
639 uint64_t mHostTotalPrev;
640 uint64_t mProcessUserPrev;
641 uint64_t mProcessKernelPrev;
642 };
643
644 class MachineRamUsage : public BaseMetric
645 {
646 public:
647 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
648 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
649 ~MachineRamUsage() { delete mUsed; };
650
651 void init(ULONG period, ULONG length);
652 void preCollect(CollectorHints& hints, uint64_t iTick);
653 void collect();
654 const char *getUnit() { return "kB"; };
655 ULONG getMinValue() { return 0; };
656 ULONG getMaxValue() { return INT32_MAX; };
657 ULONG getScale() { return 1; }
658 private:
659 RTPROCESS mProcess;
660 SubMetric *mUsed;
661 };
662
663
664#ifndef VBOX_COLLECTOR_TEST_CASE
665 class GuestCpuLoad : public BaseGuestMetric
666 {
667 public:
668 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
669 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
670 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
671
672 void init(ULONG period, ULONG length);
673 void preCollect(CollectorHints& hints, uint64_t iTick);
674 void collect();
675 int enable();
676 int disable();
677 const char *getUnit() { return "%"; };
678 ULONG getMinValue() { return 0; };
679 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
680 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
681 protected:
682 SubMetric *mUser;
683 SubMetric *mKernel;
684 SubMetric *mIdle;
685 };
686
687 class GuestRamUsage : public BaseGuestMetric
688 {
689 public:
690 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
691 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
692 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
693
694 void init(ULONG period, ULONG length);
695 void preCollect(CollectorHints& hints, uint64_t iTick);
696 void collect();
697 int enable();
698 int disable();
699 const char *getUnit() { return "kB"; };
700 ULONG getMinValue() { return 0; };
701 ULONG getMaxValue() { return INT32_MAX; };
702 ULONG getScale() { return 1; }
703 private:
704 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
705 };
706#endif /* VBOX_COLLECTOR_TEST_CASE */
707
708 /* Aggregate Functions **************************************************/
709 class Aggregate
710 {
711 public:
712 virtual ULONG compute(ULONG *data, ULONG length) = 0;
713 virtual const char *getName() = 0;
714 };
715
716 class AggregateAvg : public Aggregate
717 {
718 public:
719 virtual ULONG compute(ULONG *data, ULONG length);
720 virtual const char *getName();
721 };
722
723 class AggregateMin : public Aggregate
724 {
725 public:
726 virtual ULONG compute(ULONG *data, ULONG length);
727 virtual const char *getName();
728 };
729
730 class AggregateMax : public Aggregate
731 {
732 public:
733 virtual ULONG compute(ULONG *data, ULONG length);
734 virtual const char *getName();
735 };
736
737 /* Metric Class *********************************************************/
738 class Metric
739 {
740 public:
741 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
742 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
743 {
744 if (mAggregate)
745 {
746 mName.append(":");
747 mName.append(mAggregate->getName());
748 }
749 }
750
751 ~Metric()
752 {
753 delete mAggregate;
754 }
755 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
756
757 const char *getName() { return mName.c_str(); };
758 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
759 const char *getDescription()
760 { return mAggregate ? "" : mSubMetric->getDescription(); };
761 const char *getUnit() { return mBaseMetric->getUnit(); };
762 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
763 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
764 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
765 ULONG getLength()
766 { return mAggregate ? 1 : mBaseMetric->getLength(); };
767 ULONG getScale() { return mBaseMetric->getScale(); }
768 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
769
770 private:
771 RTCString mName;
772 BaseMetric *mBaseMetric;
773 SubMetric *mSubMetric;
774 Aggregate *mAggregate;
775 };
776
777 /* Filter Class *********************************************************/
778
779 class Filter
780 {
781 public:
782 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
783 ComSafeArrayIn(IUnknown * , objects));
784 Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
785 static bool patternMatch(const char *pszPat, const char *pszName,
786 bool fSeenColon = false);
787 bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
788 private:
789 void init(ComSafeArrayIn(IN_BSTR, metricNames),
790 ComSafeArrayIn(IUnknown * , objects));
791
792 typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
793 typedef std::list<FilterElement> ElementList;
794
795 ElementList mElements;
796
797 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
798 };
799}
800#endif /* ___performance_h */
801/* 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