VirtualBox

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

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

Metrics: work in progress

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