VirtualBox

Changeset 10528 in vbox


Ignore:
Timestamp:
Jul 11, 2008 2:27:01 PM (16 years ago)
Author:
vboxsync
Message:

Performance API, version 0, webservice broken.

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/system.h

    r9935 r10528  
    3434#include <iprt/types.h>
    3535
    36 #define IPRT_USAGE_MULTIPLIER   UINT64_C(1000000000)
    37 
    38 /**
    39  * This structure holds both computed and raw values of overall CPU load counters.
    40  *
    41  * @todo r=bird: What does these values mean?
    42  *
    43  *               Also, I no longer use 'u32', 'u16', 'u8', 'u64', etc unless this information
    44  *               is really important for the user. So, unless there is a better prefix just
    45  *               stick to 'u' here.
    46  *
    47  *               The name of the struct should include the prefix or a shortened
    48  *               version of it: RTSYSCPUUSAGESTATS
    49  *
    50  *               Also, I'd sugest calling it RTSYSCPULOADSTATS, replacing 'usage' with 'load',
    51  *               no particular reason, other than that it is easier to read in the (silly)
    52  *               condensed form we use for typedefs here.
    53  *
    54  *               Finally, I'm wondering how portable this is. I'd like to see what APIs are
    55  *               available on the important systems (Windows, Solaris, Linux) and compare
    56  *               the kind of info they return. This should be done in the defect *before*
    57  *               any of the above, please.
    58  */
    59 typedef struct RTSYSCPUUSAGESTATS
    60 {
    61     uint32_t u32User;
    62     uint32_t u32System;
    63     uint32_t u32Idle;
    64     /* Internal raw counter values. */
    65     uint32_t u32RawUser;
    66     uint32_t u32RawNice;
    67     uint32_t u32RawSystem;
    68     uint32_t u32RawIdle;
    69 } RTCPUUSAGESTATS;
    70 typedef RTCPUUSAGESTATS *PRTCPUUSAGESTATS;
    71 
    72 /* This structure holds both computed and raw values of per-VM CPU load counters. */
    73 typedef struct
    74 {
    75     uint32_t u32User;
    76     uint32_t u32System;
    77     /* Internal raw counter values. */
    78     uint64_t u64RawTotal;
    79     uint32_t u32RawProcUser;
    80     uint32_t u32RawProcSystem;
    81 } RTPROCCPUUSAGESTATS;
    82 typedef RTPROCCPUUSAGESTATS *PRTPROCCPUUSAGESTATS;
    83 
    8436
    8537__BEGIN_DECLS
     
    10860RTDECL(uint64_t) RTSystemProcessorGetActiveMask(void);
    10961
    110 /**
    111  * Gets the current figures of overall system processor usage.
    112  *
    113  * @remarks To get meaningful stats this function has to be
    114  *          called twice with a bit of delay between calls. This
    115  *          is due to the fact that at least two samples of
    116  *          system usage stats are needed to calculate the load.
    117  *
    118  * @returns IPRT status code.
    119  * @param   pStats  Pointer to the structure that contains the
    120  *                  results. Note that this structure is
    121  *                  modified with each call to this function and
    122  *                  is used to provide both in and out values.
    123  * @todo r=bird: Change to RTSystemGetCpuLoadStats.
    124  */
    125 RTDECL(int) RTSystemProcessorGetUsageStats(PRTCPUUSAGESTATS pStats);
    126 
    127 /**
    128  * Gets the current processor usage for a partucilar process.
    129  *
    130  * @remarks To get meaningful stats this function has to be
    131  *          called twice with a bit of delay between calls. This
    132  *          is due to the fact that at least two samples of
    133  *          system usage stats are needed to calculate the load.
    134  *
    135  * @returns IPRT status code.
    136  * @param   pid     VM process id.
    137  * @param   pStats  Pointer to the structure that contains the
    138  *                  results. Note that this structure is
    139  *                  modified with each call to this function and
    140  *                  is used to provide both in and out values.
    141  *
    142  * @todo    Perharps this function should be moved somewhere
    143  *          else.
    144  * @todo    r=bird: Yes is should, iprt/proc.h. RTProcGetCpuLoadStats.
    145  */
    146 RTDECL(int) RTProcessGetProcessorUsageStats(RTPROCESS pid, PRTPROCCPUUSAGESTATS pStats);
    147 
    14862/** @} */
    14963
  • trunk/src/VBox/Main/HostImpl.cpp

    r10444 r10528  
    171171
    172172#ifdef VBOX_WITH_RESOURCE_USAGE_API
    173     /* Start resource usage sampler */
    174     {
    175         int vrc = RTTimerCreate (&mUsageSampler, VBOX_USAGE_SAMPLER_INTERVAL,
    176                                  UsageSamplerCallback, this);
    177         AssertMsgRC (vrc, ("Failed to create resource usage sampling "
    178                            "timer (%Rra)\n", vrc));
    179         if (RT_FAILURE (vrc))
    180             return E_FAIL;
    181     }
     173    registerMetrics(parent->getCollector());
    182174#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    183175
     
    195187
    196188    AssertReturn (isReady(), (void) 0);
     189
     190#ifdef VBOX_WITH_RESOURCE_USAGE_API
     191    unregisterMetrics(mParent->getCollector());
     192#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    197193
    198194#ifdef VBOX_WITH_USB
     
    211207    mUSBDeviceFilters.clear();
    212208#endif
    213 
    214 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    215     /* Destroy resource usage sampler */
    216     {
    217         int vrc = RTTimerDestroy (mUsageSampler);
    218         AssertMsgRC (vrc, ("Failed to destroy resource usage "
    219                            "sampling timer (%Rra)\n", vrc));
    220     }
    221 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    222209
    223210    setReady (FALSE);
     
    11101097    return E_NOTIMPL;
    11111098#endif
    1112 }
    1113 
    1114 STDMETHODIMP Host::GetProcessorUsage (ULONG *aUser, ULONG *aSystem, ULONG *aIdle)
    1115 {
    1116 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    1117     if (aUser == NULL || aSystem == NULL || aIdle == NULL)
    1118         return E_POINTER;
    1119 
    1120     *aUser   = mCpuStats.u32User;
    1121     *aSystem = mCpuStats.u32System;
    1122     *aIdle   = mCpuStats.u32Idle;
    1123 
    1124     return S_OK;
    1125 #else /* !VBOX_WITH_RESOURCE_USAGE_API */
    1126     return E_NOTIMPL;
    1127 #endif /* !VBOX_WITH_RESOURCE_USAGE_API */
    11281099}
    11291100
     
    27222693
    27232694#ifdef VBOX_WITH_RESOURCE_USAGE_API
    2724 
    2725 /* static */
    2726 void Host::UsageSamplerCallback (PRTTIMER pTimer, void *pvUser, uint64_t iTick)
    2727 {
    2728     AssertReturnVoid (pvUser != NULL);
    2729     static_cast <Host *> (pvUser)->usageSamplerCallback();
    2730 }
    2731 
    2732 void Host::usageSamplerCallback()
    2733 {
    2734     int vrc = RTSystemProcessorGetUsageStats (&mCpuStats);
    2735     AssertMsgRC (vrc, ("Failed to get CPU stats (%Rra)\n", vrc));
    2736 
    2737 //  LogFlowThisFunc (("user=%u%% system=%u%% &mCpuStats=%p\n",
    2738 //                    mCpuStats.u32User / 10000000,
    2739 //                    mCpuStats.u32System / 10000000, &mCpuStats);
    2740 //  LogFlowThisFunc (("user=%.2f system=%.2f idle=%.2f\n", mCpuStats.u32User/10000000.,
    2741 //                    mCpuStats.u32System/10000000., mCpuStats.u32Idle/10000000.);
    2742 }
    2743 
     2695void Host::registerMetrics(PerformanceCollector *collector)
     2696{
     2697    pm::MetricFactory *metricFactory = collector->getMetricFactory();
     2698    // Create sub metrics
     2699    pm::SubMetric *cpuLoadUser = new pm::SubMetric("CPU/Load/User");
     2700    pm::SubMetric *cpuLoadKernel = new pm::SubMetric("CPU/Load/Kernel");
     2701    pm::SubMetric *cpuLoadIdle = new pm::SubMetric("CPU/Load/Idle");
     2702    // Create and register base metrics
     2703    IUnknown *objptr;
     2704    ComObjPtr<Host> tmp = this;
     2705    tmp.queryInterfaceTo(&objptr);
     2706    pm::BaseMetric *cpuLoad =
     2707        metricFactory->createHostCpuLoad(objptr, cpuLoadUser, cpuLoadKernel, cpuLoadIdle);
     2708    collector->registerBaseMetric(cpuLoad);
     2709    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, 0));
     2710    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, new pm::AggregateAvg()));
     2711    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, new pm::AggregateMin()));
     2712    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, new pm::AggregateMax()));
     2713    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, 0));
     2714    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, new pm::AggregateAvg()));
     2715    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, new pm::AggregateMin()));
     2716    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, new pm::AggregateMax()));
     2717    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadIdle, 0));
     2718    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadIdle, new pm::AggregateAvg()));
     2719    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadIdle, new pm::AggregateMin()));
     2720    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadIdle, new pm::AggregateMax()));
     2721};
     2722
     2723void Host::unregisterMetrics(PerformanceCollector *collector)
     2724{
     2725    collector->unregisterMetricsFor(this);
     2726    collector->unregisterBaseMetricsFor(this);
     2727};
    27442728#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    27452729
  • trunk/src/VBox/Main/MachineImpl.cpp

    r10420 r10528  
    147147    mSession.mPid = NIL_RTPROCESS;
    148148    mSession.mState = SessionState_Closed;
    149 
    150 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    151     mUsageSampler = NULL;
    152 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    153149}
    154150
     
    501497    }
    502498
    503 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    504     /* Start resource usage sampler */
    505     {
    506         vrc = RTTimerCreate (&mData->mUsageSampler, VBOX_USAGE_SAMPLER_INTERVAL,
    507                              Machine::UsageSamplerCallback, this);
    508         AssertMsgRC (vrc, ("Failed to create resource usage "
    509                             "sampling timer(%Rra)\n", vrc));
    510         if (RT_FAILURE (vrc))
    511             rc = E_FAIL;
    512     }
    513 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    514 
    515499    LogFlowThisFunc (("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool "
    516500                      "rc=%08X\n",
     
    636620     */
    637621    AutoMultiWriteLock2 alock (mParent, this);
    638 
    639 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    640     /* Destroy resource usage sampler */
    641     {
    642         int vrc = RTTimerDestroy (mData->mUsageSampler);
    643         AssertMsgRC (vrc, ("Failed to destroy resource usage "
    644                            "sampling timer (%Rra)\n", vrc));
    645     }
    646 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    647622
    648623    if (!mData->mSession.mMachine.isNull())
     
    28142789}
    28152790
    2816 STDMETHODIMP Machine::GetProcessorUsage (ULONG *aUser, ULONG *aSystem)
    2817 {
    2818 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    2819     if (aUser == NULL || aSystem == NULL)
    2820         return E_POINTER;
    2821 
    2822 //  LogFlowThisFunc (("user=%u%% system=%u%% &mData->mCpuStats=%p\n",
    2823 //                    mData->mCpuStats.u32User / 10000000,
    2824 //                    mData->mCpuStats.u32System / 10000000, &mData->mCpuStats));
    2825 
    2826     *aUser   = mData->mCpuStats.u32User;
    2827     *aSystem = mData->mCpuStats.u32System;
    2828     return S_OK;
    2829 #else /* !VBOX_WITH_RESOURCE_USAGE_API */
    2830     return E_NOTIMPL;
    2831 #endif /* !VBOX_WITH_RESOURCE_USAGE_API */
    2832 }
    2833 
    28342791
    28352792// public methods for internal purposes
     
    73207277
    73217278#ifdef VBOX_WITH_RESOURCE_USAGE_API
    7322 
    7323 /* static */
    7324 void Machine::UsageSamplerCallback (PRTTIMER pTimer, void *pvUser, uint64_t iTick)
    7325 {
    7326     AssertReturnVoid (pvUser != NULL);
    7327     static_cast <Machine *> (pvUser)->usageSamplerCallback();
    7328 }
    7329 
    7330 void Machine::usageSamplerCallback()
    7331 {
    7332 //  LogFlowThisFunc (("mData->mSession.mPid = %u &mData->mCpuStats = %p)\n",
    7333 //                    mData->mSession.mPid, &m_CpuStats));
    7334     if (mData->mSession.mPid != NIL_RTPROCESS)
    7335     {
    7336         int vrc = RTProcessGetProcessorUsageStats (mData->mSession.mPid,
    7337                                                    &mData->mCpuStats);
    7338         AssertMsgRC (vrc, ("Failed to get CPU stats (%Rra)\n", vrc));
    7339     }
    7340     else
    7341     {
    7342         mData->mCpuStats.u32User   = 0;
    7343         mData->mCpuStats.u32System = 0;
    7344     }
    7345 //  LogFlowThisFunc (("user=%u%% system=%u%% &mData->mCpuStats=%p\n",
    7346 //                    mData->mCpuStats.u32User / 10000000,
    7347 //                    mData->mCpuStats.u32System / 10000000, &mData->mCpuStats));
    7348 //  LogFlowThisFunc (("user=%.2f system=%.2f\n",
    7349 //                    mData->mCpuStats.u32User/10000000., mData->mCpuStats.u32System/10000000.));
    7350 }
    7351 
     7279void Machine::registerMetrics(PerformanceCollector *collector)
     7280{
     7281    pm::MetricFactory *metricFactory = collector->getMetricFactory();
     7282    // Create sub metrics
     7283    pm::SubMetric *cpuLoadUser = new pm::SubMetric("CPU/Load/User");
     7284    pm::SubMetric *cpuLoadKernel = new pm::SubMetric("CPU/Load/Kernel");
     7285    // Create and register base metrics
     7286    IUnknown *objptr;
     7287
     7288    ComObjPtr<Machine> tmp = this;
     7289    tmp.queryInterfaceTo(&objptr);
     7290    pm::BaseMetric *cpuLoad =
     7291        metricFactory->createMachineCpuLoad(objptr, mData->mSession.mPid, cpuLoadUser, cpuLoadKernel);
     7292    collector->registerBaseMetric(cpuLoad);
     7293
     7294    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, 0));
     7295    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, new pm::AggregateAvg()));
     7296    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, new pm::AggregateMin()));
     7297    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadUser, new pm::AggregateMax()));
     7298    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, 0));
     7299    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, new pm::AggregateAvg()));
     7300    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, new pm::AggregateMin()));
     7301    collector->registerMetric(new pm::Metric(cpuLoad, cpuLoadKernel, new pm::AggregateMax()));
     7302};
     7303
     7304void Machine::unregisterMetrics(PerformanceCollector *collector)
     7305{
     7306    collector->unregisterMetricsFor(this);
     7307    collector->unregisterBaseMetricsFor(this);
     7308};
    73527309#endif /* VBOX_WITH_RESOURCE_USAGE_API */
     7310
    73537311
    73547312/////////////////////////////////////////////////////////////////////////////
     
    1040610364    return S_OK;
    1040710365}
     10366
     10367
  • trunk/src/VBox/Main/Makefile.kmk

    r10268 r10528  
    259259VBoxSVC_SOURCES.solaris += solaris/USBProxyServiceSolaris.cpp
    260260VBoxSVC_SOURCES.win     +=     win/USBProxyServiceWindows.cpp
     261endif
     262
     263ifdef VBOX_WITH_RESOURCE_USAGE_API
     264VBoxSVC_SOURCES  += \
     265        PerformanceImpl.cpp \
     266        Performance.cpp
    261267endif
    262268
  • trunk/src/VBox/Main/VirtualBoxImpl.cpp

    r10400 r10528  
    228228            Key global = tree.rootKey().key ("Global");
    229229
     230#ifdef VBOX_WITH_RESOURCE_USAGE_API
     231            /* create the performance collector object BEFORE host */
     232            unconst (mData.mPerformanceCollector).createObject();
     233            rc = mData.mPerformanceCollector->init ();
     234            ComAssertComRCThrowRC (rc);
     235#endif /* VBOX_WITH_RESOURCE_USAGE_API */
     236
    230237            /* create the host object early, machines will need it */
    231238            unconst (mData.mHost).createObject();
     
    376383    }
    377384
     385#ifdef VBOX_WITH_RESOURCE_USAGE_API
     386    if (mData.mPerformanceCollector)
     387    {
     388        mData.mPerformanceCollector->uninit();
     389        unconst (mData.mPerformanceCollector).setNull();
     390    }
     391#endif /* VBOX_WITH_RESOURCE_USAGE_API */
     392
    378393    /*
    379394     *  Uninit all other children still referenced by clients
     
    571586    return S_OK;
    572587}
     588
     589STDMETHODIMP
     590VirtualBox::COMGETTER(PerformanceCollector) (IPerformanceCollector **aPerformanceCollector)
     591{
     592#ifdef VBOX_WITH_RESOURCE_USAGE_API
     593    if (!aPerformanceCollector)
     594        return E_POINTER;
     595
     596    AutoCaller autoCaller (this);
     597    CheckComRCReturnRC (autoCaller.rc());
     598
     599    mData.mPerformanceCollector.queryInterfaceTo (aPerformanceCollector);
     600
     601    return S_OK;
     602#else /* !VBOX_WITH_RESOURCE_USAGE_API */
     603    return E_NOTIMPL;
     604#endif /* !VBOX_WITH_RESOURCE_USAGE_API */
     605}
     606
    573607
    574608/**
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r10399 r10528  
    885885  <interface
    886886    name="IVirtualBox" extends="$dispatched"
    887     uuid="2d3b9ea7-25f5-4f07-a8e1-7dd7e0dcf667"
     887    uuid="557a07bc-e6ae-4520-a361-4a8493199137"
    888888    wsmap="managed"
    889889  >
     
    10551055          implemented and therefore this collection is always empty.
    10561056        </note>
     1057      </desc>
     1058    </attribute>
     1059    <attribute name="performanceCollector" type="IPerformanceCollector" readonly="yes">
     1060      <desc>
     1061        The only instance of IPerformanceCollector.
    10571062      </desc>
    10581063    </attribute>
     
    35303535    </method>
    35313536
    3532     <method name="getProcessorUsage">
    3533       <desc>
    3534         Returns the current processor usage by this virtual machine measured
    3535         over all cores of all processors in the host system.
    3536 
    3537         The values returned for each parameter are in range from <tt>0</tt> (the
    3538         machine is powered off or does not load the CPUs at all) to
    3539         <tt>1 000 000 000</tt> (all cores of all CPUs are fully in use by this
    3540         machine).
    3541       </desc>
    3542       <param name="user" type="unsigned long" dir="out">
    3543         <desc>
    3544           Pecentage of processor time spent executing in user mode.
    3545         </desc>
    3546       </param>
    3547       <param name="system" type="unsigned long" dir="out">
    3548         <desc>
    3549           Pecentage of processor time spent executing in kernel mode.
    3550         </desc>
    3551       </param>
    3552     </method>
    3553 
    35543537  </interface>
    35553538
     
    50535036    </method>
    50545037
    5055     <method name="getProcessorUsage">
    5056       <desc>
    5057         Returns the processor usage by the whole host system measured over all
    5058         cores of all processors of the host machine.
    5059 
    5060         The values returned for each parameter are in range from <tt>0</tt> (the
    5061         machine is powered off or doesn't load the CPUs at all) to
    5062         <tt>1 000 000 000</tt> (all cores of all CPUs are fully loaded by this
    5063         machine).
    5064 
    5065         <note>
    5066           The maximum value is 1000000000 which means that all cores of all CPUs
    5067           are completely used.
    5068         </note>
    5069       </desc>
    5070       <param name="user" type="unsigned long" dir="out">
    5071         <desc>
    5072           Pecentage of processor time spent executing in user mode.
    5073         </desc>
    5074       </param>
    5075       <param name="system" type="unsigned long" dir="out">
    5076         <desc>
    5077           Pecentage of processor time spent executing in kernel mode.
    5078         </desc>
    5079       </param>
    5080       <param name="idle" type="unsigned long" dir="out">
    5081         <desc>
    5082           Pecentage of processor time spent doing nothing.
    5083         </desc>
    5084       </param>
    5085     </method>
    50865038  </interface>
    50875039
     
    1012210074</if>
    1012310075
     10076  <interface
     10077    name="IPerformanceMetric" extends="$unknown"
     10078    uuid="50831d4c-ed55-4221-836c-87b487d3b44a" wsmap="managed"
     10079  >
     10080    <desc>Holds metrics parameters.</desc>
     10081 
     10082    <attribute name="metricName" type="wstring" readonly="yes">
     10083      <desc>
     10084        Name of the metric.
     10085      </desc>
     10086    </attribute>
     10087
     10088    <attribute name="object" type="$unknown" readonly="yes">
     10089      <desc>
     10090        The object this metric belongs to.
     10091      </desc>
     10092    </attribute>
     10093
     10094    <attribute name="period" type="unsigned long" readonly="yes">
     10095      <desc>
     10096        The time interval between samples, measured in seconds.
     10097      </desc>
     10098    </attribute>
     10099
     10100    <attribute name="count" type="unsigned long" readonly="yes">
     10101      <desc>
     10102        The number of recent samples retained by the collector. Older samples
     10103        are discarded.
     10104      </desc>
     10105    </attribute>
     10106
     10107    <attribute name="unit" type="wstring" readonly="yes">
     10108      <desc>
     10109        The unit of measurement.
     10110      </desc>
     10111    </attribute>
     10112
     10113    <attribute name="minimumValue" type="long" readonly="yes">
     10114      <desc>
     10115        The minimum possible value of this metric.
     10116      </desc>
     10117    </attribute>
     10118
     10119    <attribute name="maximumValue" type="long" readonly="yes">
     10120      <desc>
     10121        The maximum possible value of this metric.
     10122      </desc>
     10123    </attribute>
     10124  </interface>
     10125
     10126  <interface
     10127    name="IPerformanceCollector" extends="$unknown"
     10128    uuid="dcd37e5a-3964-43d1-be30-0f3c7234e347"
     10129    wsmap="managed"
     10130  >
     10131    <desc>
     10132      This object collects and stores performace metrics data. Performance
     10133      metrics are associated with objects like IHost and IMachine. Each object
     10134      has a distict set of performance metrics. It can be obtained with
     10135      <link to="IPerformanceCollector::getMetrics"/>.
     10136    </desc>
     10137
     10138    <attribute name="metricNames" type="wstring" readonly="yes" safearray="yes">
     10139      <desc>
     10140        An array of unique names of metrics regardless of objects they are
     10141        associated with.
     10142      </desc>
     10143    </attribute>
     10144 
     10145    <method name="getMetrics">
     10146      <desc>
     10147        Returns parameters (characteristics?) of specified metrics for a set of
     10148        objects.
     10149        <note>
     10150          Null metrics array means all metrics. Null object array means all
     10151          existing objects.
     10152        </note>
     10153      </desc>
     10154      <param name="metricNames" type="wstring" dir="in" safearray="yes"/>
     10155      <param name="objects" type="$unknown" dir="in" safearray="yes"/>
     10156      <param name="metrics" type="IPerformanceMetric" dir="return" safearray="yes"/>
     10157    </method>
     10158 
     10159    <method name="setupMetrics">
     10160      <desc>
     10161        Sets parameters of specified metrics for a set of objects.
     10162        <note>
     10163          Null metrics array means all metrics. Null object array means all
     10164          existing objects.
     10165        </note>
     10166      </desc>
     10167      <param name="metricNames" type="wstring" dir="in" safearray="yes"/>
     10168      <param name="objects" type="$unknown" dir="in" safearray="yes"/>
     10169      <param name="period" type="unsigned long" dir="in"/>
     10170      <param name="count" type="unsigned long" dir="in"/>
     10171    </method>
     10172
     10173    <method name="enableMetrics">
     10174      <desc>
     10175        Turn on collection of specified metrics.
     10176        <note>
     10177          Null metrics array means all metrics. Null object array means all
     10178          existing objects.
     10179        </note>
     10180      </desc>
     10181      <param name="metricNames" type="wstring" dir="in" safearray="yes"/>
     10182      <param name="objects" type="$unknown" dir="in" safearray="yes"/>
     10183    </method>
     10184
     10185    <method name="disableMetrics">
     10186      <desc>
     10187        Turn off collection of specified metrics.
     10188        <note>
     10189          Null metrics array means all metrics. Null object array means all
     10190          existing objects.
     10191        </note>
     10192      </desc>
     10193      <param name="metricNames" type="wstring" dir="in" safearray="yes"/>
     10194      <param name="objects" type="$unknown" dir="in" safearray="yes"/>
     10195    </method>
     10196
     10197    <method name="queryMetricsData">
     10198      <desc>
     10199        Queries collected metrics data for a set of objects.
     10200        <note>
     10201          Null metrics array means all applicable metrics. Null object array
     10202          means all existing objects. The @a returnData parameter is a
     10203          flattened array of arrays. Each start and length of a sub-array is
     10204          indicated by @a returnDataIndices and @a returnDataLengths. The
     10205          rationale behind this API style is that it doesn't require objects
     10206          to be returned, and thus eliminates all but the unavoidable IPC.
     10207        </note>
     10208      </desc>
     10209      <param name="metricNames" type="wstring" dir="in" safearray="yes"/>
     10210      <param name="objects" type="$unknown" dir="in" safearray="yes"/>
     10211      <param name="returnMetricNames" type="wstring" dir="out" safearray="yes"/>
     10212      <param name="returnObjects" type="$unknown" dir="out" safearray="yes"/>
     10213      <param name="returnDataIndices" type="unsigned long" dir="out" safearray="yes"/>
     10214      <param name="returnDataLengths" type="unsigned long" dir="out" safearray="yes"/>
     10215      <param name="returnData" type="long" dir="return" safearray="yes"/>
     10216    </method>
     10217
     10218  </interface>
     10219
    1012410220  <module name="VBoxSVC" context="LocalServer">
    1012510221    <class name="VirtualBox" uuid="B1A7A4F2-47B9-4A1E-82B2-07CCD5323C3F"
  • trunk/src/VBox/Main/include/HostImpl.h

    r10423 r10528  
    3636# include "win/svchlp.h"
    3737#endif
    38 
    39 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    40 #include "iprt/timer.h"
    41 #include "iprt/system.h"
    42 
    43 /* Each second we obtain new CPU load stats. */
    44 #define VBOX_USAGE_SAMPLER_INTERVAL 1000
    45 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    46 
    4738
    4839class VirtualBox;
     
    110101    STDMETHOD(RemoveUSBDeviceFilter) (ULONG aPosition, IHostUSBDeviceFilter **aFilter);
    111102
    112     STDMETHOD(GetProcessorUsage) (ULONG *aUser, ULONG *aSystem, ULONG *aIdle);
    113 
    114103    // public methods only for internal purposes
    115104
     
    171160
    172161#ifdef VBOX_WITH_RESOURCE_USAGE_API
    173     /** Static timer callback. */
    174     static void UsageSamplerCallback (PRTTIMER pTimer, void *pvUser, uint64_t iTick);
    175     /** Member timer callback. */
    176     void usageSamplerCallback();
     162    void registerMetrics(PerformanceCollector *collector);
     163    void unregisterMetrics(PerformanceCollector *collector);
    177164#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    178165
     
    186173#endif /* VBOX_WITH_USB */
    187174
    188 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    189     /** Pointer to the usage sampling timer. */
    190     PRTTIMER mUsageSampler;
    191     /** Structure to hold processor usage stats. */
    192     RTCPUUSAGESTATS mCpuStats;
    193 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    194175};
    195176
  • trunk/src/VBox/Main/include/MachineImpl.h

    r10000 r10528  
    3939#include "BIOSSettingsImpl.h"
    4040#include "SATAControllerImpl.h"
     41#ifdef VBOX_WITH_RESOURCE_USAGE_API
     42#include "PerformanceImpl.h"
     43#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    4144
    4245// generated header
     
    4851#include <iprt/thread.h>
    4952#include <iprt/time.h>
    50 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    51 #include <iprt/system.h>
    52 #include <iprt/timer.h>
    53 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    5453
    5554#include <list>
     
    169168        ComObjPtr <Snapshot> mCurrentSnapshot;
    170169
    171 #ifdef VBOX_WITH_RESOURCE_USAGE_API
    172         /** Pointer to the usage sampling timer. */
    173         PRTTIMER mUsageSampler;
    174         /** Structure to hold processor usage stats. */
    175         RTPROCCPUUSAGESTATS mCpuStats;
    176 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
    177170    };
    178171
     
    530523    STDMETHOD(SetGuestProperty) (INPTR BSTR aKey, INPTR BSTR aValue);
    531524
    532     STDMETHOD(GetProcessorUsage) (ULONG *user, ULONG *system);
    533 
    534525    // public methods only for internal purposes
    535526
     
    721712
    722713#ifdef VBOX_WITH_RESOURCE_USAGE_API
    723     /** Static timer callback. */
    724     static void UsageSamplerCallback (PRTTIMER pTimer, void *pvUser, uint64_t iTick);
    725     /** Member timer callback. */
    726     void usageSamplerCallback();
     714    void registerMetrics(PerformanceCollector *collector);
     715    void unregisterMetrics(PerformanceCollector *collector);
    727716#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    728717
  • trunk/src/VBox/Main/include/VirtualBoxImpl.h

    r10333 r10528  
    3636# include "win/resource.h"
    3737#endif
     38
     39#ifdef VBOX_WITH_RESOURCE_USAGE_API
     40#include "PerformanceImpl.h"
     41#endif /* VBOX_WITH_RESOURCE_USAGE_API */
     42
    3843
    3944class Machine;
     
    127132    STDMETHOD(COMGETTER(GuestOSTypes)) (IGuestOSTypeCollection **aGuestOSTypes);
    128133    STDMETHOD(COMGETTER(SharedFolders)) (ISharedFolderCollection **aSharedFolders);
     134    STDMETHOD(COMGETTER(PerformanceCollector)) (IPerformanceCollector **aPerformanceCollector);
    129135
    130136    /* IVirtualBox methods */
     
    345351    static const wchar_t *getComponentName() { return L"VirtualBox"; }
    346352
     353#ifdef VBOX_WITH_RESOURCE_USAGE_API
     354    PerformanceCollector *getCollector() { return mData.mPerformanceCollector; };
     355#endif /* VBOX_WITH_RESOURCE_USAGE_API */
     356
    347357private:
    348358
     
    414424        const ComObjPtr <Host> mHost;
    415425        const ComObjPtr <SystemProperties> mSystemProperties;
     426#ifdef VBOX_WITH_RESOURCE_USAGE_API
     427        const ComObjPtr <PerformanceCollector> mPerformanceCollector;
     428#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    416429
    417430        CfgFile mCfgFile;
  • trunk/src/VBox/Main/testcase/tstAPI.cpp

    r9911 r10528  
    920920
    921921#if 1
    922     for (int i = 0; i < 10; i++)
    923     {
     922    {
     923        Bstr metricNames[] = { L"CPU/User:avg,CPU/System:avg,CPU/Idle:avg" };
     924        com::SafeArray<BSTR> metrics(1);
     925        metricNames[0].detachTo(&metrics[0]);
     926
    924927        ComPtr <IHost> host;
    925928        CHECK_RC_BREAK (virtualBox->COMGETTER(Host) (host.asOutParam()));
     929        ComPtr <IPerformanceCollector> collector;
     930        CHECK_RC( virtualBox->COMGETTER(PerformanceCollector)(collector.asOutParam()) );
     931
     932        com::SafeIfaceArray<IUnknown> objects(1);
     933        host.queryInterfaceTo(&objects[0]);
     934        collector->SetupMetrics(ComSafeArrayAsInParam(metrics),
     935                                ComSafeArrayAsInParam(objects), 1u, 10u);
     936        RTThreadSleep(3000); /* Sleep 10 seconds. */
     937        /*com::SafeIfaceArray<IPerformanceData> result;
     938        collector->QueryMetricsData(ComSafeArrayAsInParam(metrics),
     939                                    ComSafeArrayAsInParam(objects),
     940                                    ComSafeArrayAsOutParam(result));
     941        for (unsigned i = 0; i < result.size(); i++)
     942        {
     943            Bstr metricName;
     944            result[i]->COMGETTER(MetricName) (metricName.asOutParam());
     945            com::SafeArray<LONG> values;
     946            result[i]->COMGETTER(Values) (ComSafeArrayAsOutParam(values));
     947            printf("%ls", metricName.raw());
     948            for (unsigned j = 0; j < values.size(); j++)
     949            {
     950                printf(" %d\n", values[j]);
     951            }
     952        }*/
     953    }
     954#endif
     955#if 0
     956    for (int i = 0; i < 10; i++)
     957    {
    926958        ULONG user, system, idle;
    927959        host->GetProcessorUsage(&user, &system, &idle);
    928960        printf("user=%u system=%u idle=%u\n", user/10000000, system/10000000, idle/10000000);
    929         RTThreadSleep(1000);
    930     }
    931 #endif
    932 
    933 #if 1
     961    }
     962#endif
     963
     964#if 0
    934965    {
    935966        ComPtr <IMachine> machine;
  • trunk/src/VBox/Main/xpcom/server.cpp

    r9446 r10528  
    189189NS_DECL_CLASSINFO(SystemProperties)
    190190NS_IMPL_THREADSAFE_ISUPPORTS1_CI(SystemProperties, ISystemProperties)
     191#ifdef VBOX_WITH_RESOURCE_USAGE_API
     192NS_DECL_CLASSINFO(PerformanceCollector)
     193NS_IMPL_THREADSAFE_ISUPPORTS1_CI(PerformanceCollector, IPerformanceCollector)
     194NS_DECL_CLASSINFO(PerformanceMetric)
     195NS_IMPL_THREADSAFE_ISUPPORTS1_CI(PerformanceMetric, IPerformanceMetric)
     196#endif /* VBOX_WITH_RESOURCE_USAGE_API */
    191197NS_DECL_CLASSINFO(BIOSSettings)
    192198NS_IMPL_THREADSAFE_ISUPPORTS1_CI(BIOSSettings, IBIOSSettings)
  • trunk/src/VBox/Runtime/r3/os2/system-os2.cpp

    r9906 r10528  
    6767}
    6868
    69 RTDECL(int) RTSystemProcessorGetUsageStats(PRTCPUUSAGESTATS pStats)
    70 {
    71     /* @todo Implement! */
    72     return VERR_NOT_IMPLEMENTED;
    73 }
    74 
    75 RTDECL(int) RTProcessGetProcessorUsageStats(RTPROCESS pid, PRTPROCCPUUSAGESTATS pStats)
    76 {
    77     /* @todo Implement! */
    78     return VERR_NOT_IMPLEMENTED;
    79 }
    80 
  • trunk/src/VBox/Runtime/r3/posix/system-posix.cpp

    r9935 r10528  
    9292}
    9393
    94 /**
    95  * Gets the current figures of overall system processor usage.
    96  *
    97  * @remarks To get meaningful stats this function has to be
    98  *          called twice with a bit of delay between calls. This
    99  *          is due to the fact that at least two samples of
    100  *          system usage stats are needed to calculate the load.
    101  *
    102  * @returns None.
    103  */
    104 RTDECL(int) RTSystemProcessorGetUsageStats(PRTCPUUSAGESTATS pStats)
    105 {
    106 /** @todo r=bird: This is Linux specific and doesn't belong here. Move this to r3/linux/RTSystemGetCpuLoadStats-linux.cpp. */
    107     int rc = VINF_SUCCESS;
    108     uint32_t u32UserNow, u32NiceNow, u32SystemNow, u32IdleNow;
    109     uint32_t u32UserDelta, u32SystemDelta, u32IdleDelta, u32BusyDelta, u32TotalDelta;
    110     FILE *f = fopen("/proc/stat", "r");
    111 
    112     if (f)
    113     {
    114         if (fscanf(f, "cpu %u %u %u %u", &u32UserNow, &u32NiceNow, &u32SystemNow, &u32IdleNow) == 4)
    115         {
    116             u32UserDelta   = (u32UserNow - pStats->u32RawUser) + (u32NiceNow - pStats->u32RawNice);
    117             u32SystemDelta = u32SystemNow - pStats->u32RawSystem;
    118             u32IdleDelta   = u32IdleNow - pStats->u32RawIdle;
    119             u32BusyDelta   = u32UserDelta + u32SystemDelta;
    120             u32TotalDelta  = u32BusyDelta + u32IdleDelta;
    121             pStats->u32User   = (uint32_t)(IPRT_USAGE_MULTIPLIER * u32UserDelta / u32TotalDelta);
    122             pStats->u32System = (uint32_t)(IPRT_USAGE_MULTIPLIER * u32SystemDelta / u32TotalDelta);
    123             pStats->u32Idle   = (uint32_t)(IPRT_USAGE_MULTIPLIER * u32IdleDelta / u32TotalDelta);
    124             /* Update the base. */
    125             pStats->u32RawUser   = u32UserNow;
    126             pStats->u32RawNice   = u32NiceNow;
    127             pStats->u32RawSystem = u32SystemNow;
    128             pStats->u32RawIdle   = u32IdleNow;
    129         }
    130         else
    131             rc = VERR_FILE_IO_ERROR;
    132         fclose(f);
    133     }
    134     else
    135         rc = VERR_ACCESS_DENIED;
    136 
    137     return rc;
    138 }
    139 
    140 /**
    141  * Gets the current processor usage for a partucilar process.
    142  *
    143  * @remarks To get meaningful stats this function has to be
    144  *          called twice with a bit of delay between calls. This
    145  *          is due to the fact that at least two samples of
    146  *          system usage stats are needed to calculate the load.
    147  *
    148  * @returns None.
    149  */
    150 RTDECL(int) RTProcessGetProcessorUsageStats(RTPROCESS pid, PRTPROCCPUUSAGESTATS pStats)
    151 {
    152     int rc = VINF_SUCCESS;
    153     uint32_t u32UserNow, u32NiceNow, u32SystemNow, u32IdleNow;
    154     uint32_t u32UserDelta, u32SystemDelta;
    155     uint64_t u64TotalNow, u64TotalDelta;
    156 
    157 /** @todo r=bird: This is Linux specific and doesn't belong here. Move this to r3/linux/RTSystemGetCpuLoadStats-linux.cpp. */
    158     FILE *f = fopen("/proc/stat", "r");
    159 
    160     if (f)
    161     {
    162         if (fscanf(f, "cpu %u %u %u %u", &u32UserNow, &u32NiceNow, &u32SystemNow, &u32IdleNow) == 4) /** @todo 'uint32_t' is not necessarily the same as 'unsigned int'. */
    163         {
    164             char *pszName;
    165             pid_t pid2;
    166             char c;
    167             int iTmp;
    168             unsigned uTmp;
    169             unsigned long ulTmp, ulUserNow, ulSystemNow;
    170             char buf[80]; /* @todo: this should be tied to max allowed proc name. */
    171 
    172             u64TotalNow = (uint64_t)u32UserNow + u32NiceNow + u32SystemNow + u32IdleNow;
    173             fclose(f);
    174             RTStrAPrintf(&pszName, "/proc/%d/stat", pid);
    175             //printf("Opening %s...\n", pszName);
    176             f = fopen(pszName, "r");
    177             RTMemFree(pszName);
    178 
    179             if (f)
    180             {
    181                 if (fscanf(f, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu",
    182                            &pid2, buf, &c, &iTmp, &iTmp, &iTmp, &iTmp, &iTmp, &uTmp,
    183                            &ulTmp, &ulTmp, &ulTmp, &ulTmp, &ulUserNow, &ulSystemNow) == 15)
    184                 {
    185                     Assert((pid_t)pid == pid2);
    186                     u32UserDelta      = ulUserNow - pStats->u32RawProcUser;
    187                     u32SystemDelta    = ulSystemNow - pStats->u32RawProcSystem;
    188                     u64TotalDelta     = u64TotalNow - pStats->u64RawTotal;
    189                     pStats->u32User   = (uint32_t)(IPRT_USAGE_MULTIPLIER * u32UserDelta / u64TotalDelta);
    190                     pStats->u32System = (uint32_t)(IPRT_USAGE_MULTIPLIER * u32SystemDelta / u64TotalDelta);
    191 //                  printf("%d: user=%u%% system=%u%% / raw user=%u raw system=%u total delta=%u\n", pid,
    192 //                         pStats->u32User / 10000000, pStats->u32System / 10000000,
    193 //                         pStats->u32RawProcUser, pStats->u32RawProcSystem, u64TotalDelta);
    194                     /* Update the base. */
    195                     pStats->u32RawProcUser   = ulUserNow;
    196                     pStats->u32RawProcSystem = ulSystemNow;
    197                     pStats->u64RawTotal      = u64TotalNow;
    198 //                  printf("%d: updated raw user=%u raw system=%u raw total=%u\n", pid,
    199 //                         pStats->u32RawProcUser, pStats->u32RawProcSystem, pStats->u64RawTotal);
    200                 }
    201                 else
    202                     rc = VERR_FILE_IO_ERROR;
    203             }
    204             else
    205                 rc = VERR_ACCESS_DENIED;
    206         }
    207         else
    208             rc = VERR_FILE_IO_ERROR;
    209         fclose(f);
    210     }
    211     else
    212         rc = VERR_ACCESS_DENIED;
    213 
    214     return rc;
    215 }
  • trunk/src/VBox/Runtime/r3/win/system-win.cpp

    r9906 r10528  
    6262}
    6363
    64 RTDECL(int) RTSystemProcessorGetUsageStats(PRTCPUUSAGESTATS pStats)
    65 {
    66     /* @todo Implement! */
    67     return VERR_NOT_IMPLEMENTED;
    68 }
    69 
    70 RTDECL(int) RTProcessGetProcessorUsageStats(RTPROCESS pid, PRTPROCCPUUSAGESTATS pStats)
    71 {
    72     /* @todo Implement! */
    73     return VERR_NOT_IMPLEMENTED;
    74 }
    75 
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