VirtualBox

source: vbox/trunk/src/VBox/Main/PerformanceImpl.cpp@ 25275

Last change on this file since 25275 was 25184, checked in by vboxsync, 15 years ago

Main: bring back r55600 with fix for broken machine creation

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 KB
RevLine 
[10641]1/* $Id: PerformanceImpl.cpp 25184 2009-12-04 11:37:03Z vboxsync $ */
2
3/** @file
4 *
5 * VBox Performance API COM Classes implementation
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#include "PerformanceImpl.h"
25
26#include "Logging.h"
27
28#include <iprt/process.h>
29
[16560]30#include <VBox/err.h>
31#include <VBox/settings.h>
32
[10641]33#include <vector>
34#include <algorithm>
35#include <functional>
36
[18252]37#include "Performance.h"
38
[10641]39static Bstr gMetricNames[] =
40{
[11377]41 "CPU/Load/User",
[10679]42 "CPU/Load/User:avg",
43 "CPU/Load/User:min",
44 "CPU/Load/User:max",
[11377]45 "CPU/Load/Kernel",
[10679]46 "CPU/Load/Kernel:avg",
47 "CPU/Load/Kernel:min",
48 "CPU/Load/Kernel:max",
[11377]49 "CPU/Load/Idle",
[10679]50 "CPU/Load/Idle:avg",
51 "CPU/Load/Idle:min",
52 "CPU/Load/Idle:max",
[11377]53 "CPU/MHz",
[10641]54 "CPU/MHz:avg",
55 "CPU/MHz:min",
56 "CPU/MHz:max",
[11377]57 "RAM/Usage/Total",
[10679]58 "RAM/Usage/Total:avg",
59 "RAM/Usage/Total:min",
60 "RAM/Usage/Total:max",
[11377]61 "RAM/Usage/Used",
[10679]62 "RAM/Usage/Used:avg",
63 "RAM/Usage/Used:min",
64 "RAM/Usage/Used:max",
[11377]65 "RAM/Usage/Free",
[10679]66 "RAM/Usage/Free:avg",
67 "RAM/Usage/Free:min",
68 "RAM/Usage/Free:max",
[10641]69};
70
71////////////////////////////////////////////////////////////////////////////////
72// PerformanceCollector class
73////////////////////////////////////////////////////////////////////////////////
74
75// constructor / destructor
76////////////////////////////////////////////////////////////////////////////////
77
[10713]78PerformanceCollector::PerformanceCollector() : mMagic(0) {}
[10641]79
80PerformanceCollector::~PerformanceCollector() {}
81
82HRESULT PerformanceCollector::FinalConstruct()
83{
[21878]84 LogFlowThisFunc(("\n"));
[10641]85
86 return S_OK;
87}
88
89void PerformanceCollector::FinalRelease()
90{
[21878]91 LogFlowThisFunc(("\n"));
[10641]92}
93
94// public initializer/uninitializer for internal purposes only
95////////////////////////////////////////////////////////////////////////////////
96
97/**
98 * Initializes the PerformanceCollector object.
99 */
100HRESULT PerformanceCollector::init()
101{
102 /* Enclose the state transition NotReady->InInit->Ready */
[21878]103 AutoInitSpan autoInitSpan(this);
104 AssertReturn(autoInitSpan.isOk(), E_FAIL);
[10641]105
106 LogFlowThisFuncEnter();
107
108 HRESULT rc = S_OK;
109
[12400]110 m.hal = pm::createHAL();
[10713]111
112 /* Let the sampler know it gets a valid collector. */
113 mMagic = MAGIC;
114
[10641]115 /* Start resource usage sampler */
[10959]116 int vrc = RTTimerLRCreate (&m.sampler, VBOX_USAGE_SAMPLER_MIN_INTERVAL,
117 &PerformanceCollector::staticSamplerCallback, this);
[10641]118 AssertMsgRC (vrc, ("Failed to create resource usage "
119 "sampling timer(%Rra)\n", vrc));
[21878]120 if (RT_FAILURE(vrc))
[10641]121 rc = E_FAIL;
122
[21878]123 if (SUCCEEDED(rc))
[10641]124 autoInitSpan.setSucceeded();
125
126 LogFlowThisFuncLeave();
127
128 return rc;
129}
130
131/**
132 * Uninitializes the PerformanceCollector object.
133 *
134 * Called either from FinalRelease() or by the parent when it gets destroyed.
135 */
136void PerformanceCollector::uninit()
137{
138 LogFlowThisFuncEnter();
139
140 /* Enclose the state transition Ready->InUninit->NotReady */
[21878]141 AutoUninitSpan autoUninitSpan(this);
[10641]142 if (autoUninitSpan.uninitDone())
143 {
[21878]144 LogFlowThisFunc(("Already uninitialized.\n"));
[10641]145 LogFlowThisFuncLeave();
146 return;
147 }
148
[10713]149 mMagic = 0;
150
[10641]151 /* Destroy resource usage sampler */
[10959]152 int vrc = RTTimerLRDestroy (m.sampler);
[10641]153 AssertMsgRC (vrc, ("Failed to destroy resource usage "
154 "sampling timer (%Rra)\n", vrc));
[10770]155 m.sampler = NULL;
[10641]156
[12400]157 //delete m.factory;
158 //m.factory = NULL;
[10641]159
[12400]160 delete m.hal;
161 m.hal = NULL;
162
[10641]163 LogFlowThisFuncLeave();
164}
165
166// IPerformanceCollector properties
167////////////////////////////////////////////////////////////////////////////////
168
169STDMETHODIMP
[21878]170PerformanceCollector::COMGETTER(MetricNames) (ComSafeArrayOut(BSTR, theMetricNames))
[10641]171{
[21878]172 if (ComSafeArrayOutIsNull(theMetricNames))
[10641]173 return E_POINTER;
174
[21878]175 AutoCaller autoCaller(this);
[25149]176 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[10641]177
[21878]178 AutoReadLock alock(this);
[10641]179
[21878]180 com::SafeArray<BSTR> metricNames(RT_ELEMENTS(gMetricNames));
[10641]181 for (size_t i = 0; i < RT_ELEMENTS(gMetricNames); i++)
182 {
[22399]183 Bstr tmp(gMetricNames[i]); /* gcc-3.3 cruft */
184 tmp.cloneTo(&metricNames[i]);
[10641]185 }
[21878]186 //gMetricNames.detachTo(ComSafeArrayOutArg(theMetricNames));
187 metricNames.detachTo(ComSafeArrayOutArg(theMetricNames));
[10641]188
189 return S_OK;
190}
191
192// IPerformanceCollector methods
193////////////////////////////////////////////////////////////////////////////////
194
[12668]195HRESULT PerformanceCollector::toIPerformanceMetric(pm::Metric *src, IPerformanceMetric **dst)
196{
[21878]197 ComObjPtr<PerformanceMetric> metric;
[12668]198 HRESULT rc = metric.createObject();
[21878]199 if (SUCCEEDED(rc))
[12668]200 rc = metric->init (src);
[21878]201 AssertComRCReturnRC(rc);
202 metric.queryInterfaceTo(dst);
[12668]203 return rc;
204}
205
206HRESULT PerformanceCollector::toIPerformanceMetric(pm::BaseMetric *src, IPerformanceMetric **dst)
207{
[21878]208 ComObjPtr<PerformanceMetric> metric;
[12668]209 HRESULT rc = metric.createObject();
[21878]210 if (SUCCEEDED(rc))
[12668]211 rc = metric->init (src);
[21878]212 AssertComRCReturnRC(rc);
213 metric.queryInterfaceTo(dst);
[12668]214 return rc;
215}
216
[10770]217STDMETHODIMP
[15051]218PerformanceCollector::GetMetrics (ComSafeArrayIn (IN_BSTR, metricNames),
[10770]219 ComSafeArrayIn (IUnknown *, objects),
[21878]220 ComSafeArrayOut(IPerformanceMetric *, outMetrics))
[10641]221{
[10868]222 LogFlowThisFuncEnter();
[21878]223 //LogFlowThisFunc(("mState=%d, mType=%d\n", mState, mType));
[10641]224
[10725]225 HRESULT rc = S_OK;
226
[21878]227 AutoCaller autoCaller(this);
[25149]228 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[10641]229
[10770]230 pm::Filter filter (ComSafeArrayInArg (metricNames),
231 ComSafeArrayInArg (objects));
[10725]232
[21878]233 AutoReadLock alock(this);
[10753]234
[10725]235 MetricList filteredMetrics;
236 MetricList::iterator it;
[10770]237 for (it = m.metrics.begin(); it != m.metrics.end(); ++it)
238 if (filter.match ((*it)->getObject(), (*it)->getName()))
239 filteredMetrics.push_back (*it);
[10725]240
[10770]241 com::SafeIfaceArray<IPerformanceMetric> retMetrics (filteredMetrics.size());
[10725]242 int i = 0;
[10753]243 for (it = filteredMetrics.begin(); it != filteredMetrics.end(); ++it)
[10725]244 {
[21878]245 ComObjPtr<PerformanceMetric> metric;
[10725]246 rc = metric.createObject();
[21878]247 if (SUCCEEDED(rc))
[10725]248 rc = metric->init (*it);
[21878]249 AssertComRCReturnRC(rc);
[10770]250 LogFlow (("PerformanceCollector::GetMetrics() store a metric at "
251 "retMetrics[%d]...\n", i));
[21878]252 metric.queryInterfaceTo(&retMetrics [i++]);
[10725]253 }
[21878]254 retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
[10868]255 LogFlowThisFuncLeave();
[10725]256 return rc;
[10641]257}
258
[10770]259STDMETHODIMP
[15051]260PerformanceCollector::SetupMetrics (ComSafeArrayIn (IN_BSTR, metricNames),
[10770]261 ComSafeArrayIn (IUnknown *, objects),
[13082]262 ULONG aPeriod, ULONG aCount,
[21878]263 ComSafeArrayOut(IPerformanceMetric *,
[13082]264 outMetrics))
[10641]265{
[21878]266 AutoCaller autoCaller(this);
[25149]267 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[10725]268
[10770]269 pm::Filter filter (ComSafeArrayInArg (metricNames),
270 ComSafeArrayInArg (objects));
[10641]271
[21878]272 AutoWriteLock alock(this);
[10753]273
[12668]274 HRESULT rc = S_OK;
275 BaseMetricList filteredMetrics;
[10679]276 BaseMetricList::iterator it;
[10770]277 for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); ++it)
[10679]278 if (filter.match((*it)->getObject(), (*it)->getName()))
[10713]279 {
[11336]280 LogFlow (("PerformanceCollector::SetupMetrics() setting period to %u,"
281 " count to %u for %s\n", aPeriod, aCount, (*it)->getName()));
[10641]282 (*it)->init(aPeriod, aCount);
[11481]283 if (aPeriod == 0 || aCount == 0)
284 {
285 LogFlow (("PerformanceCollector::SetupMetrics() disabling %s\n",
286 (*it)->getName()));
287 (*it)->disable();
288 }
289 else
290 {
291 LogFlow (("PerformanceCollector::SetupMetrics() enabling %s\n",
292 (*it)->getName()));
293 (*it)->enable();
294 }
[13082]295 filteredMetrics.push_back(*it);
[10713]296 }
[14579]297
[13082]298 com::SafeIfaceArray<IPerformanceMetric> retMetrics (filteredMetrics.size());
299 int i = 0;
300 for (it = filteredMetrics.begin();
[21878]301 it != filteredMetrics.end() && SUCCEEDED(rc); ++it)
[13082]302 rc = toIPerformanceMetric(*it, &retMetrics [i++]);
[21878]303 retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
[13082]304
[12668]305 LogFlowThisFuncLeave();
306 return rc;
[10641]307}
308
[10770]309STDMETHODIMP
[15051]310PerformanceCollector::EnableMetrics (ComSafeArrayIn (IN_BSTR, metricNames),
[13082]311 ComSafeArrayIn (IUnknown *, objects),
[21878]312 ComSafeArrayOut(IPerformanceMetric *,
[13082]313 outMetrics))
[10641]314{
[21878]315 AutoCaller autoCaller(this);
[25149]316 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[10725]317
[10770]318 pm::Filter filter (ComSafeArrayInArg (metricNames),
319 ComSafeArrayInArg (objects));
[10713]320
[21878]321 AutoWriteLock alock(this); /* Write lock is not needed atm since we are */
[10868]322 /* fiddling with enable bit only, but we */
323 /* care for those who come next :-). */
[10770]324
[12668]325 HRESULT rc = S_OK;
326 BaseMetricList filteredMetrics;
[10713]327 BaseMetricList::iterator it;
[10770]328 for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); ++it)
[10713]329 if (filter.match((*it)->getObject(), (*it)->getName()))
[12668]330 {
[10713]331 (*it)->enable();
[13082]332 filteredMetrics.push_back(*it);
[12668]333 }
[10713]334
[13082]335 com::SafeIfaceArray<IPerformanceMetric> retMetrics (filteredMetrics.size());
336 int i = 0;
337 for (it = filteredMetrics.begin();
[21878]338 it != filteredMetrics.end() && SUCCEEDED(rc); ++it)
[13082]339 rc = toIPerformanceMetric(*it, &retMetrics [i++]);
[21878]340 retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
[13082]341
[12668]342 LogFlowThisFuncLeave();
343 return rc;
[10641]344}
345
[10770]346STDMETHODIMP
[15051]347PerformanceCollector::DisableMetrics (ComSafeArrayIn (IN_BSTR, metricNames),
[12668]348 ComSafeArrayIn (IUnknown *, objects),
[21878]349 ComSafeArrayOut(IPerformanceMetric *,
[12668]350 outMetrics))
351{
[21878]352 AutoCaller autoCaller(this);
[25149]353 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[10725]354
[10770]355 pm::Filter filter (ComSafeArrayInArg (metricNames),
356 ComSafeArrayInArg (objects));
[10713]357
[21878]358 AutoWriteLock alock(this); /* Write lock is not needed atm since we are */
[10868]359 /* fiddling with enable bit only, but we */
360 /* care for those who come next :-). */
[10770]361
[12668]362 HRESULT rc = S_OK;
363 BaseMetricList filteredMetrics;
[10713]364 BaseMetricList::iterator it;
[10770]365 for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); ++it)
[10713]366 if (filter.match((*it)->getObject(), (*it)->getName()))
[12668]367 {
[10713]368 (*it)->disable();
[13082]369 filteredMetrics.push_back(*it);
[12668]370 }
[10713]371
[13082]372 com::SafeIfaceArray<IPerformanceMetric> retMetrics (filteredMetrics.size());
373 int i = 0;
374 for (it = filteredMetrics.begin();
[21878]375 it != filteredMetrics.end() && SUCCEEDED(rc); ++it)
[13082]376 rc = toIPerformanceMetric(*it, &retMetrics [i++]);
[21878]377 retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
[13082]378
[12668]379 LogFlowThisFuncLeave();
380 return rc;
[10641]381}
382
[10770]383STDMETHODIMP
[15051]384PerformanceCollector::QueryMetricsData (ComSafeArrayIn (IN_BSTR, metricNames),
[10770]385 ComSafeArrayIn (IUnknown *, objects),
[21878]386 ComSafeArrayOut(BSTR, outMetricNames),
387 ComSafeArrayOut(IUnknown *, outObjects),
388 ComSafeArrayOut(BSTR, outUnits),
389 ComSafeArrayOut(ULONG, outScales),
390 ComSafeArrayOut(ULONG, outSequenceNumbers),
391 ComSafeArrayOut(ULONG, outDataIndices),
392 ComSafeArrayOut(ULONG, outDataLengths),
393 ComSafeArrayOut(LONG, outData))
[10641]394{
[21878]395 AutoCaller autoCaller(this);
[25149]396 if (FAILED(autoCaller.rc())) return autoCaller.rc();
[10641]397
[10868]398 pm::Filter filter (ComSafeArrayInArg (metricNames),
399 ComSafeArrayInArg (objects));
400
[21878]401 AutoReadLock alock(this);
[10641]402
403 /* Let's compute the size of the resulting flat array */
[10868]404 size_t flatSize = 0;
405 MetricList filteredMetrics;
406 MetricList::iterator it;
[10770]407 for (it = m.metrics.begin(); it != m.metrics.end(); ++it)
[10868]408 if (filter.match ((*it)->getObject(), (*it)->getName()))
409 {
410 filteredMetrics.push_back (*it);
411 flatSize += (*it)->getLength();
412 }
413
414 int i = 0;
[10641]415 size_t flatIndex = 0;
[10868]416 size_t numberOfMetrics = filteredMetrics.size();
[21878]417 com::SafeArray<BSTR> retNames (numberOfMetrics);
418 com::SafeIfaceArray<IUnknown> retObjects (numberOfMetrics);
419 com::SafeArray<BSTR> retUnits (numberOfMetrics);
420 com::SafeArray<ULONG> retScales (numberOfMetrics);
421 com::SafeArray<ULONG> retSequenceNumbers (numberOfMetrics);
422 com::SafeArray<ULONG> retIndices (numberOfMetrics);
423 com::SafeArray<ULONG> retLengths (numberOfMetrics);
424 com::SafeArray<LONG> retData (flatSize);
[10713]425
[10868]426 for (it = filteredMetrics.begin(); it != filteredMetrics.end(); ++it, ++i)
[10641]427 {
[12973]428 ULONG *values, length, sequenceNumber;
[10641]429 /* @todo We may want to revise the query method to get rid of excessive alloc/memcpy calls. */
[12973]430 (*it)->query(&values, &length, &sequenceNumber);
[11336]431 LogFlow (("PerformanceCollector::QueryMetricsData() querying metric %s "
432 "returned %d values.\n", (*it)->getName(), length));
[10641]433 memcpy(retData.raw() + flatIndex, values, length * sizeof(*values));
434 Bstr tmp((*it)->getName());
435 tmp.detachTo(&retNames[i]);
[21878]436 (*it)->getObject().queryInterfaceTo(&retObjects[i]);
[12973]437 tmp = (*it)->getUnit();
438 tmp.detachTo(&retUnits[i]);
439 retScales[i] = (*it)->getScale();
440 retSequenceNumbers[i] = sequenceNumber;
[10641]441 retLengths[i] = length;
[18487]442 retIndices[i] = (ULONG)flatIndex;
[10641]443 flatIndex += length;
444 }
[10713]445
[21878]446 retNames.detachTo(ComSafeArrayOutArg(outMetricNames));
447 retObjects.detachTo(ComSafeArrayOutArg(outObjects));
448 retUnits.detachTo(ComSafeArrayOutArg(outUnits));
449 retScales.detachTo(ComSafeArrayOutArg(outScales));
450 retSequenceNumbers.detachTo(ComSafeArrayOutArg(outSequenceNumbers));
451 retIndices.detachTo(ComSafeArrayOutArg(outDataIndices));
452 retLengths.detachTo(ComSafeArrayOutArg(outDataLengths));
453 retData.detachTo(ComSafeArrayOutArg(outData));
[10641]454 return S_OK;
455}
456
457// public methods for internal purposes
458///////////////////////////////////////////////////////////////////////////////
459
460void PerformanceCollector::registerBaseMetric (pm::BaseMetric *baseMetric)
461{
[11391]462 //LogFlowThisFuncEnter();
[21878]463 AutoCaller autoCaller(this);
464 if (!SUCCEEDED(autoCaller.rc())) return;
[10770]465
[21878]466 AutoWriteLock alock(this);
[11391]467 LogAleksey(("{%p} " LOG_FN_FMT ": obj=%p name=%s\n", this, __PRETTY_FUNCTION__, (void *)baseMetric->getObject(), baseMetric->getName()));
[10770]468 m.baseMetrics.push_back (baseMetric);
[11391]469 //LogFlowThisFuncLeave();
[10641]470}
471
472void PerformanceCollector::registerMetric (pm::Metric *metric)
473{
[11391]474 //LogFlowThisFuncEnter();
[21878]475 AutoCaller autoCaller(this);
476 if (!SUCCEEDED(autoCaller.rc())) return;
[10770]477
[21878]478 AutoWriteLock alock(this);
[11391]479 LogAleksey(("{%p} " LOG_FN_FMT ": obj=%p name=%s\n", this, __PRETTY_FUNCTION__, (void *)metric->getObject(), metric->getName()));
[10770]480 m.metrics.push_back (metric);
[11391]481 //LogFlowThisFuncLeave();
[10641]482}
483
[21878]484void PerformanceCollector::unregisterBaseMetricsFor (const ComPtr<IUnknown> &aObject)
[10641]485{
[11391]486 //LogFlowThisFuncEnter();
[21878]487 AutoCaller autoCaller(this);
488 if (!SUCCEEDED(autoCaller.rc())) return;
[10770]489
[21878]490 AutoWriteLock alock(this);
[11391]491 LogAleksey(("{%p} " LOG_FN_FMT ": before remove_if: m.baseMetrics.size()=%d\n", this, __PRETTY_FUNCTION__, m.baseMetrics.size()));
[19161]492 BaseMetricList::iterator it;
493 for (it = m.baseMetrics.begin(); it != m.baseMetrics.end();)
494 if ((*it)->associatedWith(aObject))
495 {
496 delete *it;
[25035]497 it = m.baseMetrics.erase(it);
[19161]498 }
499 else
500 ++it;
[11391]501 LogAleksey(("{%p} " LOG_FN_FMT ": after remove_if: m.baseMetrics.size()=%d\n", this, __PRETTY_FUNCTION__, m.baseMetrics.size()));
502 //LogFlowThisFuncLeave();
[10641]503}
504
[21878]505void PerformanceCollector::unregisterMetricsFor (const ComPtr<IUnknown> &aObject)
[10641]506{
[11391]507 //LogFlowThisFuncEnter();
[21878]508 AutoCaller autoCaller(this);
509 if (!SUCCEEDED(autoCaller.rc())) return;
[10770]510
[21878]511 AutoWriteLock alock(this);
[11391]512 LogAleksey(("{%p} " LOG_FN_FMT ": obj=%p\n", this, __PRETTY_FUNCTION__, (void *)aObject));
[19161]513 MetricList::iterator it;
514 for (it = m.metrics.begin(); it != m.metrics.end();)
515 if ((*it)->associatedWith(aObject))
516 {
517 delete *it;
[25035]518 it = m.metrics.erase(it);
[19161]519 }
520 else
521 ++it;
[11391]522 //LogFlowThisFuncLeave();
[10641]523}
524
[21395]525void PerformanceCollector::suspendSampling()
526{
[21878]527 AutoCaller autoCaller(this);
528 if (!SUCCEEDED(autoCaller.rc())) return;
[21395]529
530 int rc = RTTimerLRStop(m.sampler);
531 AssertRC(rc);
532}
533
534void PerformanceCollector::resumeSampling()
535{
[21878]536 AutoCaller autoCaller(this);
537 if (!SUCCEEDED(autoCaller.rc())) return;
[21395]538
539 int rc = RTTimerLRStart(m.sampler, 0);
540 AssertRC(rc);
541}
542
543
[10641]544// private methods
545///////////////////////////////////////////////////////////////////////////////
546
547/* static */
[10959]548void PerformanceCollector::staticSamplerCallback (RTTIMERLR hTimerLR, void *pvUser,
[17911]549 uint64_t /* iTick */)
[10641]550{
551 AssertReturnVoid (pvUser != NULL);
[10713]552 PerformanceCollector *collector = static_cast <PerformanceCollector *> (pvUser);
[10770]553 Assert (collector->mMagic == MAGIC);
[10713]554 if (collector->mMagic == MAGIC)
555 {
556 collector->samplerCallback();
557 }
[10959]558 NOREF (hTimerLR);
[10641]559}
560
561void PerformanceCollector::samplerCallback()
562{
[11391]563 Log4(("{%p} " LOG_FN_FMT ": ENTER\n", this, __PRETTY_FUNCTION__));
[21878]564 AutoWriteLock alock(this);
[10753]565
[12400]566 pm::CollectorHints hints;
[10713]567 uint64_t timestamp = RTTimeMilliTS();
[12400]568 BaseMetricList toBeCollected;
569 BaseMetricList::iterator it;
570 /* Compose the list of metrics being collected at this moment */
571 for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); it++)
572 if ((*it)->collectorBeat(timestamp))
573 {
574 (*it)->preCollect(hints);
575 toBeCollected.push_back(*it);
576 }
577
[12461]578 if (toBeCollected.size() == 0)
579 return;
580
[12400]581 /* Let know the platform specific code what is being collected */
582 m.hal->preCollect(hints);
583
584 /* Finally, collect the data */
[12456]585 std::for_each (toBeCollected.begin(), toBeCollected.end(),
[12400]586 std::mem_fun (&pm::BaseMetric::collect));
[11391]587 Log4(("{%p} " LOG_FN_FMT ": LEAVE\n", this, __PRETTY_FUNCTION__));
[10641]588}
589
590////////////////////////////////////////////////////////////////////////////////
591// PerformanceMetric class
592////////////////////////////////////////////////////////////////////////////////
593
594// constructor / destructor
595////////////////////////////////////////////////////////////////////////////////
596
[10779]597PerformanceMetric::PerformanceMetric()
[10641]598{
599}
600
601PerformanceMetric::~PerformanceMetric()
602{
603}
604
605HRESULT PerformanceMetric::FinalConstruct()
606{
[21878]607 LogFlowThisFunc(("\n"));
[10641]608
609 return S_OK;
610}
611
612void PerformanceMetric::FinalRelease()
613{
[21878]614 LogFlowThisFunc(("\n"));
[10641]615
616 uninit ();
617}
618
619// public initializer/uninitializer for internal purposes only
620////////////////////////////////////////////////////////////////////////////////
621
622HRESULT PerformanceMetric::init (pm::Metric *aMetric)
623{
[11583]624 m.name = aMetric->getName();
625 m.object = aMetric->getObject();
626 m.description = aMetric->getDescription();
627 m.period = aMetric->getPeriod();
628 m.count = aMetric->getLength();
629 m.unit = aMetric->getUnit();
630 m.min = aMetric->getMinValue();
631 m.max = aMetric->getMaxValue();
[10641]632 return S_OK;
633}
634
[12668]635HRESULT PerformanceMetric::init (pm::BaseMetric *aMetric)
636{
637 m.name = aMetric->getName();
638 m.object = aMetric->getObject();
639 m.description = "";
640 m.period = aMetric->getPeriod();
641 m.count = aMetric->getLength();
642 m.unit = aMetric->getUnit();
643 m.min = aMetric->getMinValue();
644 m.max = aMetric->getMaxValue();
645 return S_OK;
646}
647
[10641]648void PerformanceMetric::uninit()
649{
650}
651
652STDMETHODIMP PerformanceMetric::COMGETTER(MetricName) (BSTR *aMetricName)
653{
[10770]654 /// @todo (r=dmik) why do all these getters not do AutoCaller and
655 /// AutoReadLock? Is the underlying metric a constant object?
656
[21878]657 m.name.cloneTo(aMetricName);
[10641]658 return S_OK;
659}
660
661STDMETHODIMP PerformanceMetric::COMGETTER(Object) (IUnknown **anObject)
662{
[10779]663 m.object.queryInterfaceTo(anObject);
[10641]664 return S_OK;
665}
666
[11583]667STDMETHODIMP PerformanceMetric::COMGETTER(Description) (BSTR *aDescription)
668{
[21878]669 m.description.cloneTo(aDescription);
[11583]670 return S_OK;
671}
672
[10725]673STDMETHODIMP PerformanceMetric::COMGETTER(Period) (ULONG *aPeriod)
[10641]674{
[10779]675 *aPeriod = m.period;
[10641]676 return S_OK;
677}
678
[10725]679STDMETHODIMP PerformanceMetric::COMGETTER(Count) (ULONG *aCount)
[10641]680{
[10779]681 *aCount = m.count;
[10641]682 return S_OK;
683}
684
685STDMETHODIMP PerformanceMetric::COMGETTER(Unit) (BSTR *aUnit)
686{
[10779]687 m.unit.cloneTo(aUnit);
[10641]688 return S_OK;
689}
690
[10725]691STDMETHODIMP PerformanceMetric::COMGETTER(MinimumValue) (LONG *aMinValue)
[10641]692{
[10779]693 *aMinValue = m.min;
[10641]694 return S_OK;
695}
696
[10725]697STDMETHODIMP PerformanceMetric::COMGETTER(MaximumValue) (LONG *aMaxValue)
[10641]698{
[10779]699 *aMaxValue = m.max;
[10641]700 return S_OK;
701}
[14772]702/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use