VirtualBox

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

Last change on this file since 28368 was 28205, checked in by vboxsync, 15 years ago

Main/VirtualBoxCallback: rename OnSnapshotDiscard to OnSnapshotDeleted for consistency, clean up wording and other minor issues

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.7 KB
Line 
1/* $Id: Performance.h 28205 2010-04-12 13:39:18Z vboxsync $ */
2
3/** @file
4 *
5 * VBox Performance Classes declaration.
6 */
7
8/*
9 * Copyright (C) 2008 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23#ifndef ___performance_h
24#define ___performance_h
25
26#include <VBox/com/defs.h>
27#include <VBox/com/ptr.h>
28#include <VBox/com/string.h>
29#include <VBox/com/VirtualBox.h>
30
31#include <iprt/types.h>
32#include <iprt/err.h>
33
34#include <algorithm>
35#include <functional> /* For std::fun_ptr in testcase */
36#include <list>
37#include <vector>
38
39/* Forward decl. */
40class Machine;
41
42namespace pm
43{
44 /* CPU load is measured in 1/1000 of per cent. */
45 const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000);
46
47 /* Sub Metrics **********************************************************/
48 class CircularBuffer
49 {
50 public:
51 CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
52 void init(ULONG length);
53 ULONG length();
54 ULONG getSequenceNumber() { return mSequenceNumber; }
55 void put(ULONG value);
56 void copyTo(ULONG *data);
57 private:
58 ULONG *mData;
59 ULONG mLength;
60 ULONG mEnd;
61 ULONG mSequenceNumber;
62 bool mWrapped;
63 };
64
65 class SubMetric : public CircularBuffer
66 {
67 public:
68 SubMetric(const char *name, const char *description)
69 : mName(name), mDescription(description) {};
70 void query(ULONG *data);
71 const char *getName() { return mName; };
72 const char *getDescription() { return mDescription; };
73 private:
74 const char *mName;
75 const char *mDescription;
76 };
77
78
79 /* Collector Hardware Abstraction Layer *********************************/
80 enum {
81 COLLECT_NONE = 0x0,
82 COLLECT_CPU_LOAD = 0x1,
83 COLLECT_RAM_USAGE = 0x2
84 };
85 typedef int HintFlags;
86 typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair;
87
88 class CollectorHints
89 {
90 public:
91 typedef std::list<ProcessFlagsPair> ProcessList;
92
93 CollectorHints() : mHostFlags(COLLECT_NONE) {}
94 void collectHostCpuLoad()
95 { mHostFlags |= COLLECT_CPU_LOAD; }
96 void collectHostRamUsage()
97 { mHostFlags |= COLLECT_RAM_USAGE; }
98 void collectProcessCpuLoad(RTPROCESS process)
99 { findProcess(process).second |= COLLECT_CPU_LOAD; }
100 void collectProcessRamUsage(RTPROCESS process)
101 { findProcess(process).second |= COLLECT_RAM_USAGE; }
102 bool isHostCpuLoadCollected() const
103 { return (mHostFlags & COLLECT_CPU_LOAD) != 0; }
104 bool isHostRamUsageCollected() const
105 { return (mHostFlags & COLLECT_RAM_USAGE) != 0; }
106 bool isProcessCpuLoadCollected(RTPROCESS process)
107 { return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; }
108 bool isProcessRamUsageCollected(RTPROCESS process)
109 { return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; }
110 void getProcesses(std::vector<RTPROCESS>& processes) const
111 {
112 processes.clear();
113 processes.reserve(mProcesses.size());
114 for (ProcessList::const_iterator it = mProcesses.begin(); it != mProcesses.end(); it++)
115 processes.push_back(it->first);
116 }
117 const ProcessList& getProcessFlags() const
118 {
119 return mProcesses;
120 }
121 private:
122 HintFlags mHostFlags;
123 ProcessList mProcesses;
124
125 ProcessFlagsPair& findProcess(RTPROCESS process)
126 {
127 ProcessList::iterator it;
128 for (it = mProcesses.begin(); it != mProcesses.end(); it++)
129 if (it->first == process)
130 return *it;
131
132 /* Not found -- add new */
133 mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE));
134 return mProcesses.back();
135 }
136 };
137
138 class CollectorHAL
139 {
140 public:
141 CollectorHAL() : mMemAllocVMM(0), mMemFreeVMM(0), mMemBalloonedVMM(0) {};
142 virtual ~CollectorHAL() { };
143 virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
144 /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
145 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
146 /** Returns the average frequency in MHz across all host's CPUs. */
147 virtual int getHostCpuMHz(ULONG *mhz);
148 /** Returns the amount of physical memory in kilobytes. */
149 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
150 /** Returns CPU usage in 1/1000th per cent by a particular process. */
151 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
152 /** Returns the amount of memory used by a process in kilobytes. */
153 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
154
155 /** Returns CPU usage counters in platform-specific units. */
156 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
157 /** Returns process' CPU usage counter in platform-specific units. */
158 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
159
160 /** Enable metrics collecting (if applicable) */
161 virtual int enable();
162 /** Disable metrics collecting (if applicable) */
163 virtual int disable();
164
165 virtual int setMemHypervisorStats(ULONG memAlloc, ULONG memFree, ULONG memBallooned)
166 {
167 mMemAllocVMM = memAlloc;
168 mMemFreeVMM = memFree;
169 mMemBalloonedVMM = memBallooned;
170 return S_OK;
171 }
172
173 virtual void getMemHypervisorStats(ULONG *pMemAlloc, ULONG *pMemFree, ULONG *pMemBallooned)
174 {
175 *pMemAlloc = mMemAllocVMM;
176 *pMemFree = mMemFreeVMM;
177 *pMemBallooned = mMemBalloonedVMM;
178 }
179
180 private:
181 ULONG mMemAllocVMM;
182 ULONG mMemFreeVMM;
183 ULONG mMemBalloonedVMM;
184 };
185
186 class CollectorGuestHAL : public CollectorHAL
187 {
188 public:
189 CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL) : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL), mGuest(NULL),
190 mLastTick(0), mHostHAL(hostHAL), mCpuUser(0), mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0),
191 mMemBalloon(0), mMemCache(0), mPageTotal(0) {};
192 ~CollectorGuestHAL();
193
194 virtual int preCollect(const CollectorHints& hints, uint64_t iTick);
195
196 /** Enable metrics collecting (if applicable) */
197 virtual int enable();
198 /** Disable metrics collecting (if applicable) */
199 virtual int disable();
200
201 /** Return guest cpu absolute load values (0-100). */
202 void getGuestCpuLoad(ULONG *pulCpuUser, ULONG *pulCpuKernel, ULONG *pulCpuIdle)
203 {
204 *pulCpuUser = mCpuUser;
205 *pulCpuKernel = mCpuKernel;
206 *pulCpuIdle = mCpuIdle;
207 }
208
209 /** Return guest memory information in KB. */
210 void getGuestMemLoad(ULONG *pulMemTotal, ULONG *pulMemFree, ULONG *pulMemBalloon, ULONG *pulMemCache, ULONG *pulPageTotal)
211 {
212 *pulMemTotal = mMemTotal;
213 *pulMemFree = mMemFree;
214 *pulMemBalloon = mMemBalloon;
215 *pulMemCache = mMemCache;
216 *pulPageTotal = mPageTotal;
217 }
218
219
220 protected:
221 uint32_t cEnabled;
222 Machine *mMachine;
223 ComPtr<IConsole> mConsole;
224 ComPtr<IGuest> mGuest;
225 uint64_t mLastTick;
226
227 CollectorHAL *mHostHAL;
228
229 ULONG mCpuUser;
230 ULONG mCpuKernel;
231 ULONG mCpuIdle;
232 ULONG mMemTotal;
233 ULONG mMemFree;
234 ULONG mMemBalloon;
235 ULONG mMemCache;
236 ULONG mPageTotal;
237 };
238
239 extern CollectorHAL *createHAL();
240
241 /* Base Metrics *********************************************************/
242 class BaseMetric
243 {
244 public:
245 BaseMetric(CollectorHAL *hal, const char *name, ComPtr<IUnknown> object)
246 : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object), mLastSampleTaken(0), mEnabled(false) {};
247 virtual ~BaseMetric() {};
248
249 virtual void init(ULONG period, ULONG length) = 0;
250 virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
251 virtual void collect() = 0;
252 virtual const char *getUnit() = 0;
253 virtual ULONG getMinValue() = 0;
254 virtual ULONG getMaxValue() = 0;
255 virtual ULONG getScale() = 0;
256
257 bool collectorBeat(uint64_t nowAt);
258
259 void enable()
260 {
261 mEnabled = true;
262 mHAL->enable();
263 };
264 void disable()
265 {
266 mHAL->disable();
267 mEnabled = false;
268 };
269
270 bool isEnabled() { return mEnabled; };
271 ULONG getPeriod() { return mPeriod; };
272 ULONG getLength() { return mLength; };
273 const char *getName() { return mName; };
274 ComPtr<IUnknown> getObject() { return mObject; };
275 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
276
277 protected:
278 ULONG mPeriod;
279 ULONG mLength;
280 CollectorHAL *mHAL;
281 const char *mName;
282 ComPtr<IUnknown> mObject;
283 uint64_t mLastSampleTaken;
284 bool mEnabled;
285 };
286
287 class HostCpuLoad : public BaseMetric
288 {
289 public:
290 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
291 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
292 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
293
294 void init(ULONG period, ULONG length);
295
296 void collect();
297 const char *getUnit() { return "%"; };
298 ULONG getMinValue() { return 0; };
299 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
300 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
301
302 protected:
303 SubMetric *mUser;
304 SubMetric *mKernel;
305 SubMetric *mIdle;
306 };
307
308 class HostCpuLoadRaw : public HostCpuLoad
309 {
310 public:
311 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
312 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
313
314 void preCollect(CollectorHints& hints, uint64_t iTick);
315 void collect();
316 private:
317 uint64_t mUserPrev;
318 uint64_t mKernelPrev;
319 uint64_t mIdlePrev;
320 };
321
322 class HostCpuMhz : public BaseMetric
323 {
324 public:
325 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
326 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
327 ~HostCpuMhz() { delete mMHz; };
328
329 void init(ULONG period, ULONG length);
330 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
331 void collect();
332 const char *getUnit() { return "MHz"; };
333 ULONG getMinValue() { return 0; };
334 ULONG getMaxValue() { return INT32_MAX; };
335 ULONG getScale() { return 1; }
336 private:
337 SubMetric *mMHz;
338 };
339
340 class HostRamUsage : public BaseMetric
341 {
342 public:
343 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM)
344 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available), mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM) {};
345 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; };
346
347 void init(ULONG period, ULONG length);
348 void preCollect(CollectorHints& hints, uint64_t iTick);
349 void collect();
350 const char *getUnit() { return "kB"; };
351 ULONG getMinValue() { return 0; };
352 ULONG getMaxValue() { return INT32_MAX; };
353 ULONG getScale() { return 1; }
354 private:
355 SubMetric *mTotal;
356 SubMetric *mUsed;
357 SubMetric *mAvailable;
358 SubMetric *mAllocVMM;
359 SubMetric *mFreeVMM;
360 SubMetric *mBalloonVMM;
361 };
362
363 class MachineCpuLoad : public BaseMetric
364 {
365 public:
366 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
367 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
368 ~MachineCpuLoad() { delete mUser; delete mKernel; };
369
370 void init(ULONG period, ULONG length);
371 void collect();
372 const char *getUnit() { return "%"; };
373 ULONG getMinValue() { return 0; };
374 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
375 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
376 protected:
377 RTPROCESS mProcess;
378 SubMetric *mUser;
379 SubMetric *mKernel;
380 };
381
382 class MachineCpuLoadRaw : public MachineCpuLoad
383 {
384 public:
385 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
386 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
387
388 void preCollect(CollectorHints& hints, uint64_t iTick);
389 void collect();
390 private:
391 uint64_t mHostTotalPrev;
392 uint64_t mProcessUserPrev;
393 uint64_t mProcessKernelPrev;
394 };
395
396 class MachineRamUsage : public BaseMetric
397 {
398 public:
399 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
400 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
401 ~MachineRamUsage() { delete mUsed; };
402
403 void init(ULONG period, ULONG length);
404 void preCollect(CollectorHints& hints, uint64_t iTick);
405 void collect();
406 const char *getUnit() { return "kB"; };
407 ULONG getMinValue() { return 0; };
408 ULONG getMaxValue() { return INT32_MAX; };
409 ULONG getScale() { return 1; }
410 private:
411 RTPROCESS mProcess;
412 SubMetric *mUsed;
413 };
414
415
416 class GuestCpuLoad : public BaseMetric
417 {
418 public:
419 GuestCpuLoad(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
420 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle), mGuestHAL(hal) {};
421 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
422
423 void init(ULONG period, ULONG length);
424 void preCollect(CollectorHints& hints, uint64_t iTick);
425 void collect();
426 const char *getUnit() { return "%"; };
427 ULONG getMinValue() { return 0; };
428 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
429 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
430 protected:
431 SubMetric *mUser;
432 SubMetric *mKernel;
433 SubMetric *mIdle;
434 CollectorGuestHAL *mGuestHAL;
435 };
436
437 class GuestRamUsage : public BaseMetric
438 {
439 public:
440 GuestRamUsage(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *cache, SubMetric *pagedtotal)
441 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mGuestHAL(hal) {};
442 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mCache; delete mPagedTotal; };
443
444 void init(ULONG period, ULONG length);
445 void preCollect(CollectorHints& hints, uint64_t iTick);
446 void collect();
447 const char *getUnit() { return "kB"; };
448 ULONG getMinValue() { return 0; };
449 ULONG getMaxValue() { return INT32_MAX; };
450 ULONG getScale() { return 1; }
451 private:
452 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal;
453 CollectorGuestHAL *mGuestHAL;
454 };
455
456 /* Aggregate Functions **************************************************/
457 class Aggregate
458 {
459 public:
460 virtual ULONG compute(ULONG *data, ULONG length) = 0;
461 virtual const char *getName() = 0;
462 };
463
464 class AggregateAvg : public Aggregate
465 {
466 public:
467 virtual ULONG compute(ULONG *data, ULONG length);
468 virtual const char *getName();
469 };
470
471 class AggregateMin : public Aggregate
472 {
473 public:
474 virtual ULONG compute(ULONG *data, ULONG length);
475 virtual const char *getName();
476 };
477
478 class AggregateMax : public Aggregate
479 {
480 public:
481 virtual ULONG compute(ULONG *data, ULONG length);
482 virtual const char *getName();
483 };
484
485 /* Metric Class *********************************************************/
486 class Metric
487 {
488 public:
489 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
490 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
491 {
492 if (mAggregate)
493 {
494 mName.append(":");
495 mName.append(mAggregate->getName());
496 }
497 }
498
499 ~Metric()
500 {
501 delete mAggregate;
502 }
503 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
504
505 const char *getName() { return mName.c_str(); };
506 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
507 const char *getDescription()
508 { return mAggregate ? "" : mSubMetric->getDescription(); };
509 const char *getUnit() { return mBaseMetric->getUnit(); };
510 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
511 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
512 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
513 ULONG getLength()
514 { return mAggregate ? 1 : mBaseMetric->getLength(); };
515 ULONG getScale() { return mBaseMetric->getScale(); }
516 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
517
518 private:
519 iprt::MiniString mName;
520 BaseMetric *mBaseMetric;
521 SubMetric *mSubMetric;
522 Aggregate *mAggregate;
523 };
524
525 /* Filter Class *********************************************************/
526
527 class Filter
528 {
529 public:
530 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
531 ComSafeArrayIn(IUnknown * , objects));
532 static bool patternMatch(const char *pszPat, const char *pszName,
533 bool fSeenColon = false);
534 bool match(const ComPtr<IUnknown> object, const iprt::MiniString &name) const;
535 private:
536 void init(ComSafeArrayIn(IN_BSTR, metricNames),
537 ComSafeArrayIn(IUnknown * , objects));
538
539 typedef std::pair<const ComPtr<IUnknown>, const iprt::MiniString> FilterElement;
540 typedef std::list<FilterElement> ElementList;
541
542 ElementList mElements;
543
544 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
545 };
546}
547#endif /* ___performance_h */
548/* 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