VirtualBox

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

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

metrics update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.5 KB
Line 
1/* $Id: Performance.h 27849 2010-03-31 07:33:59Z 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
30#include <iprt/types.h>
31#include <iprt/err.h>
32
33#include <algorithm>
34#include <functional> /* For std::fun_ptr in testcase */
35#include <list>
36#include <vector>
37
38namespace pm
39{
40 /* CPU load is measured in 1/1000 of per cent. */
41 const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000);
42
43 /* Sub Metrics **********************************************************/
44 class CircularBuffer
45 {
46 public:
47 CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
48 void init(ULONG length);
49 ULONG length();
50 ULONG getSequenceNumber() { return mSequenceNumber; }
51 void put(ULONG value);
52 void copyTo(ULONG *data);
53 private:
54 ULONG *mData;
55 ULONG mLength;
56 ULONG mEnd;
57 ULONG mSequenceNumber;
58 bool mWrapped;
59 };
60
61 class SubMetric : public CircularBuffer
62 {
63 public:
64 SubMetric(const char *name, const char *description)
65 : mName(name), mDescription(description) {};
66 void query(ULONG *data);
67 const char *getName() { return mName; };
68 const char *getDescription() { return mDescription; };
69 private:
70 const char *mName;
71 const char *mDescription;
72 };
73
74
75 /* Collector Hardware Abstraction Layer *********************************/
76 enum {
77 COLLECT_NONE = 0x0,
78 COLLECT_CPU_LOAD = 0x1,
79 COLLECT_RAM_USAGE = 0x2
80 };
81 typedef int HintFlags;
82 typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair;
83
84 class CollectorHints
85 {
86 public:
87 typedef std::list<ProcessFlagsPair> ProcessList;
88
89 CollectorHints() : mHostFlags(COLLECT_NONE) {}
90 void collectHostCpuLoad()
91 { mHostFlags |= COLLECT_CPU_LOAD; }
92 void collectHostRamUsage()
93 { mHostFlags |= COLLECT_RAM_USAGE; }
94 void collectProcessCpuLoad(RTPROCESS process)
95 { findProcess(process).second |= COLLECT_CPU_LOAD; }
96 void collectProcessRamUsage(RTPROCESS process)
97 { findProcess(process).second |= COLLECT_RAM_USAGE; }
98 bool isHostCpuLoadCollected() const
99 { return (mHostFlags & COLLECT_CPU_LOAD) != 0; }
100 bool isHostRamUsageCollected() const
101 { return (mHostFlags & COLLECT_RAM_USAGE) != 0; }
102 bool isProcessCpuLoadCollected(RTPROCESS process)
103 { return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; }
104 bool isProcessRamUsageCollected(RTPROCESS process)
105 { return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; }
106 void getProcesses(std::vector<RTPROCESS>& processes) const
107 {
108 processes.clear();
109 processes.reserve(mProcesses.size());
110 for (ProcessList::const_iterator it = mProcesses.begin(); it != mProcesses.end(); it++)
111 processes.push_back(it->first);
112 }
113 const ProcessList& getProcessFlags() const
114 {
115 return mProcesses;
116 }
117 private:
118 HintFlags mHostFlags;
119 ProcessList mProcesses;
120
121 ProcessFlagsPair& findProcess(RTPROCESS process)
122 {
123 ProcessList::iterator it;
124 for (it = mProcesses.begin(); it != mProcesses.end(); it++)
125 if (it->first == process)
126 return *it;
127
128 /* Not found -- add new */
129 mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE));
130 return mProcesses.back();
131 }
132 };
133
134 class CollectorHAL
135 {
136 public:
137 virtual ~CollectorHAL() { };
138 virtual int preCollect(const CollectorHints& /* hints */) { return VINF_SUCCESS; }
139 /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
140 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
141 /** Returns the average frequency in MHz across all host's CPUs. */
142 virtual int getHostCpuMHz(ULONG *mhz);
143 /** Returns the amount of physical memory in kilobytes. */
144 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
145 /** Returns CPU usage in 1/1000th per cent by a particular process. */
146 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
147 /** Returns the amount of memory used by a process in kilobytes. */
148 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
149
150 /** Returns CPU usage counters in platform-specific units. */
151 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
152 /** Returns process' CPU usage counter in platform-specific units. */
153 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
154
155 /** Enable metrics collecting (if applicable) */
156 virtual int enable();
157 /** Disable metrics collecting (if applicable) */
158 virtual int disable();
159 };
160
161 class CollectorGuestHAL : public CollectorHAL
162 {
163 public:
164 CollectorGuestHAL() : cEnabled(0) {};
165 ~CollectorGuestHAL();
166
167 /** Enable metrics collecting (if applicable) */
168 virtual int enable();
169 /** Disable metrics collecting (if applicable) */
170 virtual int disable();
171 protected:
172 unsigned cEnabled;
173 };
174
175 extern CollectorHAL *createHAL();
176
177 /* Base Metrics *********************************************************/
178 class BaseMetric
179 {
180 public:
181 BaseMetric(CollectorHAL *hal, const char *name, ComPtr<IUnknown> object)
182 : mHAL(hal), mPeriod(0), mLength(0), mName(name), mObject(object), mLastSampleTaken(0), mEnabled(false) {};
183 virtual ~BaseMetric() {};
184
185 virtual void init(ULONG period, ULONG length) = 0;
186 virtual void preCollect(CollectorHints& hints) = 0;
187 virtual void collect() = 0;
188 virtual const char *getUnit() = 0;
189 virtual ULONG getMinValue() = 0;
190 virtual ULONG getMaxValue() = 0;
191 virtual ULONG getScale() = 0;
192
193 bool collectorBeat(uint64_t nowAt);
194
195 void enable()
196 {
197 mEnabled = true;
198 mHAL->enable();
199 };
200 void disable()
201 {
202 mHAL->disable();
203 mEnabled = false;
204 };
205
206 bool isEnabled() { return mEnabled; };
207 ULONG getPeriod() { return mPeriod; };
208 ULONG getLength() { return mLength; };
209 const char *getName() { return mName; };
210 ComPtr<IUnknown> getObject() { return mObject; };
211 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
212
213 protected:
214 CollectorHAL *mHAL;
215 ULONG mPeriod;
216 ULONG mLength;
217 const char *mName;
218 ComPtr<IUnknown> mObject;
219 uint64_t mLastSampleTaken;
220 bool mEnabled;
221 };
222
223 class HostCpuLoad : public BaseMetric
224 {
225 public:
226 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
227 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
228 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
229
230 void init(ULONG period, ULONG length);
231
232 void collect();
233 const char *getUnit() { return "%"; };
234 ULONG getMinValue() { return 0; };
235 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
236 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
237
238 protected:
239 SubMetric *mUser;
240 SubMetric *mKernel;
241 SubMetric *mIdle;
242 };
243
244 class HostCpuLoadRaw : public HostCpuLoad
245 {
246 public:
247 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
248 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
249
250 void preCollect(CollectorHints& hints);
251 void collect();
252 private:
253 uint64_t mUserPrev;
254 uint64_t mKernelPrev;
255 uint64_t mIdlePrev;
256 };
257
258 class HostCpuMhz : public BaseMetric
259 {
260 public:
261 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
262 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
263 ~HostCpuMhz() { delete mMHz; };
264
265 void init(ULONG period, ULONG length);
266 void preCollect(CollectorHints& /* hints */) {}
267 void collect();
268 const char *getUnit() { return "MHz"; };
269 ULONG getMinValue() { return 0; };
270 ULONG getMaxValue() { return INT32_MAX; };
271 ULONG getScale() { return 1; }
272 private:
273 SubMetric *mMHz;
274 };
275
276 class HostRamUsage : public BaseMetric
277 {
278 public:
279 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
280 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
281 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
282
283 void init(ULONG period, ULONG length);
284 void preCollect(CollectorHints& hints);
285 void collect();
286 const char *getUnit() { return "kB"; };
287 ULONG getMinValue() { return 0; };
288 ULONG getMaxValue() { return INT32_MAX; };
289 ULONG getScale() { return 1; }
290 private:
291 SubMetric *mTotal;
292 SubMetric *mUsed;
293 SubMetric *mAvailable;
294 };
295
296 class MachineCpuLoad : public BaseMetric
297 {
298 public:
299 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
300 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
301 ~MachineCpuLoad() { delete mUser; delete mKernel; };
302
303 void init(ULONG period, ULONG length);
304 void collect();
305 const char *getUnit() { return "%"; };
306 ULONG getMinValue() { return 0; };
307 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
308 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
309 protected:
310 RTPROCESS mProcess;
311 SubMetric *mUser;
312 SubMetric *mKernel;
313 };
314
315 class MachineCpuLoadRaw : public MachineCpuLoad
316 {
317 public:
318 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
319 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
320
321 void preCollect(CollectorHints& hints);
322 void collect();
323 private:
324 uint64_t mHostTotalPrev;
325 uint64_t mProcessUserPrev;
326 uint64_t mProcessKernelPrev;
327 };
328
329 class MachineRamUsage : public BaseMetric
330 {
331 public:
332 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
333 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
334 ~MachineRamUsage() { delete mUsed; };
335
336 void init(ULONG period, ULONG length);
337 void preCollect(CollectorHints& hints);
338 void collect();
339 const char *getUnit() { return "kB"; };
340 ULONG getMinValue() { return 0; };
341 ULONG getMaxValue() { return INT32_MAX; };
342 ULONG getScale() { return 1; }
343 private:
344 RTPROCESS mProcess;
345 SubMetric *mUsed;
346 };
347
348
349 class GuestCpuLoad : public BaseMetric
350 {
351 public:
352 GuestCpuLoad(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
353 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
354 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
355
356 void init(ULONG period, ULONG length);
357 void preCollect(CollectorHints& hints);
358 void collect();
359 const char *getUnit() { return "%"; };
360 ULONG getMinValue() { return 0; };
361 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
362 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
363 protected:
364 SubMetric *mUser;
365 SubMetric *mKernel;
366 SubMetric *mIdle;
367 };
368
369 class GuestRamUsage : public BaseMetric
370 {
371 public:
372 GuestRamUsage(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *cache, SubMetric *pagedtotal, SubMetric *pagedfree)
373 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mPagedFree(pagedfree) {};
374 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mCache; delete mPagedTotal; delete mPagedFree; };
375
376 void init(ULONG period, ULONG length);
377 void preCollect(CollectorHints& hints);
378 void collect();
379 const char *getUnit() { return "kB"; };
380 ULONG getMinValue() { return 0; };
381 ULONG getMaxValue() { return INT32_MAX; };
382 ULONG getScale() { return 1; }
383 private:
384 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mPagedFree;
385 };
386
387 class GuestSystemUsage : public BaseMetric
388 {
389 public:
390 GuestSystemUsage(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *processes, SubMetric *threads)
391 : BaseMetric(hal, "System/Usage", object), mProcesses(processes), mThreads(threads) {};
392 ~GuestSystemUsage() { delete mProcesses; delete mThreads; };
393
394 void init(ULONG period, ULONG length);
395 void preCollect(CollectorHints& hints);
396 void collect();
397 const char *getUnit() { return "kB"; };
398 ULONG getMinValue() { return 0; };
399 ULONG getMaxValue() { return INT32_MAX; };
400 ULONG getScale() { return 1; }
401 private:
402 SubMetric *mProcesses, *mThreads;
403 };
404
405 /* Aggregate Functions **************************************************/
406 class Aggregate
407 {
408 public:
409 virtual ULONG compute(ULONG *data, ULONG length) = 0;
410 virtual const char *getName() = 0;
411 };
412
413 class AggregateAvg : public Aggregate
414 {
415 public:
416 virtual ULONG compute(ULONG *data, ULONG length);
417 virtual const char *getName();
418 };
419
420 class AggregateMin : public Aggregate
421 {
422 public:
423 virtual ULONG compute(ULONG *data, ULONG length);
424 virtual const char *getName();
425 };
426
427 class AggregateMax : public Aggregate
428 {
429 public:
430 virtual ULONG compute(ULONG *data, ULONG length);
431 virtual const char *getName();
432 };
433
434 /* Metric Class *********************************************************/
435 class Metric
436 {
437 public:
438 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
439 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
440 {
441 if (mAggregate)
442 {
443 mName.append(":");
444 mName.append(mAggregate->getName());
445 }
446 }
447
448 ~Metric()
449 {
450 delete mAggregate;
451 }
452 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
453
454 const char *getName() { return mName.c_str(); };
455 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
456 const char *getDescription()
457 { return mAggregate ? "" : mSubMetric->getDescription(); };
458 const char *getUnit() { return mBaseMetric->getUnit(); };
459 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
460 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
461 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
462 ULONG getLength()
463 { return mAggregate ? 1 : mBaseMetric->getLength(); };
464 ULONG getScale() { return mBaseMetric->getScale(); }
465 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
466
467 private:
468 iprt::MiniString mName;
469 BaseMetric *mBaseMetric;
470 SubMetric *mSubMetric;
471 Aggregate *mAggregate;
472 };
473
474 /* Filter Class *********************************************************/
475
476 class Filter
477 {
478 public:
479 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
480 ComSafeArrayIn(IUnknown * , objects));
481 static bool patternMatch(const char *pszPat, const char *pszName,
482 bool fSeenColon = false);
483 bool match(const ComPtr<IUnknown> object, const iprt::MiniString &name) const;
484 private:
485 void init(ComSafeArrayIn(IN_BSTR, metricNames),
486 ComSafeArrayIn(IUnknown * , objects));
487
488 typedef std::pair<const ComPtr<IUnknown>, const iprt::MiniString> FilterElement;
489 typedef std::list<FilterElement> ElementList;
490
491 ElementList mElements;
492
493 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
494 };
495}
496#endif /* ___performance_h */
497/* 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