VirtualBox

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

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

Main: the big XML settings rework. Move XML reading/writing out of interface implementation code into separate layer so it can handle individual settings versions in the future.

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