VirtualBox

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

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

Main: separate internal machine data structs into MachineImplPrivate.h to significantly speed up compilation and for better interface separation; remove obsolete ConsoleEvents.h file

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