VirtualBox

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

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

Main/Metrics: Host link speed metric and the fix for base name extraction in VBoxManage (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.1 KB
Line 
1/* $Id: Performance.h 43933 2012-11-22 07:43:47Z 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 VMSTATMASK_NONE = 0x00000000,
157 VMSTATMASK_GUEST_CPUUSER = 0x00000001,
158 VMSTATMASK_GUEST_CPUKERNEL = 0x00000002,
159 VMSTATMASK_GUEST_CPUIDLE = 0x00000004,
160 VMSTATMASK_GUEST_MEMTOTAL = 0x00000008,
161 VMSTATMASK_GUEST_MEMFREE = 0x00000010,
162 VMSTATMASK_GUEST_MEMBALLOON = 0x00000020,
163 VMSTATMASK_GUEST_MEMSHARED = 0x00000040,
164 VMSTATMASK_GUEST_MEMCACHE = 0x00000080,
165 VMSTATMASK_GUEST_PAGETOTAL = 0x00000100,
166 VMSTATMASK_VMM_ALLOC = 0x00010000,
167 VMSTATMASK_VMM_FREE = 0x00020000,
168 VMSTATMASK_VMM_BALOON = 0x00040000,
169 VMSTATMASK_VMM_SHARED = 0x00080000,
170 VMSTATMASK_NET_RX = 0x01000000,
171 VMSTATMASK_NET_TX = 0x02000000
172 } VMSTATMASK;
173
174 const ULONG VMSTATS_GUEST_CPULOAD =
175 VMSTATMASK_GUEST_CPUUSER | VMSTATMASK_GUEST_CPUKERNEL |
176 VMSTATMASK_GUEST_CPUIDLE;
177 const ULONG VMSTATS_GUEST_RAMUSAGE =
178 VMSTATMASK_GUEST_MEMTOTAL | VMSTATMASK_GUEST_MEMFREE |
179 VMSTATMASK_GUEST_MEMBALLOON | VMSTATMASK_GUEST_MEMSHARED |
180 VMSTATMASK_GUEST_MEMCACHE | VMSTATMASK_GUEST_PAGETOTAL;
181 const ULONG VMSTATS_VMM_RAM =
182 VMSTATMASK_VMM_ALLOC | VMSTATMASK_VMM_FREE|
183 VMSTATMASK_VMM_BALOON | VMSTATMASK_VMM_SHARED;
184 const ULONG VMSTATS_NET_RATE =
185 VMSTATMASK_NET_RX | VMSTATMASK_NET_TX;
186 const ULONG VMSTATS_ALL =
187 VMSTATS_GUEST_CPULOAD | VMSTATS_GUEST_RAMUSAGE |
188 VMSTATS_VMM_RAM | VMSTATS_NET_RATE;
189 class CollectorGuest;
190
191 class CollectorGuestRequest
192 {
193 public:
194 CollectorGuestRequest()
195 : mCGuest(0) {};
196 virtual ~CollectorGuestRequest() {};
197 void setGuest(CollectorGuest *aGuest) { mCGuest = aGuest; };
198 CollectorGuest *getGuest() { return mCGuest; };
199 virtual int execute() = 0;
200
201 virtual void debugPrint(void *aObject, const char *aFunction, const char *aText) = 0;
202 protected:
203 CollectorGuest *mCGuest;
204 const char *mDebugName;
205 };
206
207 class CGRQEnable : public CollectorGuestRequest
208 {
209 public:
210 CGRQEnable(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 CGRQDisable : public CollectorGuestRequest
220 {
221 public:
222 CGRQDisable(ULONG aMask)
223 : mMask(aMask) {};
224 int execute();
225
226 void debugPrint(void *aObject, const char *aFunction, const char *aText);
227 private:
228 ULONG mMask;
229 };
230
231 class CGRQAbort : public CollectorGuestRequest
232 {
233 public:
234 CGRQAbort() {};
235 int execute();
236
237 void debugPrint(void *aObject, const char *aFunction, const char *aText);
238 };
239
240 class CollectorGuestQueue
241 {
242 public:
243 CollectorGuestQueue();
244 ~CollectorGuestQueue();
245 void push(CollectorGuestRequest* rq);
246 CollectorGuestRequest* pop();
247 private:
248 RTCLockMtx mLockMtx;
249 RTSEMEVENT mEvent;
250 std::queue<CollectorGuestRequest*> mQueue;
251 };
252
253 class CollectorGuestManager;
254
255 class CollectorGuest
256 {
257 public:
258 CollectorGuest(Machine *machine, RTPROCESS process);
259 ~CollectorGuest();
260
261 void setManager(CollectorGuestManager *aManager)
262 { mManager = aManager; };
263 bool isUnregistered() { return mUnregistered; };
264 bool isEnabled() { return mEnabled != 0; };
265 bool isValid(ULONG mask) { return (mValid & mask) == mask; };
266 void invalidate(ULONG mask) { mValid &= ~mask; };
267 void unregister() { mUnregistered = true; };
268 void updateStats(ULONG aValidStats, ULONG aCpuUser,
269 ULONG aCpuKernel, ULONG aCpuIdle,
270 ULONG aMemTotal, ULONG aMemFree,
271 ULONG aMemBalloon, ULONG aMemShared,
272 ULONG aMemCache, ULONG aPageTotal,
273 ULONG aAllocVMM, ULONG aFreeVMM,
274 ULONG aBalloonedVMM, ULONG aSharedVMM,
275 ULONG aVmNetRx, ULONG aVmNetTx);
276 int enable(ULONG mask);
277 int disable(ULONG mask);
278
279 int enqueueRequest(CollectorGuestRequest *aRequest);
280 int enableInternal(ULONG mask);
281 int disableInternal(ULONG mask);
282
283 const com::Utf8Str& getVMName() const { return mMachineName; };
284
285 RTPROCESS getProcess() { return mProcess; };
286 ULONG getCpuUser() { return mCpuUser; };
287 ULONG getCpuKernel() { return mCpuKernel; };
288 ULONG getCpuIdle() { return mCpuIdle; };
289 ULONG getMemTotal() { return mMemTotal; };
290 ULONG getMemFree() { return mMemFree; };
291 ULONG getMemBalloon() { return mMemBalloon; };
292 ULONG getMemShared() { return mMemShared; };
293 ULONG getMemCache() { return mMemCache; };
294 ULONG getPageTotal() { return mPageTotal; };
295 ULONG getAllocVMM() { return mAllocVMM; };
296 ULONG getFreeVMM() { return mFreeVMM; };
297 ULONG getBalloonedVMM() { return mBalloonedVMM; };
298 ULONG getSharedVMM() { return mSharedVMM; };
299 ULONG getVmNetRx() { return mVmNetRx; };
300 ULONG getVmNetTx() { return mVmNetTx; };
301
302 private:
303 int enableVMMStats(bool mCollectVMMStats);
304
305 CollectorGuestManager *mManager;
306
307 bool mUnregistered;
308 ULONG mEnabled;
309 ULONG mValid;
310 Machine *mMachine;
311 com::Utf8Str mMachineName;
312 RTPROCESS mProcess;
313 ComPtr<IConsole> mConsole;
314 ComPtr<IGuest> mGuest;
315 ULONG mCpuUser;
316 ULONG mCpuKernel;
317 ULONG mCpuIdle;
318 ULONG mMemTotal;
319 ULONG mMemFree;
320 ULONG mMemBalloon;
321 ULONG mMemShared;
322 ULONG mMemCache;
323 ULONG mPageTotal;
324 ULONG mAllocVMM;
325 ULONG mFreeVMM;
326 ULONG mBalloonedVMM;
327 ULONG mSharedVMM;
328 ULONG mVmNetRx;
329 ULONG mVmNetTx;
330 };
331
332 typedef std::list<CollectorGuest*> CollectorGuestList;
333 class CollectorGuestManager
334 {
335 public:
336 CollectorGuestManager();
337 ~CollectorGuestManager();
338 void registerGuest(CollectorGuest* pGuest);
339 void unregisterGuest(CollectorGuest* pGuest);
340 CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; };
341 void preCollect(CollectorHints& hints, uint64_t iTick);
342 void destroyUnregistered();
343 int enqueueRequest(CollectorGuestRequest *aRequest);
344
345 CollectorGuest *getBlockedGuest() { return mGuestBeingCalled; };
346
347 static DECLCALLBACK(int) requestProcessingThread(RTTHREAD aThread, void *pvUser);
348 private:
349 RTTHREAD mThread;
350 CollectorGuestList mGuests;
351 CollectorGuest *mVMMStatsProvider;
352 CollectorGuestQueue mQueue;
353 CollectorGuest *mGuestBeingCalled;
354 };
355
356 /* Collector Hardware Abstraction Layer *********************************/
357 typedef std::list<RTCString> DiskList;
358
359 class CollectorHAL
360 {
361 public:
362 CollectorHAL() {};
363 virtual ~CollectorHAL() { };
364 virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
365 /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
366 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
367 /** Returns the average frequency in MHz across all host's CPUs. */
368 virtual int getHostCpuMHz(ULONG *mhz);
369 /** Returns the amount of physical memory in kilobytes. */
370 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
371 /** Returns file system counters in megabytes. */
372 virtual int getHostFilesystemUsage(const char *name, ULONG *total, ULONG *used, ULONG *available);
373 /** Returns CPU usage in 1/1000th per cent by a particular process. */
374 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
375 /** Returns the amount of memory used by a process in kilobytes. */
376 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
377
378 /** Returns CPU usage counters in platform-specific units. */
379 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
380 /** Returns received and transmitted bytes. */
381 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx);
382 /** Returns disk usage counters in platform-specific units. */
383 virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms);
384 /** Returns process' CPU usage counter in platform-specific units. */
385 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
386
387 /** Returns the list of disks used by the specified file system. */
388 virtual int getDiskListByFs(const char *name, DiskList& list);
389 };
390
391 extern CollectorHAL *createHAL();
392
393 /* Base Metrics *********************************************************/
394 class BaseMetric
395 {
396 public:
397 BaseMetric(CollectorHAL *hal, const com::Utf8Str name, ComPtr<IUnknown> object)
398 : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object),
399 mLastSampleTaken(0), mEnabled(false), mUnregistered(false) {};
400 virtual ~BaseMetric() {};
401
402 virtual void init(ULONG period, ULONG length) = 0;
403 virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
404 virtual void collect() = 0;
405 virtual const char *getUnit() = 0;
406 virtual ULONG getMinValue() = 0;
407 virtual ULONG getMaxValue() = 0;
408 virtual ULONG getScale() = 0;
409
410 bool collectorBeat(uint64_t nowAt);
411
412 virtual int enable() { mEnabled = true; return S_OK; };
413 virtual int disable() { mEnabled = false; return S_OK; };
414 void unregister() { mUnregistered = true; };
415
416 bool isUnregistered() { return mUnregistered; };
417 bool isEnabled() { return mEnabled; };
418 ULONG getPeriod() { return mPeriod; };
419 ULONG getLength() { return mLength; };
420 const char *getName() { return mName.c_str(); };
421 ComPtr<IUnknown> getObject() { return mObject; };
422 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
423
424 protected:
425 ULONG mPeriod;
426 ULONG mLength;
427 CollectorHAL *mHAL;
428 const com::Utf8Str mName;
429 ComPtr<IUnknown> mObject;
430 uint64_t mLastSampleTaken;
431 bool mEnabled;
432 bool mUnregistered;
433 };
434
435 class BaseGuestMetric : public BaseMetric
436 {
437 public:
438 BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
439 : BaseMetric(NULL, name, object), mCGuest(cguest) {};
440 protected:
441 CollectorGuest *mCGuest;
442 };
443
444 class HostCpuLoad : public BaseMetric
445 {
446 public:
447 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
448 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
449 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
450
451 void init(ULONG period, ULONG length);
452
453 void collect();
454 const char *getUnit() { return "%"; };
455 ULONG getMinValue() { return 0; };
456 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
457 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
458
459 protected:
460 SubMetric *mUser;
461 SubMetric *mKernel;
462 SubMetric *mIdle;
463 };
464
465 class HostCpuLoadRaw : public HostCpuLoad
466 {
467 public:
468 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
469 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
470
471 void preCollect(CollectorHints& hints, uint64_t iTick);
472 void collect();
473 private:
474 uint64_t mUserPrev;
475 uint64_t mKernelPrev;
476 uint64_t mIdlePrev;
477 };
478
479 class HostCpuMhz : public BaseMetric
480 {
481 public:
482 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
483 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
484 ~HostCpuMhz() { delete mMHz; };
485
486 void init(ULONG period, ULONG length);
487 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
488 void collect();
489 const char *getUnit() { return "MHz"; };
490 ULONG getMinValue() { return 0; };
491 ULONG getMaxValue() { return INT32_MAX; };
492 ULONG getScale() { return 1; }
493 private:
494 SubMetric *mMHz;
495 };
496
497 class HostRamUsage : public BaseMetric
498 {
499 public:
500 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
501 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
502 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
503
504 void init(ULONG period, ULONG length);
505 void preCollect(CollectorHints& hints, uint64_t iTick);
506 void collect();
507 const char *getUnit() { return "kB"; };
508 ULONG getMinValue() { return 0; };
509 ULONG getMaxValue() { return INT32_MAX; };
510 ULONG getScale() { return 1; }
511 private:
512 SubMetric *mTotal;
513 SubMetric *mUsed;
514 SubMetric *mAvailable;
515 };
516
517 class HostNetworkSpeed : public BaseMetric
518 {
519 public:
520 HostNetworkSpeed(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str /* shortname */, com::Utf8Str /* ifname */, uint32_t speed, SubMetric *linkspeed)
521 : BaseMetric(hal, name, object), mSpeed(speed), mLinkSpeed(linkspeed) {};
522 ~HostNetworkSpeed() { delete mLinkSpeed; };
523
524 void init(ULONG period, ULONG length) { mPeriod = period; mLength = length; mLinkSpeed->init(length); };
525 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {};
526 void collect() { mLinkSpeed->put(mSpeed); };
527 const char *getUnit() { return "mbit/s"; };
528 ULONG getMinValue() { return 0; };
529 ULONG getMaxValue() { return INT32_MAX; };
530 ULONG getScale() { return 1; }
531 private:
532 ULONG mSpeed;
533 SubMetric *mLinkSpeed;
534 };
535
536 class HostNetworkLoadRaw : public BaseMetric
537 {
538 public:
539 HostNetworkLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str ifname, uint32_t speed, SubMetric *rx, SubMetric *tx)
540 : 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 */ };
541 ~HostNetworkLoadRaw() { delete mRx; delete mTx; };
542
543 void init(ULONG period, ULONG length);
544
545 void preCollect(CollectorHints& hints, uint64_t iTick);
546 void collect();
547 const char *getUnit() { return "%"; };
548 ULONG getMinValue() { return 0; };
549 ULONG getMaxValue() { return PM_NETWORK_LOAD_MULTIPLIER; };
550 ULONG getScale() { return PM_NETWORK_LOAD_MULTIPLIER / 100; }
551
552 private:
553 com::Utf8Str mShortName;
554 com::Utf8Str mInterfaceName;
555 SubMetric *mRx;
556 SubMetric *mTx;
557 uint64_t mRxPrev;
558 uint64_t mTxPrev;
559 uint64_t mSpeed;
560 int mRc;
561 };
562
563 class HostFilesystemUsage : public BaseMetric
564 {
565 public:
566 HostFilesystemUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str fsname, SubMetric *total, SubMetric *used, SubMetric *available)
567 : BaseMetric(hal, name, object), mFsName(fsname), mTotal(total), mUsed(used), mAvailable(available) {};
568 ~HostFilesystemUsage() { delete mTotal; delete mUsed; delete mAvailable; };
569
570 void init(ULONG period, ULONG length);
571 void preCollect(CollectorHints& hints, uint64_t iTick);
572 void collect();
573 const char *getUnit() { return "mB"; };
574 ULONG getMinValue() { return 0; };
575 ULONG getMaxValue() { return INT32_MAX; };
576 ULONG getScale() { return 1; }
577 private:
578 com::Utf8Str mFsName;
579 SubMetric *mTotal;
580 SubMetric *mUsed;
581 SubMetric *mAvailable;
582 };
583
584 class HostDiskLoadRaw : public BaseMetric
585 {
586 public:
587 HostDiskLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *util)
588 : BaseMetric(hal, name, object), mDiskName(diskname), mUtil(util), mDiskPrev(0), mTotalPrev(0) {};
589 ~HostDiskLoadRaw() { delete mUtil; };
590
591 void init(ULONG period, ULONG length);
592
593 void preCollect(CollectorHints& hints, uint64_t iTick);
594 void collect();
595 const char *getUnit() { return "%"; };
596 ULONG getMinValue() { return 0; };
597 ULONG getMaxValue() { return PM_DISK_LOAD_MULTIPLIER; };
598 ULONG getScale() { return PM_DISK_LOAD_MULTIPLIER / 100; }
599
600 private:
601 com::Utf8Str mDiskName;
602 SubMetric *mUtil;
603 uint64_t mDiskPrev;
604 uint64_t mTotalPrev;
605 };
606
607
608#ifndef VBOX_COLLECTOR_TEST_CASE
609 class HostRamVmm : public BaseMetric
610 {
611 public:
612 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
613 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
614 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
615 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
616 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
617
618 void init(ULONG period, ULONG length);
619 void preCollect(CollectorHints& hints, uint64_t iTick);
620 void collect();
621 int enable();
622 int disable();
623 const char *getUnit() { return "kB"; };
624 ULONG getMinValue() { return 0; };
625 ULONG getMaxValue() { return INT32_MAX; };
626 ULONG getScale() { return 1; }
627
628 private:
629 CollectorGuestManager *mCollectorGuestManager;
630 SubMetric *mAllocVMM;
631 SubMetric *mFreeVMM;
632 SubMetric *mBalloonVMM;
633 SubMetric *mSharedVMM;
634 ULONG mAllocCurrent;
635 ULONG mFreeCurrent;
636 ULONG mBalloonedCurrent;
637 ULONG mSharedCurrent;
638 };
639#endif /* VBOX_COLLECTOR_TEST_CASE */
640
641 class MachineCpuLoad : public BaseMetric
642 {
643 public:
644 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
645 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
646 ~MachineCpuLoad() { delete mUser; delete mKernel; };
647
648 void init(ULONG period, ULONG length);
649 void collect();
650 const char *getUnit() { return "%"; };
651 ULONG getMinValue() { return 0; };
652 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
653 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
654 protected:
655 RTPROCESS mProcess;
656 SubMetric *mUser;
657 SubMetric *mKernel;
658 };
659
660 class MachineCpuLoadRaw : public MachineCpuLoad
661 {
662 public:
663 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
664 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
665
666 void preCollect(CollectorHints& hints, uint64_t iTick);
667 void collect();
668 private:
669 uint64_t mHostTotalPrev;
670 uint64_t mProcessUserPrev;
671 uint64_t mProcessKernelPrev;
672 };
673
674 class MachineRamUsage : public BaseMetric
675 {
676 public:
677 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
678 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
679 ~MachineRamUsage() { delete mUsed; };
680
681 void init(ULONG period, ULONG length);
682 void preCollect(CollectorHints& hints, uint64_t iTick);
683 void collect();
684 const char *getUnit() { return "kB"; };
685 ULONG getMinValue() { return 0; };
686 ULONG getMaxValue() { return INT32_MAX; };
687 ULONG getScale() { return 1; }
688 private:
689 RTPROCESS mProcess;
690 SubMetric *mUsed;
691 };
692
693
694#ifndef VBOX_COLLECTOR_TEST_CASE
695 /*
696 * Although MachineNetRate is measured for VM, not for the guest, it is
697 * derived from BaseGuestMetric since it uses the same mechanism for
698 * data collection -- values get pushed by Guest class along with other
699 * guest statistics.
700 */
701 class MachineNetRate : public BaseGuestMetric
702 {
703 public:
704 MachineNetRate(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *rx, SubMetric *tx)
705 : BaseGuestMetric(cguest, "Net/Rate", object), mRx(rx), mTx(tx) {};
706 ~MachineNetRate() { delete mRx; delete mTx; };
707
708 void init(ULONG period, ULONG length);
709 void preCollect(CollectorHints& hints, uint64_t iTick);
710 void collect();
711 int enable();
712 int disable();
713 const char *getUnit() { return "B/s"; };
714 ULONG getMinValue() { return 0; };
715 ULONG getMaxValue() { return INT32_MAX; };
716 ULONG getScale() { return 1; }
717 private:
718 SubMetric *mRx, *mTx;
719 };
720
721 class GuestCpuLoad : public BaseGuestMetric
722 {
723 public:
724 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
725 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
726 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
727
728 void init(ULONG period, ULONG length);
729 void preCollect(CollectorHints& hints, uint64_t iTick);
730 void collect();
731 int enable();
732 int disable();
733 const char *getUnit() { return "%"; };
734 ULONG getMinValue() { return 0; };
735 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
736 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
737 protected:
738 SubMetric *mUser;
739 SubMetric *mKernel;
740 SubMetric *mIdle;
741 };
742
743 class GuestRamUsage : public BaseGuestMetric
744 {
745 public:
746 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
747 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
748 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
749
750 void init(ULONG period, ULONG length);
751 void preCollect(CollectorHints& hints, uint64_t iTick);
752 void collect();
753 int enable();
754 int disable();
755 const char *getUnit() { return "kB"; };
756 ULONG getMinValue() { return 0; };
757 ULONG getMaxValue() { return INT32_MAX; };
758 ULONG getScale() { return 1; }
759 private:
760 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
761 };
762#endif /* VBOX_COLLECTOR_TEST_CASE */
763
764 /* Aggregate Functions **************************************************/
765 class Aggregate
766 {
767 public:
768 virtual ULONG compute(ULONG *data, ULONG length) = 0;
769 virtual const char *getName() = 0;
770 };
771
772 class AggregateAvg : public Aggregate
773 {
774 public:
775 virtual ULONG compute(ULONG *data, ULONG length);
776 virtual const char *getName();
777 };
778
779 class AggregateMin : public Aggregate
780 {
781 public:
782 virtual ULONG compute(ULONG *data, ULONG length);
783 virtual const char *getName();
784 };
785
786 class AggregateMax : public Aggregate
787 {
788 public:
789 virtual ULONG compute(ULONG *data, ULONG length);
790 virtual const char *getName();
791 };
792
793 /* Metric Class *********************************************************/
794 class Metric
795 {
796 public:
797 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
798 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
799 {
800 if (mAggregate)
801 {
802 mName.append(":");
803 mName.append(mAggregate->getName());
804 }
805 }
806
807 ~Metric()
808 {
809 delete mAggregate;
810 }
811 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
812
813 const char *getName() { return mName.c_str(); };
814 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
815 const char *getDescription()
816 { return mAggregate ? "" : mSubMetric->getDescription(); };
817 const char *getUnit() { return mBaseMetric->getUnit(); };
818 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
819 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
820 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
821 ULONG getLength()
822 { return mAggregate ? 1 : mBaseMetric->getLength(); };
823 ULONG getScale() { return mBaseMetric->getScale(); }
824 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
825
826 private:
827 RTCString mName;
828 BaseMetric *mBaseMetric;
829 SubMetric *mSubMetric;
830 Aggregate *mAggregate;
831 };
832
833 /* Filter Class *********************************************************/
834
835 class Filter
836 {
837 public:
838 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
839 ComSafeArrayIn(IUnknown * , objects));
840 Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
841 static bool patternMatch(const char *pszPat, const char *pszName,
842 bool fSeenColon = false);
843 bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
844 private:
845 void init(ComSafeArrayIn(IN_BSTR, metricNames),
846 ComSafeArrayIn(IUnknown * , objects));
847
848 typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
849 typedef std::list<FilterElement> ElementList;
850
851 ElementList mElements;
852
853 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
854 };
855}
856#endif /* ___performance_h */
857/* 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