VirtualBox

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

Last change on this file since 86506 was 85263, checked in by vboxsync, 4 years ago

Main/Performance.cpp/h: A whole bunch of int/HRESULT mixups. bugref:9790

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

© 2023 Oracle
ContactPrivacy policyTerms of Use