VirtualBox

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

Last change on this file since 106903 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette