Performance.cpp revision 2db3ef4e3e71073797237d3c34dcd7d9943a26aa
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/* $Id$ */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/** @file
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * VBox Performance Classes implementation.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/*
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * available from http://www.virtualbox.org. This file is free software;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * you can redistribute it and/or modify it under the terms of the GNU
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * General Public License (GPL) as published by the Free Software
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * additional information or have any questions.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/*
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @todo list:
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * 1) Solaris backend
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * 2) Linux backend
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * 3) Detection of erroneous metric names
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * 4) Min/max ranges for metrics
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * 5) Darwin backend
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * 6) [OS/2 backend]
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <VBox/com/array.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <VBox/com/ptr.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <VBox/com/string.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <VBox/err.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <iprt/string.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <iprt/mem.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include "Logging.h"
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include "Performance.h"
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncusing namespace pm;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync// Default factory
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncBaseMetric *MetricFactory::createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync Assert(mHAL);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return new HostCpuLoadRaw(mHAL, object, user, kernel, idle);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncBaseMetric *MetricFactory::createHostCpuMHz(ComPtr<IUnknown> object, SubMetric *mhz)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync Assert(mHAL);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return new HostCpuMhz(mHAL, object, mhz);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncBaseMetric *MetricFactory::createHostRamUsage(ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync Assert(mHAL);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return new HostRamUsage(mHAL, object, total, used, available);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncBaseMetric *MetricFactory::createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync Assert(mHAL);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return new MachineCpuLoadRaw(mHAL, object, process, user, kernel);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncBaseMetric *MetricFactory::createMachineRamUsage(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync Assert(mHAL);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return new MachineRamUsage(mHAL, object, process, used);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync// Stubs for non-pure virtual methods
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncint CollectorHAL::getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return E_NOTIMPL;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncint CollectorHAL::getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel)
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync return E_NOTIMPL;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsyncint CollectorHAL::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return E_NOTIMPL;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync}
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncint CollectorHAL::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return E_NOTIMPL;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncvoid BaseMetric::collectorBeat(uint64_t nowAt)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (isEnabled())
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (nowAt - mLastSampleTaken >= mPeriod * 1000)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mLastSampleTaken = nowAt;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync Log4(("{%p} " LOG_FN_FMT ": Collecting data for obj(%p)...\n", this, __PRETTY_FUNCTION__, (void *)mObject));
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync collect();
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync }
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync }
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync}
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync/*bool BaseMetric::associatedWith(ComPtr<IUnknown> object)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync LogFlowThisFunc (("mObject(%p) == object(%p) is %s.\n", mObject, object, mObject == object ? "true" : "false"));
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return mObject == object;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}*/
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncvoid HostCpuLoad::init(ULONG period, ULONG length)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mPeriod = period;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mLength = length;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUser->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mKernel->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mIdle->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncvoid HostCpuLoad::collect()
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync ULONG user, kernel, idle;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync int rc = mHAL->getHostCpuLoad(&user, &kernel, &idle);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (RT_SUCCESS(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUser->put(user);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mKernel->put(kernel);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mIdle->put(idle);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncvoid HostCpuLoadRaw::collect()
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync uint64_t user, kernel, idle;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync uint64_t userDiff, kernelDiff, idleDiff, totalDiff;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync int rc = mHAL->getRawHostCpuLoad(&user, &kernel, &idle);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (RT_SUCCESS(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync userDiff = user - mUserPrev;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync kernelDiff = kernel - mKernelPrev;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync idleDiff = idle - mIdlePrev;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync totalDiff = userDiff + kernelDiff + idleDiff;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (totalDiff == 0)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync /* This is only possible if none of counters has changed! */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync LogFlowThisFunc (("Impossible! User, kernel and idle raw "
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync "counters has not changed since last sample.\n" ));
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUser->put(0);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mKernel->put(0);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mIdle->put(0);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync else
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * userDiff / totalDiff));
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * kernelDiff / totalDiff));
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * idleDiff / totalDiff));
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUserPrev = user;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mKernelPrev = kernel;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mIdlePrev = idle;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncvoid HostCpuMhz::init(ULONG period, ULONG length)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mPeriod = period;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mLength = length;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mMHz->init(mLength);
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync}
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsyncvoid HostCpuMhz::collect()
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync ULONG mhz;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync int rc = mHAL->getHostCpuMHz(&mhz);
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync if (RT_SUCCESS(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mMHz->put(mhz);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncvoid HostRamUsage::init(ULONG period, ULONG length)
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mPeriod = period;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mLength = length;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mTotal->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUsed->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mAvailable->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsyncvoid HostRamUsage::collect()
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync ULONG total, used, available;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync int rc = mHAL->getHostMemoryUsage(&total, &used, &available);
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync if (RT_SUCCESS(rc))
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync {
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mTotal->put(total);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUsed->put(used);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mAvailable->put(available);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsyncvoid MachineCpuLoad::init(ULONG period, ULONG length)
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mPeriod = period;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync mLength = length;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUser->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mKernel->init(mLength);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncvoid MachineCpuLoad::collect()
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync ULONG user, kernel;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync int rc = mHAL->getProcessCpuLoad(mProcess, &user, &kernel);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (RT_SUCCESS(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync mUser->put(user);
mKernel->put(kernel);
}
}
void MachineCpuLoadRaw::collect()
{
uint64_t processUser, processKernel, hostTotal;
int rc = mHAL->getRawProcessCpuLoad(mProcess, &processUser, &processKernel, &hostTotal);
if (RT_SUCCESS(rc))
{
if (hostTotal == mHostTotalPrev)
{
/* Nearly impossible, but... */
mUser->put(0);
mKernel->put(0);
}
else
{
mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * (processUser - mProcessUserPrev) / (hostTotal - mHostTotalPrev)));
mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * (processKernel - mProcessKernelPrev ) / (hostTotal - mHostTotalPrev)));
}
mHostTotalPrev = hostTotal;
mProcessUserPrev = processUser;
mProcessKernelPrev = processKernel;
}
}
void MachineRamUsage::init(ULONG period, ULONG length)
{
mPeriod = period;
mLength = length;
mUsed->init(mLength);
}
void MachineRamUsage::collect()
{
ULONG used;
int rc = mHAL->getProcessMemoryUsage(mProcess, &used);
if (RT_SUCCESS(rc))
mUsed->put(used);
}
void CircularBuffer::init(ULONG length)
{
if (mData)
RTMemFree(mData);
mLength = length;
mData = (ULONG *)RTMemAllocZ(length * sizeof(ULONG));
mWrapped = false;
mEnd = 0;
}
ULONG CircularBuffer::length()
{
return mWrapped ? mLength : mEnd;
}
void CircularBuffer::put(ULONG value)
{
if (mData)
{
mData[mEnd++] = value;
if (mEnd >= mLength)
{
mEnd = 0;
mWrapped = true;
}
}
}
void CircularBuffer::copyTo(ULONG *data)
{
if (mWrapped)
{
memcpy(data, mData + mEnd, (mLength - mEnd) * sizeof(ULONG));
// Copy the wrapped part
if (mEnd)
memcpy(data + (mLength - mEnd), mData, mEnd * sizeof(ULONG));
}
else
memcpy(data, mData, mEnd * sizeof(ULONG));
}
void SubMetric::query(ULONG *data)
{
copyTo(data);
}
void Metric::query(ULONG **data, ULONG *count)
{
ULONG length;
ULONG *tmpData;
length = mSubMetric->length();
if (length)
{
tmpData = (ULONG*)RTMemAlloc(sizeof(*tmpData)*length);
mSubMetric->query(tmpData);
if (mAggregate)
{
*count = 1;
*data = (ULONG*)RTMemAlloc(sizeof(**data));
**data = mAggregate->compute(tmpData, length);
RTMemFree(tmpData);
}
else
{
*count = length;
*data = tmpData;
}
}
else
{
*count = 0;
*data = 0;
}
}
ULONG AggregateAvg::compute(ULONG *data, ULONG length)
{
uint64_t tmp = 0;
for (ULONG i = 0; i < length; ++i)
tmp += data[i];
return (ULONG)(tmp / length);
}
const char * AggregateAvg::getName()
{
return "avg";
}
ULONG AggregateMin::compute(ULONG *data, ULONG length)
{
ULONG tmp = *data;
for (ULONG i = 0; i < length; ++i)
if (data[i] < tmp)
tmp = data[i];
return tmp;
}
const char * AggregateMin::getName()
{
return "min";
}
ULONG AggregateMax::compute(ULONG *data, ULONG length)
{
ULONG tmp = *data;
for (ULONG i = 0; i < length; ++i)
if (data[i] > tmp)
tmp = data[i];
return tmp;
}
const char * AggregateMax::getName()
{
return "max";
}
Filter::Filter(ComSafeArrayIn(INPTR BSTR, metricNames),
ComSafeArrayIn(IUnknown *, objects))
{
com::SafeArray <INPTR BSTR> nameArray(ComSafeArrayInArg(metricNames));
if (ComSafeArrayInIsNull(objects))
{
if (nameArray.size())
{
for (size_t i = 0; i < nameArray.size(); ++i)
processMetricList(std::string(com::Utf8Str(nameArray[i])), ComPtr<IUnknown>());
}
else
processMetricList(std::string("*"), ComPtr<IUnknown>());
}
else
{
com::SafeIfaceArray <IUnknown> objectArray(ComSafeArrayInArg(objects));
for (size_t i = 0; i < objectArray.size(); ++i)
switch (nameArray.size())
{
case 0:
processMetricList(std::string("*"), objectArray[i]);
break;
case 1:
processMetricList(std::string(com::Utf8Str(nameArray[0])), objectArray[i]);
break;
default:
processMetricList(std::string(com::Utf8Str(nameArray[i])), objectArray[i]);
break;
}
}
}
void Filter::processMetricList(const std::string &name, const ComPtr<IUnknown> object)
{
std::string::size_type startPos = 0;
for (std::string::size_type pos = name.find(",");
pos != std::string::npos;
pos = name.find(",", startPos))
{
mElements.push_back(std::make_pair(object, name.substr(startPos, pos - startPos)));
startPos = pos + 1;
}
mElements.push_back(std::make_pair(object, name.substr(startPos)));
}
bool Filter::match(const ComPtr<IUnknown> object, const std::string &name) const
{
ElementList::const_iterator it;
LogAleksey(("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str()));
for (it = mElements.begin(); it != mElements.end(); it++)
{
LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str()));
if ((*it).first.isNull() || (*it).first == object)
{
// Objects match, compare names
if ((*it).second == "*" || (*it).second == name)
{
LogFlowThisFunc(("...found!\n"));
return true;
}
}
}
LogAleksey(("...no matches!\n"));
return false;
}