VirtualBox

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

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

Backed out 55600; unable to create new VMs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1/* $Id: PerformanceImpl.cpp 25182 2009-12-04 10:50:15Z 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
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 if (FAILED(autoCaller.rc())) return 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 if (FAILED(autoCaller.rc())) return 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 if (FAILED(autoCaller.rc())) return 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 if (FAILED(autoCaller.rc())) return 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 if (FAILED(autoCaller.rc())) return 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 if (FAILED(autoCaller.rc())) return 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 delete *it;
497 it = m.baseMetrics.erase(it);
498 }
499 else
500 ++it;
501 LogAleksey(("{%p} " LOG_FN_FMT ": after remove_if: m.baseMetrics.size()=%d\n", this, __PRETTY_FUNCTION__, m.baseMetrics.size()));
502 //LogFlowThisFuncLeave();
503}
504
505void PerformanceCollector::unregisterMetricsFor (const ComPtr<IUnknown> &aObject)
506{
507 //LogFlowThisFuncEnter();
508 AutoCaller autoCaller(this);
509 if (!SUCCEEDED(autoCaller.rc())) return;
510
511 AutoWriteLock alock(this);
512 LogAleksey(("{%p} " LOG_FN_FMT ": obj=%p\n", this, __PRETTY_FUNCTION__, (void *)aObject));
513 MetricList::iterator it;
514 for (it = m.metrics.begin(); it != m.metrics.end();)
515 if ((*it)->associatedWith(aObject))
516 {
517 delete *it;
518 it = m.metrics.erase(it);
519 }
520 else
521 ++it;
522 //LogFlowThisFuncLeave();
523}
524
525void PerformanceCollector::suspendSampling()
526{
527 AutoCaller autoCaller(this);
528 if (!SUCCEEDED(autoCaller.rc())) return;
529
530 Log(("PerformanceCollector::suspendSampling\n"));
531 int rc = RTTimerLRStop(m.sampler);
532 AssertRC(rc);
533}
534
535void PerformanceCollector::resumeSampling()
536{
537 AutoCaller autoCaller(this);
538 if (!SUCCEEDED(autoCaller.rc())) return;
539
540 Log(("PerformanceCollector::resumeSampling\n"));
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 {
558Log(("staticSamplerCallback %RX64\n", RTTimeNanoTS()));
559 collector->samplerCallback();
560 }
561 NOREF (hTimerLR);
562}
563
564void PerformanceCollector::samplerCallback()
565{
566 Log4(("{%p} " LOG_FN_FMT ": ENTER\n", this, __PRETTY_FUNCTION__));
567 AutoWriteLock alock(this);
568
569 pm::CollectorHints hints;
570 uint64_t timestamp = RTTimeMilliTS();
571 BaseMetricList toBeCollected;
572 BaseMetricList::iterator it;
573 /* Compose the list of metrics being collected at this moment */
574 for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); it++)
575 if ((*it)->collectorBeat(timestamp))
576 {
577 (*it)->preCollect(hints);
578 toBeCollected.push_back(*it);
579 }
580
581 if (toBeCollected.size() == 0)
582 return;
583
584 /* Let know the platform specific code what is being collected */
585 m.hal->preCollect(hints);
586
587 /* Finally, collect the data */
588 std::for_each (toBeCollected.begin(), toBeCollected.end(),
589 std::mem_fun (&pm::BaseMetric::collect));
590 Log4(("{%p} " LOG_FN_FMT ": LEAVE\n", this, __PRETTY_FUNCTION__));
591}
592
593////////////////////////////////////////////////////////////////////////////////
594// PerformanceMetric class
595////////////////////////////////////////////////////////////////////////////////
596
597// constructor / destructor
598////////////////////////////////////////////////////////////////////////////////
599
600PerformanceMetric::PerformanceMetric()
601{
602}
603
604PerformanceMetric::~PerformanceMetric()
605{
606}
607
608HRESULT PerformanceMetric::FinalConstruct()
609{
610 LogFlowThisFunc(("\n"));
611
612 return S_OK;
613}
614
615void PerformanceMetric::FinalRelease()
616{
617 LogFlowThisFunc(("\n"));
618
619 uninit ();
620}
621
622// public initializer/uninitializer for internal purposes only
623////////////////////////////////////////////////////////////////////////////////
624
625HRESULT PerformanceMetric::init (pm::Metric *aMetric)
626{
627 m.name = aMetric->getName();
628 m.object = aMetric->getObject();
629 m.description = aMetric->getDescription();
630 m.period = aMetric->getPeriod();
631 m.count = aMetric->getLength();
632 m.unit = aMetric->getUnit();
633 m.min = aMetric->getMinValue();
634 m.max = aMetric->getMaxValue();
635 return S_OK;
636}
637
638HRESULT PerformanceMetric::init (pm::BaseMetric *aMetric)
639{
640 m.name = aMetric->getName();
641 m.object = aMetric->getObject();
642 m.description = "";
643 m.period = aMetric->getPeriod();
644 m.count = aMetric->getLength();
645 m.unit = aMetric->getUnit();
646 m.min = aMetric->getMinValue();
647 m.max = aMetric->getMaxValue();
648 return S_OK;
649}
650
651void PerformanceMetric::uninit()
652{
653}
654
655STDMETHODIMP PerformanceMetric::COMGETTER(MetricName) (BSTR *aMetricName)
656{
657 /// @todo (r=dmik) why do all these getters not do AutoCaller and
658 /// AutoReadLock? Is the underlying metric a constant object?
659
660 m.name.cloneTo(aMetricName);
661 return S_OK;
662}
663
664STDMETHODIMP PerformanceMetric::COMGETTER(Object) (IUnknown **anObject)
665{
666 m.object.queryInterfaceTo(anObject);
667 return S_OK;
668}
669
670STDMETHODIMP PerformanceMetric::COMGETTER(Description) (BSTR *aDescription)
671{
672 m.description.cloneTo(aDescription);
673 return S_OK;
674}
675
676STDMETHODIMP PerformanceMetric::COMGETTER(Period) (ULONG *aPeriod)
677{
678 *aPeriod = m.period;
679 return S_OK;
680}
681
682STDMETHODIMP PerformanceMetric::COMGETTER(Count) (ULONG *aCount)
683{
684 *aCount = m.count;
685 return S_OK;
686}
687
688STDMETHODIMP PerformanceMetric::COMGETTER(Unit) (BSTR *aUnit)
689{
690 m.unit.cloneTo(aUnit);
691 return S_OK;
692}
693
694STDMETHODIMP PerformanceMetric::COMGETTER(MinimumValue) (LONG *aMinValue)
695{
696 *aMinValue = m.min;
697 return S_OK;
698}
699
700STDMETHODIMP PerformanceMetric::COMGETTER(MaximumValue) (LONG *aMaxValue)
701{
702 *aMaxValue = m.max;
703 return S_OK;
704}
705/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use