Performance.cpp revision e64031e20c39650a7bc902a3e1aba613b9415dee
/* $Id$ */
/** @file
*
* VBox Performance Classes implementation.
*/
/*
* Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*
* @todo list:
*
* 1) Detection of erroneous metric names
*/
#ifndef VBOX_COLLECTOR_TEST_CASE
#include "VirtualBoxImpl.h"
#include "MachineImpl.h"
#endif
#include "Performance.h"
#include <algorithm>
#include "Logging.h"
using namespace pm;
// Stubs for non-pure virtual methods
{
return E_NOTIMPL;
}
int CollectorHAL::getProcessCpuLoad(RTPROCESS /* process */, ULONG * /* user */, ULONG * /* kernel */)
{
return E_NOTIMPL;
}
int CollectorHAL::getRawHostCpuLoad(uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* idle */)
{
return E_NOTIMPL;
}
int CollectorHAL::getRawProcessCpuLoad(RTPROCESS /* process */, uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* total */)
{
return E_NOTIMPL;
}
int CollectorHAL::getHostMemoryUsage(ULONG * /* total */, ULONG * /* used */, ULONG * /* available */)
{
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
int CollectorHAL::enable()
{
return E_NOTIMPL;
}
int CollectorHAL::disable()
{
return E_NOTIMPL;
}
/* Generic implementations */
{
unsigned cCpus = 0;
uint64_t u64TotalMHz = 0;
{
this, __PRETTY_FUNCTION__, (int)iCpu));
{
this, __PRETTY_FUNCTION__, (int)iCpu));
if (uMHz != 0)
{
u64TotalMHz += uMHz;
cCpus++;
}
}
}
return VINF_SUCCESS;
}
#ifndef VBOX_COLLECTOR_TEST_CASE
{
}
int CollectorGuestHAL::enable()
{
{
return ret;
/* get the associated console; this is a remote call (!) */
return ret;
}
return ret;
}
int CollectorGuestHAL::disable()
{
if (ASMAtomicDecU32(&cEnabled) == 0)
{
}
return S_OK;
}
{
if ( mGuest
{
if (mHostHAL)
}
return S_OK;
}
#endif /* !VBOX_COLLECTOR_TEST_CASE */
{
if (isEnabled())
{
{
return true;
}
}
return false;
}
/*bool BaseMetric::associatedWith(ComPtr<IUnknown> object)
{
LogFlowThisFunc(("mObject(%p) == object(%p) is %s.\n", mObject, object, mObject == object ? "true" : "false"));
return mObject == object;
}*/
{
}
void HostCpuLoad::collect()
{
if (RT_SUCCESS(rc))
{
}
}
{
}
void HostCpuLoadRaw::collect()
{
if (RT_SUCCESS(rc))
{
if (totalDiff == 0)
{
/* This is only possible if none of counters has changed! */
LogFlowThisFunc(("Impossible! User, kernel and idle raw "
"counters has not changed since last sample.\n" ));
}
else
{
}
}
}
{
}
void HostCpuMhz::collect()
{
if (RT_SUCCESS(rc))
}
{
}
{
}
void HostRamUsage::collect()
{
if (RT_SUCCESS(rc))
{
}
}
{
}
void MachineCpuLoad::collect()
{
if (RT_SUCCESS(rc))
{
}
}
{
}
void MachineCpuLoadRaw::collect()
{
if (RT_SUCCESS(rc))
{
if (hostTotal == mHostTotalPrev)
{
/* Nearly impossible, but... */
}
else
{
mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * (processUser - mProcessUserPrev) / (hostTotal - mHostTotalPrev)));
mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * (processKernel - mProcessKernelPrev ) / (hostTotal - mHostTotalPrev)));
}
}
}
{
}
{
}
void MachineRamUsage::collect()
{
if (RT_SUCCESS(rc))
}
{
}
{
}
void GuestCpuLoad::collect()
{
}
{
}
{
}
void GuestRamUsage::collect()
{
}
{
if (mData)
if (mLength)
else
mWrapped = false;
mEnd = 0;
mSequenceNumber = 0;
}
{
}
{
if (mData)
{
{
mEnd = 0;
mWrapped = true;
}
}
}
{
if (mWrapped)
{
// Copy the wrapped part
if (mEnd)
}
else
}
{
}
{
if (length)
{
if (mAggregate)
{
*count = 1;
}
else
{
}
}
else
{
*count = 0;
*data = 0;
}
}
{
}
const char * AggregateAvg::getName()
{
return "avg";
}
{
return tmp;
}
const char * AggregateMin::getName()
{
return "min";
}
{
return tmp;
}
const char * AggregateMax::getName()
{
return "max";
}
{
/*
* a way to pass null arrays via webservice, I haven't found one. So I
* guess the users will be forced to use empty arrays instead. Constructing
* an empty SafeArray is a bit awkward, so what we do in this method is
* actually convert null arrays to empty arrays and pass them down to
* init() method. If someone knows how to do it better, please be my guest,
* fix it.
*/
{
if (ComSafeArrayInIsNull(objects))
{
objectArray.reset(0);
}
else
{
}
}
else
{
if (ComSafeArrayInIsNull(objects))
{
objectArray.reset(0);
}
else
{
}
}
}
{
if (!objectArray.size())
{
{
}
else
}
else
{
{
case 0:
break;
case 1:
break;
default:
break;
}
}
}
{
{
mElements.push_back(std::make_pair(object, iprt::MiniString(name.substr(startPos, pos - startPos).c_str())));
}
}
/**
* modified to handle the special case of trailing colon in the pattern.
*
* @returns True if matches, false if not.
* @param pszPat Pattern.
* @param pszName Name to match against the pattern.
* @param fSeenColon Seen colon (':').
*/
bool fSeenColon)
{
/* ASSUMES ASCII */
for (;;)
{
switch (chPat)
{
default:
return false;
break;
case '*':
{
/* nothing */;
/* Handle a special case, the mask terminating with a colon. */
if (chPat == ':')
{
fSeenColon = true;
}
for (;;)
{
&& ( !chPat
return true;
if (!ch)
return false;
}
/* won't ever get here */
break;
}
case '?':
if (!*pszName)
return false;
break;
/* Handle a special case, the mask terminating with a colon. */
case ':':
return !*pszName;
if (*pszName != ':')
return false;
fSeenColon = true;
break;
case '\0':
return !*pszName;
}
pszName++;
pszPat++;
}
return true;
}
{
{
LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str()));
{
// Objects match, compare names
{
LogFlowThisFunc(("...found!\n"));
return true;
}
}
}
LogAleksey(("...no matches!\n"));
return false;
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */