VirtualBox

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

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

Main/Performance: Burn fix.

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