VirtualBox

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

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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