VirtualBox

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

最後變更 在這個檔案從36418是 36128,由 vboxsync 提交於 14 年 前

Main/Metrics: Hypervisor and guest metrics re-done (#5566)

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 20.8 KB
 
1/* $Id: Performance.h 36128 2011-03-02 05:44:04Z vboxsync $ */
2
3/** @file
4 *
5 * VBox Performance Classes declaration.
6 */
7
8/*
9 * Copyright (C) 2008 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.alldomusa.eu.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#ifndef ___performance_h
20#define ___performance_h
21
22#include <VBox/com/defs.h>
23#include <VBox/com/ptr.h>
24#include <VBox/com/string.h>
25#include <VBox/com/VirtualBox.h>
26
27#include <iprt/types.h>
28#include <iprt/err.h>
29
30#include <algorithm>
31#include <functional> /* For std::fun_ptr in testcase */
32#include <list>
33#include <vector>
34
35/* Forward decl. */
36class Machine;
37
38namespace pm
39{
40 /* CPU load is measured in 1/1000 of per cent. */
41 const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000);
42
43 /* Sub Metrics **********************************************************/
44 class CircularBuffer
45 {
46 public:
47 CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
48 void init(ULONG length);
49 ULONG length();
50 ULONG getSequenceNumber() { return mSequenceNumber; }
51 void put(ULONG value);
52 void copyTo(ULONG *data);
53 private:
54 ULONG *mData;
55 ULONG mLength;
56 ULONG mEnd;
57 ULONG mSequenceNumber;
58 bool mWrapped;
59 };
60
61 class SubMetric : public CircularBuffer
62 {
63 public:
64 SubMetric(const char *name, const char *description)
65 : mName(name), mDescription(description) {};
66 void query(ULONG *data);
67 const char *getName() { return mName; };
68 const char *getDescription() { return mDescription; };
69 private:
70 const char *mName;
71 const char *mDescription;
72 };
73
74
75 enum {
76 COLLECT_NONE = 0x0,
77 COLLECT_CPU_LOAD = 0x1,
78 COLLECT_RAM_USAGE = 0x2,
79 COLLECT_GUEST_STATS = 0x4
80 };
81 typedef int HintFlags;
82 typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair;
83
84 class CollectorHints
85 {
86 public:
87 typedef std::list<ProcessFlagsPair> ProcessList;
88
89 CollectorHints() : mHostFlags(COLLECT_NONE) {}
90 void collectHostCpuLoad()
91 { mHostFlags |= COLLECT_CPU_LOAD; }
92 void collectHostRamUsage()
93 { mHostFlags |= COLLECT_RAM_USAGE; }
94 void collectHostRamVmm()
95 { mHostFlags |= COLLECT_GUEST_STATS; }
96 void collectProcessCpuLoad(RTPROCESS process)
97 { findProcess(process).second |= COLLECT_CPU_LOAD; }
98 void collectProcessRamUsage(RTPROCESS process)
99 { findProcess(process).second |= COLLECT_RAM_USAGE; }
100 void collectGuestStats(RTPROCESS process)
101 { findProcess(process).second |= COLLECT_GUEST_STATS; }
102 bool isHostCpuLoadCollected() const
103 { return (mHostFlags & COLLECT_CPU_LOAD) != 0; }
104 bool isHostRamUsageCollected() const
105 { return (mHostFlags & COLLECT_RAM_USAGE) != 0; }
106 bool isHostRamVmmCollected() const
107 { return (mHostFlags & COLLECT_GUEST_STATS) != 0; }
108 bool isProcessCpuLoadCollected(RTPROCESS process)
109 { return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; }
110 bool isProcessRamUsageCollected(RTPROCESS process)
111 { return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; }
112 bool isGuestStatsCollected(RTPROCESS process)
113 { return (findProcess(process).second & COLLECT_GUEST_STATS) != 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 for (it = mProcesses.begin(); it != mProcesses.end(); it++)
133 if (it->first == process)
134 return *it;
135
136 /* Not found -- add new */
137 mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE));
138 return mProcesses.back();
139 }
140 };
141
142 /* Guest Collector Classes *********************************/
143 class CollectorGuest
144 {
145 public:
146 CollectorGuest(Machine *machine, RTPROCESS process);
147 ~CollectorGuest();
148
149 bool isEnabled() { return mEnabled; };
150 bool isValid() { return mValid; };
151 void invalidateStats() { mValid = false; };
152 int updateStats();
153 int enable();
154 int disable();
155
156 RTPROCESS getProcess() { return mProcess; };
157 ULONG getCpuUser() { return mCpuUser; };
158 ULONG getCpuKernel() { return mCpuKernel; };
159 ULONG getCpuIdle() { return mCpuIdle; };
160 ULONG getMemTotal() { return mMemTotal; };
161 ULONG getMemFree() { return mMemFree; };
162 ULONG getMemBalloon() { return mMemBalloon; };
163 ULONG getMemShared() { return mMemShared; };
164 ULONG getMemCache() { return mMemCache; };
165 ULONG getPageTotal() { return mPageTotal; };
166 ULONG getAllocVMM() { return mAllocVMM; };
167 ULONG getFreeVMM() { return mFreeVMM; };
168 ULONG getBalloonedVMM() { return mBalloonedVMM; };
169 ULONG getSharedVMM() { return mSharedVMM; };
170
171 private:
172 bool mEnabled;
173 bool mValid;
174 Machine *mMachine;
175 RTPROCESS mProcess;
176 ComPtr<IConsole> mConsole;
177 ComPtr<IGuest> mGuest;
178 ULONG mCpuUser;
179 ULONG mCpuKernel;
180 ULONG mCpuIdle;
181 ULONG mMemTotal;
182 ULONG mMemFree;
183 ULONG mMemBalloon;
184 ULONG mMemShared;
185 ULONG mMemCache;
186 ULONG mPageTotal;
187 ULONG mAllocVMM;
188 ULONG mFreeVMM;
189 ULONG mBalloonedVMM;
190 ULONG mSharedVMM;
191 };
192
193 typedef std::list<CollectorGuest*> CollectorGuestList;
194 class CollectorGuestManager
195 {
196 public:
197 CollectorGuestManager() : mVMMStatsProvider(NULL) {};
198 void registerGuest(CollectorGuest* pGuest);
199 void unregisterGuest(CollectorGuest* pGuest);
200 CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; };
201 void preCollect(CollectorHints& hints, uint64_t iTick);
202 private:
203 CollectorGuestList mGuests;
204 CollectorGuest *mVMMStatsProvider;
205 };
206
207 /* Collector Hardware Abstraction Layer *********************************/
208 class CollectorHAL
209 {
210 public:
211 CollectorHAL() {};
212 virtual ~CollectorHAL() { };
213 virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
214 /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
215 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
216 /** Returns the average frequency in MHz across all host's CPUs. */
217 virtual int getHostCpuMHz(ULONG *mhz);
218 /** Returns the amount of physical memory in kilobytes. */
219 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
220 /** Returns CPU usage in 1/1000th per cent by a particular process. */
221 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
222 /** Returns the amount of memory used by a process in kilobytes. */
223 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
224
225 /** Returns CPU usage counters in platform-specific units. */
226 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
227 /** Returns process' CPU usage counter in platform-specific units. */
228 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
229 };
230
231 extern CollectorHAL *createHAL();
232
233 /* Base Metrics *********************************************************/
234 class BaseMetric
235 {
236 public:
237 BaseMetric(CollectorHAL *hal, const char *name, ComPtr<IUnknown> object)
238 : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object), mLastSampleTaken(0), mEnabled(false) {};
239 virtual ~BaseMetric() {};
240
241 virtual void init(ULONG period, ULONG length) = 0;
242 virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
243 virtual void collect() = 0;
244 virtual const char *getUnit() = 0;
245 virtual ULONG getMinValue() = 0;
246 virtual ULONG getMaxValue() = 0;
247 virtual ULONG getScale() = 0;
248
249 bool collectorBeat(uint64_t nowAt);
250
251 void enable() { mEnabled = true; };
252 void disable() { mEnabled = false; };
253
254 bool isEnabled() { return mEnabled; };
255 ULONG getPeriod() { return mPeriod; };
256 ULONG getLength() { return mLength; };
257 const char *getName() { return mName; };
258 ComPtr<IUnknown> getObject() { return mObject; };
259 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
260
261 protected:
262 ULONG mPeriod;
263 ULONG mLength;
264 CollectorHAL *mHAL;
265 const char *mName;
266 ComPtr<IUnknown> mObject;
267 uint64_t mLastSampleTaken;
268 bool mEnabled;
269 };
270
271 class BaseGuestMetric : public BaseMetric
272 {
273 public:
274 BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
275 : BaseMetric(NULL, name, object), mCGuest(cguest) {};
276 protected:
277 CollectorGuest *mCGuest;
278 };
279
280 class HostCpuLoad : public BaseMetric
281 {
282 public:
283 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
284 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
285 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
286
287 void init(ULONG period, ULONG length);
288
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
295 protected:
296 SubMetric *mUser;
297 SubMetric *mKernel;
298 SubMetric *mIdle;
299 };
300
301 class HostCpuLoadRaw : public HostCpuLoad
302 {
303 public:
304 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
305 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
306
307 void preCollect(CollectorHints& hints, uint64_t iTick);
308 void collect();
309 private:
310 uint64_t mUserPrev;
311 uint64_t mKernelPrev;
312 uint64_t mIdlePrev;
313 };
314
315 class HostCpuMhz : public BaseMetric
316 {
317 public:
318 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
319 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
320 ~HostCpuMhz() { delete mMHz; };
321
322 void init(ULONG period, ULONG length);
323 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
324 void collect();
325 const char *getUnit() { return "MHz"; };
326 ULONG getMinValue() { return 0; };
327 ULONG getMaxValue() { return INT32_MAX; };
328 ULONG getScale() { return 1; }
329 private:
330 SubMetric *mMHz;
331 };
332
333 class HostRamUsage : public BaseMetric
334 {
335 public:
336 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
337 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
338 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
339
340 void init(ULONG period, ULONG length);
341 void preCollect(CollectorHints& hints, uint64_t iTick);
342 void collect();
343 const char *getUnit() { return "kB"; };
344 ULONG getMinValue() { return 0; };
345 ULONG getMaxValue() { return INT32_MAX; };
346 ULONG getScale() { return 1; }
347 private:
348 SubMetric *mTotal;
349 SubMetric *mUsed;
350 SubMetric *mAvailable;
351 };
352
353 class HostRamVmm : public BaseMetric
354 {
355 public:
356 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
357 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
358 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
359 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
360 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
361
362 void init(ULONG period, ULONG length);
363 void preCollect(CollectorHints& hints, uint64_t iTick);
364 void collect();
365 const char *getUnit() { return "kB"; };
366 ULONG getMinValue() { return 0; };
367 ULONG getMaxValue() { return INT32_MAX; };
368 ULONG getScale() { return 1; }
369
370 private:
371 CollectorGuestManager *mCollectorGuestManager;
372 SubMetric *mAllocVMM;
373 SubMetric *mFreeVMM;
374 SubMetric *mBalloonVMM;
375 SubMetric *mSharedVMM;
376 ULONG mAllocCurrent;
377 ULONG mFreeCurrent;
378 ULONG mBalloonedCurrent;
379 ULONG mSharedCurrent;
380 };
381
382 class MachineCpuLoad : public BaseMetric
383 {
384 public:
385 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
386 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
387 ~MachineCpuLoad() { delete mUser; delete mKernel; };
388
389 void init(ULONG period, ULONG length);
390 void collect();
391 const char *getUnit() { return "%"; };
392 ULONG getMinValue() { return 0; };
393 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
394 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
395 protected:
396 RTPROCESS mProcess;
397 SubMetric *mUser;
398 SubMetric *mKernel;
399 };
400
401 class MachineCpuLoadRaw : public MachineCpuLoad
402 {
403 public:
404 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
405 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
406
407 void preCollect(CollectorHints& hints, uint64_t iTick);
408 void collect();
409 private:
410 uint64_t mHostTotalPrev;
411 uint64_t mProcessUserPrev;
412 uint64_t mProcessKernelPrev;
413 };
414
415 class MachineRamUsage : public BaseMetric
416 {
417 public:
418 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
419 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
420 ~MachineRamUsage() { delete mUsed; };
421
422 void init(ULONG period, ULONG length);
423 void preCollect(CollectorHints& hints, uint64_t iTick);
424 void collect();
425 const char *getUnit() { return "kB"; };
426 ULONG getMinValue() { return 0; };
427 ULONG getMaxValue() { return INT32_MAX; };
428 ULONG getScale() { return 1; }
429 private:
430 RTPROCESS mProcess;
431 SubMetric *mUsed;
432 };
433
434
435 class GuestCpuLoad : public BaseGuestMetric
436 {
437 public:
438 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
439 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
440 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
441
442 void init(ULONG period, ULONG length);
443 void preCollect(CollectorHints& hints, uint64_t iTick);
444 void collect();
445 const char *getUnit() { return "%"; };
446 ULONG getMinValue() { return 0; };
447 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
448 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
449 protected:
450 SubMetric *mUser;
451 SubMetric *mKernel;
452 SubMetric *mIdle;
453 };
454
455 class GuestRamUsage : public BaseGuestMetric
456 {
457 public:
458 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
459 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
460 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
461
462 void init(ULONG period, ULONG length);
463 void preCollect(CollectorHints& hints, uint64_t iTick);
464 void collect();
465 const char *getUnit() { return "kB"; };
466 ULONG getMinValue() { return 0; };
467 ULONG getMaxValue() { return INT32_MAX; };
468 ULONG getScale() { return 1; }
469 private:
470 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
471 };
472
473 /* Aggregate Functions **************************************************/
474 class Aggregate
475 {
476 public:
477 virtual ULONG compute(ULONG *data, ULONG length) = 0;
478 virtual const char *getName() = 0;
479 };
480
481 class AggregateAvg : public Aggregate
482 {
483 public:
484 virtual ULONG compute(ULONG *data, ULONG length);
485 virtual const char *getName();
486 };
487
488 class AggregateMin : public Aggregate
489 {
490 public:
491 virtual ULONG compute(ULONG *data, ULONG length);
492 virtual const char *getName();
493 };
494
495 class AggregateMax : public Aggregate
496 {
497 public:
498 virtual ULONG compute(ULONG *data, ULONG length);
499 virtual const char *getName();
500 };
501
502 /* Metric Class *********************************************************/
503 class Metric
504 {
505 public:
506 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
507 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
508 {
509 if (mAggregate)
510 {
511 mName.append(":");
512 mName.append(mAggregate->getName());
513 }
514 }
515
516 ~Metric()
517 {
518 delete mAggregate;
519 }
520 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
521
522 const char *getName() { return mName.c_str(); };
523 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
524 const char *getDescription()
525 { return mAggregate ? "" : mSubMetric->getDescription(); };
526 const char *getUnit() { return mBaseMetric->getUnit(); };
527 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
528 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
529 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
530 ULONG getLength()
531 { return mAggregate ? 1 : mBaseMetric->getLength(); };
532 ULONG getScale() { return mBaseMetric->getScale(); }
533 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
534
535 private:
536 iprt::MiniString mName;
537 BaseMetric *mBaseMetric;
538 SubMetric *mSubMetric;
539 Aggregate *mAggregate;
540 };
541
542 /* Filter Class *********************************************************/
543
544 class Filter
545 {
546 public:
547 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
548 ComSafeArrayIn(IUnknown * , objects));
549 static bool patternMatch(const char *pszPat, const char *pszName,
550 bool fSeenColon = false);
551 bool match(const ComPtr<IUnknown> object, const iprt::MiniString &name) const;
552 private:
553 void init(ComSafeArrayIn(IN_BSTR, metricNames),
554 ComSafeArrayIn(IUnknown * , objects));
555
556 typedef std::pair<const ComPtr<IUnknown>, const iprt::MiniString> FilterElement;
557 typedef std::list<FilterElement> ElementList;
558
559 ElementList mElements;
560
561 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
562 };
563}
564#endif /* ___performance_h */
565/* vi: set tabstop=4 shiftwidth=4 expandtab: */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette