VirtualBox

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

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

PerfAPI: Improved Win collector. More realistic performance test. No factories.

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