VirtualBox

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

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

PerfAPI: Fixed the problem with passing null/empty arrays to PerfAPI methods.
Enabled attributes of type IUnknown in SOAP, JAX-WS, WSDL, CPP and Python style sheets.
Added PerfCollector python class to shellcommon.py to provide more 'pythonic' way to access metric data.
Added the reference to shellcommon.py to IDL docs as an example of PerfAPI usage in python.

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