VirtualBox

Changeset 10753 in vbox


Ignore:
Timestamp:
Jul 18, 2008 7:22:21 PM (16 years ago)
Author:
vboxsync
Message:

Stubs for all platforms. Implementation of host CPU load and RAM usage counters for Windows. Locking. Fixes.

Location:
trunk/src/VBox/Main
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/HostImpl.cpp

    r10713 r10753  
    27112711    aCollector->registerBaseMetric (cpuLoad);
    27122712    pm::BaseMetric *ramUsage =
    2713         metricFactory->createHostCpuLoad (objptr, ramUsageTotal, ramUsageUsed,
    2714                                           ramUsageFree);
     2713        metricFactory->createHostRamUsage (objptr, ramUsageTotal, ramUsageUsed,
     2714                                           ramUsageFree);
    27152715    aCollector->registerBaseMetric (ramUsage);
    27162716
  • trunk/src/VBox/Main/Makefile.kmk

    r10744 r10753  
    268268        PerformanceImpl.cpp \
    269269        Performance.cpp
     270VBoxSVC_SOURCES.darwin  +=  darwin/PerformanceDarwin.cpp
     271VBoxSVC_SOURCES.linux   +=   linux/PerformanceLinux.cpp
     272VBoxSVC_SOURCES.os2     +=     os2/PerformanceOs2.cpp
     273VBoxSVC_SOURCES.solaris += solaris/PerformanceSolaris.cpp
     274VBoxSVC_SOURCES.win     +=     win/PerformanceWin.cpp
     275VBoxSVC_LDFLAGS.win     += PDH.LIB
    270276endif
    271277
  • trunk/src/VBox/Main/Performance.cpp

    r10725 r10753  
    6161}
    6262
    63 // Linux factory
    64 
    65 MetricFactoryLinux::MetricFactoryLinux()
    66 {
    67     mHAL = new CollectorLinux();
    68     Assert(mHAL);
    69 }
    70 
    71 BaseMetric *MetricFactoryLinux::createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
    72 {
    73     Assert(mHAL);
    74     return new HostCpuLoadRaw(mHAL, object, user, kernel, idle);
    75 }
    76 
    77 BaseMetric *MetricFactoryLinux::createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
    78 {
    79     Assert(mHAL);
    80     return new MachineCpuLoadRaw(mHAL, object, process, user, kernel);
    81 }
    82 
    83 
    8463// Stubs for non-pure virtual methods
    8564
     
    10079
    10180int CollectorHAL::getRawProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel)
    102 {
    103     return E_NOTIMPL;
    104 }
    105 
    106 // Collector HAL for Linux
    107 #include <stdio.h>
    108 
    109 int CollectorLinux::getRawHostCpuLoad(unsigned long *user, unsigned long *kernel, unsigned long *idle)
    110 {
    111 #ifdef RT_OS_LINUX
    112     int rc = VINF_SUCCESS;
    113     unsigned long nice;
    114     FILE *f = fopen("/proc/stat", "r");
    115 
    116     if (f)
    117     {
    118         if (fscanf(f, "cpu %lu %lu %lu %lu", user, &nice, kernel, idle) == 4)
    119             *user += nice;
    120         else
    121             rc = VERR_FILE_IO_ERROR;
    122         fclose(f);
    123     }
    124     else
    125         rc = VERR_ACCESS_DENIED;
    126 
    127     return rc;
    128 #else
    129     return E_NOTIMPL;
    130 #endif
    131 }
    132 
    133 int CollectorLinux::getRawProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel)
    134 {
    135 #ifdef RT_OS_LINUX
    136     int rc = VINF_SUCCESS;
    137     char *pszName;
    138     pid_t pid2;
    139     char c;
    140     int iTmp;
    141     unsigned uTmp;
    142     unsigned long ulTmp;
    143     char buf[80]; /* @todo: this should be tied to max allowed proc name. */
    144 
    145     RTStrAPrintf(&pszName, "/proc/%d/stat", process);
    146     //printf("Opening %s...\n", pszName);
    147     FILE *f = fopen(pszName, "r");
    148     RTMemFree(pszName);
    149 
    150     if (f)
    151     {
    152         if (fscanf(f, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu",
    153                    &pid2, buf, &c, &iTmp, &iTmp, &iTmp, &iTmp, &iTmp, &uTmp,
    154                    &ulTmp, &ulTmp, &ulTmp, &ulTmp, user, kernel) == 15)
    155         {
    156             Assert((pid_t)process == pid2);
    157         }
    158         else
    159             rc = VERR_FILE_IO_ERROR;
    160         fclose(f);
    161     }
    162     else
    163         rc = VERR_ACCESS_DENIED;
    164 
    165     return rc;
    166 #else
    167     return E_NOTIMPL;
    168 #endif
    169 }
    170 
    171 int CollectorLinux::getHostCpuMHz(unsigned long *mhz)
    172 {
    173     return E_NOTIMPL;
    174 }
    175 
    176 int CollectorLinux::getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available)
    177 {
    178 #ifdef RT_OS_LINUX
    179     int rc = VINF_SUCCESS;
    180     unsigned long buffers, cached;
    181     FILE *f = fopen("/proc/meminfo", "r");
    182 
    183     if (f)
    184     {
    185         int processed = fscanf(f, "MemTotal: %lu kB", total);
    186         processed    += fscanf(f, "MemFree: %lu kB", available);
    187         processed    += fscanf(f, "Buffers: %lu kB", &buffers);
    188         processed    += fscanf(f, "Cached: %lu kB", &cached);
    189         if (processed == 4)
    190             *available += buffers + cached;
    191         else
    192             rc = VERR_FILE_IO_ERROR;
    193         fclose(f);
    194     }
    195     else
    196         rc = VERR_ACCESS_DENIED;
    197 
    198     return rc;
    199 #else
    200     return E_NOTIMPL;
    201 #endif
    202 }
    203 int CollectorLinux::getProcessMemoryUsage(RTPROCESS process, unsigned long *used)
    20481{
    20582    return E_NOTIMPL;
     
    230107{
    231108    unsigned long user, kernel, idle;
    232     mHAL->getHostCpuLoad(&user, &kernel, &idle);
    233     mUser->put(user);
    234     mKernel->put(kernel);
    235     mIdle->put(idle);
     109    int rc = mHAL->getHostCpuLoad(&user, &kernel, &idle);
     110    if (RT_SUCCESS(rc))
     111    {
     112        mUser->put(user);
     113        mKernel->put(kernel);
     114        mIdle->put(idle);
     115    }
    236116}
    237117
     
    242122
    243123    int rc = mHAL->getRawHostCpuLoad(&user, &kernel, &idle);
    244     AssertRC(rc);
    245124    if (RT_SUCCESS(rc))
    246125    {
     
    271150    unsigned long mhz;
    272151    int rc = mHAL->getHostCpuMHz(&mhz);
    273     AssertRC(rc);
    274152    if (RT_SUCCESS(rc))
    275153        mMHz->put(mhz);
     
    289167    unsigned long total, used, available;
    290168    int rc = mHAL->getHostMemoryUsage(&total, &used, &available);
    291     AssertRC(rc);
    292169    if (RT_SUCCESS(rc))
    293170    {
     
    312189    unsigned long user, kernel;
    313190    int rc = mHAL->getProcessCpuLoad(mProcess, &user, &kernel);
    314     AssertRC(rc);
    315191    if (RT_SUCCESS(rc))
    316192    {
     
    326202
    327203    int rc = mHAL->getRawHostCpuLoad(&hostUser, &hostKernel, &hostIdle);
    328     AssertRC(rc);
    329204    if (RT_SUCCESS(rc))
    330205    {
     
    356231    unsigned long used;
    357232    int rc = mHAL->getProcessMemoryUsage(mProcess, &used);
    358     AssertRC(rc);
    359233    if (RT_SUCCESS(rc))
    360234        mUsed->put(used);
     
    442316    for (unsigned long i = 0; i < length; ++i)
    443317        tmp += data[i];
    444     return tmp / length;
     318    return (unsigned long)(tmp / length);
    445319}
    446320
  • trunk/src/VBox/Main/PerformanceImpl.cpp

    r10725 r10753  
    102102
    103103    /* @todo Obviously other platforms must be added as well. */
     104#ifdef RT_OS_SOLARIS
     105    m.mFactory = new pm::MetricFactorySolaris();
     106#endif
     107#ifdef RT_OS_LINUX
    104108    m.mFactory = new pm::MetricFactoryLinux();
     109#endif
     110#ifdef RT_OS_WINDOWS
     111    m.mFactory = new pm::MetricFactoryWin();
     112#endif
     113#ifdef RT_OS_OS2
     114    m.mFactory = new pm::MetricFactoryOS2();
     115#endif
     116#ifdef RT_OS_DARWIN
     117    m.mFactory = new pm::MetricFactoryDarwin();
     118#endif
    105119
    106120    /* Let the sampler know it gets a valid collector.  */
     
    196210    pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
    197211
     212    AutoReadLock alock (this);
     213
    198214    MetricList filteredMetrics;
    199215    MetricList::iterator it;
     
    204220    com::SafeIfaceArray<IPerformanceMetric> retMetrics(filteredMetrics.size());
    205221    int i = 0;
    206     for (it = m.mMetrics.begin(); it != m.mMetrics.end(); ++it)
     222    for (it = filteredMetrics.begin(); it != filteredMetrics.end(); ++it)
    207223    {
    208224        ComObjPtr<PerformanceMetric> metric;
     
    211227            rc = metric->init (*it);
    212228        ComAssertComRCThrowRC (rc);
     229        LogFlow(("PerformanceCollector::GetMetrics() store a metric at retMetrics[%d]...\n", i));
    213230        metric.queryInterfaceTo(&retMetrics[i++]);
    214231    }
     
    225242
    226243    pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
     244
     245    AutoWriteLock alock (this);
    227246
    228247    BaseMetricList::iterator it;
     
    245264    pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
    246265
     266    AutoReadLock alock (this); /* Need a read lock to access mBaseMetrics */
     267
    247268    BaseMetricList::iterator it;
    248269    for (it = m.mBaseMetrics.begin(); it != m.mBaseMetrics.end(); ++it)
     
    260281
    261282    pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
     283
     284    AutoReadLock alock (this);
    262285
    263286    BaseMetricList::iterator it;
     
    280303    CheckComRCReturnRC (autoCaller.rc());
    281304
    282     /// @todo r=dmik don't we need to lock this for reading?
     305    AutoReadLock alock (this);
    283306
    284307    int i;
     
    328351void PerformanceCollector::registerBaseMetric (pm::BaseMetric *baseMetric)
    329352{
     353    AutoWriteLock alock (this);
    330354    m.mBaseMetrics.push_back (baseMetric);
    331355}
     
    333357void PerformanceCollector::registerMetric (pm::Metric *metric)
    334358{
     359    AutoWriteLock alock (this);
    335360    m.mMetrics.push_back (metric);
    336361}
     
    338363void PerformanceCollector::unregisterBaseMetricsFor (const ComPtr <IUnknown> &aObject)
    339364{
     365    AutoWriteLock alock (this);
    340366    std::remove_if (m.mBaseMetrics.begin(), m.mBaseMetrics.end(),
    341367                    std::bind2nd (std::mem_fun (&pm::BaseMetric::associatedWith),
     
    345371void PerformanceCollector::unregisterMetricsFor (const ComPtr <IUnknown> &aObject)
    346372{
     373    AutoWriteLock alock (this);
    347374    std::remove_if (m.mMetrics.begin(), m.mMetrics.end(),
    348375                    std::bind2nd (std::mem_fun (&pm::Metric::associatedWith),
     
    368395void PerformanceCollector::samplerCallback()
    369396{
     397    AutoWriteLock alock (this);
     398
    370399    uint64_t timestamp = RTTimeMilliTS();
    371400    std::for_each(m.mBaseMetrics.begin(), m.mBaseMetrics.end(),
     
    380409////////////////////////////////////////////////////////////////////////////////
    381410
    382 PerformanceMetric::PerformanceMetric()
    383 {
    384     mMetric = 0;
     411PerformanceMetric::PerformanceMetric() : mMetric(0)
     412{
    385413}
    386414
  • trunk/src/VBox/Main/include/Performance.h

    r10726 r10753  
    2525#include <iprt/types.h>
    2626#include <VBox/com/defs.h>
     27#include <VBox/com/ptr.h>
    2728#include <list>
    2829#include <string>
    2930
    3031namespace pm {
    31     const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000000);
     32    /* CPU load is measured in 1/1000 of per cent. */
     33    const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000);
    3234
    3335    /* Sub Metrics **********************************************************/
     
    6870        virtual int getProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel);
    6971        virtual int getProcessMemoryUsage(RTPROCESS process, unsigned long *used) = 0;
    70 
    71         virtual int getRawHostCpuLoad(unsigned long *user, unsigned long *kernel, unsigned long *idle);
    72         virtual int getRawProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel);
    73     };
    74 
    75     class CollectorLinux : public CollectorHAL
    76     {
    77     public:
    78         virtual int getHostCpuMHz(unsigned long *mhz);
    79         virtual int getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available);
    80         virtual int getProcessMemoryUsage(RTPROCESS process, unsigned long *used);
    8172
    8273        virtual int getRawHostCpuLoad(unsigned long *user, unsigned long *kernel, unsigned long *idle);
     
    309300    };
    310301
    311     // @todo Move implementation to linux/PerformanceLinux.cpp
     302    class MetricFactorySolaris : public MetricFactory
     303    {
     304    public:
     305        MetricFactorySolaris();
     306        virtual BaseMetric   *createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle);
     307        virtual BaseMetric   *createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel);
     308    };
     309
    312310    class MetricFactoryLinux : public MetricFactory
    313311    {
     
    318316    };
    319317
     318    class MetricFactoryWin : public MetricFactory
     319    {
     320    public:
     321        MetricFactoryWin();
     322        // Nothing else to do here (yet)
     323    };
     324
     325    class MetricFactoryOS2 : public MetricFactory
     326    {
     327    public:
     328        MetricFactoryOS2();
     329        // Nothing else to do here (yet)
     330    };
     331
     332    class MetricFactoryDarwin : public MetricFactory
     333    {
     334    public:
     335        MetricFactoryDarwin();
     336        // Nothing else to do here (yet)
     337    };
     338
    320339    class Filter
    321340    {
  • trunk/src/VBox/Main/testcase/tstAPI.cpp

    r10727 r10753  
    10561056        for (unsigned j = 0; j < retLengths[i]; j++)
    10571057        {
    1058             printf(", %d %s", retData[retIndices[i] + j], metricUnit.raw());
     1058            printf(", %d %ls", retData[retIndices[i] + j] / (strcmp((const char *)metricUnit.raw(), "%")?1:1000), metricUnit.raw());
    10591059        }
    10601060        printf("\n");
Note: See TracChangeset for help on using the changeset viewer.

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