VirtualBox

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

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

PerformanceImpl.cpp: r=bird: marked what looks like an invalid std::list::erase use.

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

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