VirtualBox

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

Last change on this file since 14949 was 14949, checked in by vboxsync, 16 years ago

Appended vim modeline to set tabstop and expand tabs (in the way
suggested by our coding guidelines).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.6 KB
Line 
1/* $Id: Performance.h 14949 2008-12-03 15:17:16Z 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 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 inline bool processEqual(ProcessFlagsPair pair, RTPROCESS process)
83 {
84 return pair.first == process;
85 }
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
128 it = std::find_if(mProcesses.begin(),
129 mProcesses.end(),
130 std::bind2nd(std::ptr_fun(processEqual), process));
131
132 if (it != mProcesses.end())
133 return *it;
134
135 /* Not found -- add new */
136 mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE));
137 return mProcesses.back();
138 }
139 };
140
141 class CollectorHAL
142 {
143 public:
144 virtual ~CollectorHAL() { };
145 virtual int preCollect(const CollectorHints& hints) { return VINF_SUCCESS; }
146 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
147 virtual int getHostCpuMHz(ULONG *mhz);
148 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available) = 0;
149 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
150 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used) = 0;
151
152 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
153 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
154 };
155
156 extern CollectorHAL *createHAL();
157
158 /* Base Metrics *********************************************************/
159 class BaseMetric
160 {
161 public:
162 BaseMetric(CollectorHAL *hal, const char *name, ComPtr<IUnknown> object)
163 : mHAL(hal), mPeriod(0), mLength(0), mName(name), mObject(object), mLastSampleTaken(0), mEnabled(false) {};
164
165 virtual void init(ULONG period, ULONG length) = 0;
166 virtual void preCollect(CollectorHints& hints) = 0;
167 virtual void collect() = 0;
168 virtual const char *getUnit() = 0;
169 virtual ULONG getMinValue() = 0;
170 virtual ULONG getMaxValue() = 0;
171 virtual ULONG getScale() = 0;
172
173 bool collectorBeat(uint64_t nowAt);
174
175 void enable() { mEnabled = true; };
176 void disable() { mEnabled = false; };
177
178 bool isEnabled() { return mEnabled; };
179 ULONG getPeriod() { return mPeriod; };
180 ULONG getLength() { return mLength; };
181 const char *getName() { return mName; };
182 ComPtr<IUnknown> getObject() { return mObject; };
183 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
184
185 protected:
186 CollectorHAL *mHAL;
187 ULONG mPeriod;
188 ULONG mLength;
189 const char *mName;
190 ComPtr<IUnknown> mObject;
191 uint64_t mLastSampleTaken;
192 bool mEnabled;
193 };
194
195 class HostCpuLoad : public BaseMetric
196 {
197 public:
198 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
199 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
200 void init(ULONG period, ULONG length);
201
202 void collect();
203 const char *getUnit() { return "%"; };
204 ULONG getMinValue() { return 0; };
205 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
206 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
207
208 protected:
209 SubMetric *mUser;
210 SubMetric *mKernel;
211 SubMetric *mIdle;
212 };
213
214 class HostCpuLoadRaw : public HostCpuLoad
215 {
216 public:
217 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
218 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
219
220 void preCollect(CollectorHints& hints);
221 void collect();
222 private:
223 uint64_t mUserPrev;
224 uint64_t mKernelPrev;
225 uint64_t mIdlePrev;
226 };
227
228 class HostCpuMhz : public BaseMetric
229 {
230 public:
231 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
232 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
233
234 void init(ULONG period, ULONG length);
235 void preCollect(CollectorHints& hints) {}
236 void collect();
237 const char *getUnit() { return "MHz"; };
238 ULONG getMinValue() { return 0; };
239 ULONG getMaxValue() { return INT32_MAX; };
240 ULONG getScale() { return 1; }
241 private:
242 SubMetric *mMHz;
243 };
244
245 class HostRamUsage : public BaseMetric
246 {
247 public:
248 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
249 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
250
251 void init(ULONG period, ULONG length);
252 void preCollect(CollectorHints& hints);
253 void collect();
254 const char *getUnit() { return "kB"; };
255 ULONG getMinValue() { return 0; };
256 ULONG getMaxValue() { return INT32_MAX; };
257 ULONG getScale() { return 1; }
258 private:
259 SubMetric *mTotal;
260 SubMetric *mUsed;
261 SubMetric *mAvailable;
262 };
263
264 class MachineCpuLoad : public BaseMetric
265 {
266 public:
267 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
268 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
269
270 void init(ULONG period, ULONG length);
271 void collect();
272 const char *getUnit() { return "%"; };
273 ULONG getMinValue() { return 0; };
274 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
275 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
276 protected:
277 RTPROCESS mProcess;
278 SubMetric *mUser;
279 SubMetric *mKernel;
280 };
281
282 class MachineCpuLoadRaw : public MachineCpuLoad
283 {
284 public:
285 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
286 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
287
288 void preCollect(CollectorHints& hints);
289 void collect();
290 private:
291 uint64_t mHostTotalPrev;
292 uint64_t mProcessUserPrev;
293 uint64_t mProcessKernelPrev;
294 };
295
296 class MachineRamUsage : public BaseMetric
297 {
298 public:
299 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
300 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
301
302 void init(ULONG period, ULONG length);
303 void preCollect(CollectorHints& hints);
304 void collect();
305 const char *getUnit() { return "kB"; };
306 ULONG getMinValue() { return 0; };
307 ULONG getMaxValue() { return INT32_MAX; };
308 ULONG getScale() { return 1; }
309 private:
310 RTPROCESS mProcess;
311 SubMetric *mUsed;
312 };
313
314 /* Aggregate Functions **************************************************/
315 class Aggregate
316 {
317 public:
318 virtual ULONG compute(ULONG *data, ULONG length) = 0;
319 virtual const char *getName() = 0;
320 };
321
322 class AggregateAvg : public Aggregate
323 {
324 public:
325 virtual ULONG compute(ULONG *data, ULONG length);
326 virtual const char *getName();
327 };
328
329 class AggregateMin : public Aggregate
330 {
331 public:
332 virtual ULONG compute(ULONG *data, ULONG length);
333 virtual const char *getName();
334 };
335
336 class AggregateMax : public Aggregate
337 {
338 public:
339 virtual ULONG compute(ULONG *data, ULONG length);
340 virtual const char *getName();
341 };
342
343 /* Metric Class *********************************************************/
344 class Metric
345 {
346 public:
347 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
348 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
349 {
350 if (mAggregate)
351 {
352 mName += ":";
353 mName += mAggregate->getName();
354 }
355 }
356
357 ~Metric()
358 {
359 delete mAggregate;
360 }
361 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
362
363 const char *getName() { return mName.c_str(); };
364 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
365 const char *getDescription()
366 { return mAggregate ? "" : mSubMetric->getDescription(); };
367 const char *getUnit() { return mBaseMetric->getUnit(); };
368 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
369 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
370 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
371 ULONG getLength()
372 { return mAggregate ? 1 : mBaseMetric->getLength(); };
373 ULONG getScale() { return mBaseMetric->getScale(); }
374 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
375
376 private:
377 std::string mName;
378 BaseMetric *mBaseMetric;
379 SubMetric *mSubMetric;
380 Aggregate *mAggregate;
381 };
382
383 /* Filter Class *********************************************************/
384
385 class Filter
386 {
387 public:
388 Filter(ComSafeArrayIn(INPTR BSTR, metricNames),
389 ComSafeArrayIn(IUnknown * , objects));
390 static bool patternMatch(const char *pszPat, const char *pszName,
391 bool fSeenColon = false);
392 bool match(const ComPtr<IUnknown> object, const std::string &name) const;
393 private:
394 void init(ComSafeArrayIn(INPTR BSTR, metricNames),
395 ComSafeArrayIn(IUnknown * , objects));
396
397 typedef std::pair<const ComPtr<IUnknown>, const std::string> FilterElement;
398 typedef std::list<FilterElement> ElementList;
399
400 ElementList mElements;
401
402 void processMetricList(const std::string &name, const ComPtr<IUnknown> object);
403 };
404}
405
406/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use