VirtualBox

Changeset 40358 in vbox


Ignore:
Timestamp:
Mar 5, 2012 2:40:52 PM (13 years ago)
Author:
vboxsync
Message:

Main/Metrics: All calls to VM processes are done in separate thread (#6029)

Location:
trunk/src/VBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp

    r40081 r40358  
    303303                     ComSafeArrayAsInParam(objects), period, samples,
    304304                     ComSafeArrayAsOutParam(affectedMetrics)));
     305    if (FAILED(rc))
     306        return 2;
     307
    305308    if (listMatches)
    306309        listAffectedMetrics(aVirtualBox,
     
    475478                     ComSafeArrayAsInParam(objects), period, samples,
    476479                     ComSafeArrayAsOutParam(affectedMetrics)));
     480    if (FAILED(rc))
     481        return 2;
     482
    477483    if (listMatches)
    478484        listAffectedMetrics(aVirtualBox,
     
    581587                      ComSafeArrayAsInParam(objects),
    582588                      ComSafeArrayAsOutParam(affectedMetrics)));
     589    if (FAILED(rc))
     590        return 2;
     591
    583592    if (listMatches)
    584593        listAffectedMetrics(aVirtualBox,
     
    623632                       ComSafeArrayAsInParam(objects),
    624633                       ComSafeArrayAsOutParam(affectedMetrics)));
     634    if (FAILED(rc))
     635        return 2;
     636
    625637    if (listMatches)
    626638        listAffectedMetrics(aVirtualBox,
  • trunk/src/VBox/Main/include/Performance.h

    r40084 r40358  
    2525#include <iprt/types.h>
    2626#include <iprt/err.h>
     27#include <iprt/cpp/lock.h>
    2728
    2829#include <algorithm>
     
    3031#include <list>
    3132#include <vector>
     33#include <queue>
    3234
    3335/* Forward decl. */
     
    171173        GUESTSTATMASK_ALLOCVMM|GUESTSTATMASK_FREEVMM|
    172174        GUESTSTATMASK_BALOONVMM|GUESTSTATMASK_SHAREDVMM;
     175    const ULONG GUESTSTATS_ALL = GUESTSTATS_CPULOAD|GUESTSTATS_RAMUSAGE|GUESTSTATS_VMMRAM;
     176
     177    class CollectorGuest;
     178
     179    class CollectorGuestRequest
     180    {
     181    public:
     182        CollectorGuestRequest()
     183            : mCGuest(0) {};
     184        virtual ~CollectorGuestRequest() {};
     185        void setGuest(CollectorGuest *aGuest) { mCGuest = aGuest; };
     186        CollectorGuest *getGuest() { return mCGuest; };
     187        virtual int execute() = 0;
     188
     189        virtual void debugPrint(void *aObject, const char *aFunction, const char *aText) = 0;
     190    protected:
     191        CollectorGuest *mCGuest;
     192        const char *mDebugName;
     193    };
     194
     195    class CGRQEnable : public CollectorGuestRequest
     196    {
     197    public:
     198        CGRQEnable(ULONG aMask)
     199            : mMask(aMask) {};
     200        int execute();
     201
     202        void debugPrint(void *aObject, const char *aFunction, const char *aText);
     203    private:
     204        ULONG mMask;
     205    };
     206
     207    class CGRQDisable : public CollectorGuestRequest
     208    {
     209    public:
     210        CGRQDisable(ULONG aMask)
     211            : mMask(aMask) {};
     212        int execute();
     213
     214        void debugPrint(void *aObject, const char *aFunction, const char *aText);
     215    private:
     216        ULONG mMask;
     217    };
     218
     219    class CGRQAbort : public CollectorGuestRequest
     220    {
     221    public:
     222        CGRQAbort() {};
     223        int execute();
     224
     225        void debugPrint(void *aObject, const char *aFunction, const char *aText);
     226    };
     227
     228    class CollectorGuestQueue
     229    {
     230    public:
     231        CollectorGuestQueue();
     232        ~CollectorGuestQueue();
     233        void push(CollectorGuestRequest* rq);
     234        CollectorGuestRequest* pop();
     235    private:
     236        RTCLockMtx mLockMtx;
     237        RTSEMEVENT mEvent;
     238        std::queue<CollectorGuestRequest*> mQueue;
     239    };
     240
     241    class CollectorGuestManager;
    173242
    174243    class CollectorGuest
     
    178247        ~CollectorGuest();
    179248
    180         bool isUnregistered()   { return mUnregistered; };
    181         bool isEnabled()        { return mEnabled; };
    182         bool isValid(ULONG mask){ return (mValid & mask) == mask; };
    183         void invalidateStats()  { mValid = 0; };
    184         void unregister()       { mUnregistered = true; };
     249        void setManager(CollectorGuestManager *aManager)
     250                                    { mManager = aManager; };
     251        bool isUnregistered()       { return mUnregistered; };
     252        bool isEnabled()            { return mEnabled != 0; };
     253        bool isValid(ULONG mask)    { return (mValid & mask) == mask; };
     254        void invalidate(ULONG mask) { mValid &= ~mask; };
     255        void unregister()           { mUnregistered = true; };
    185256        void updateStats(ULONG aValidStats, ULONG aCpuUser,
    186257                         ULONG aCpuKernel, ULONG aCpuIdle,
     
    190261                         ULONG aAllocVMM, ULONG aFreeVMM,
    191262                         ULONG aBalloonedVMM, ULONG aSharedVMM);
    192         int enable();
    193         int disable();
    194         int enableVMMStats(bool mCollectVMMStats);
     263        int enable(ULONG mask);
     264        int disable(ULONG mask);
     265
     266        int enqueueRequest(CollectorGuestRequest *aRequest);
     267        int enableInternal(ULONG mask);
     268        int disableInternal(ULONG mask);
     269
     270        const com::Utf8Str& getVMName() const { return mMachineName; };
    195271
    196272        RTPROCESS getProcess()  { return mProcess; };
     
    210286
    211287    private:
     288        int enableVMMStats(bool mCollectVMMStats);
     289
     290        CollectorGuestManager *mManager;
     291
    212292        bool                 mUnregistered;
    213         bool                 mEnabled;
     293        ULONG                mEnabled;
    214294        ULONG                mValid;
    215295        Machine             *mMachine;
     296        com::Utf8Str         mMachineName;
    216297        RTPROCESS            mProcess;
    217298        ComPtr<IConsole>     mConsole;
     
    236317    {
    237318    public:
    238         CollectorGuestManager() : mVMMStatsProvider(NULL) {};
    239         ~CollectorGuestManager() { Assert(mGuests.size() == 0); };
     319        CollectorGuestManager();
     320        ~CollectorGuestManager();
    240321        void registerGuest(CollectorGuest* pGuest);
    241322        void unregisterGuest(CollectorGuest* pGuest);
     
    243324        void preCollect(CollectorHints& hints, uint64_t iTick);
    244325        void destroyUnregistered();
    245     private:
    246         CollectorGuestList mGuests;
    247         CollectorGuest    *mVMMStatsProvider;
     326        int enqueueRequest(CollectorGuestRequest *aRequest);
     327
     328        CollectorGuest *getBlockedGuest() { return mGuestBeingCalled; };
     329
     330        static DECLCALLBACK(int) requestProcessingThread(RTTHREAD aThread, void *pvUser);
     331    private:
     332        RTTHREAD            mThread;
     333        CollectorGuestList  mGuests;
     334        CollectorGuest     *mVMMStatsProvider;
     335        CollectorGuestQueue mQueue;
     336        CollectorGuest     *mGuestBeingCalled;
    248337    };
    249338
     
    293382        bool collectorBeat(uint64_t nowAt);
    294383
    295         void enable()  { mEnabled = true; };
    296         void disable() { mEnabled = false; };
     384        virtual int enable()  { mEnabled = true; return S_OK; };
     385        virtual int disable() { mEnabled = false; return S_OK; };
    297386        void unregister() { mUnregistered = true; };
    298387
     
    398487    };
    399488
     489#ifndef VBOX_COLLECTOR_TEST_CASE
    400490    class HostRamVmm : public BaseMetric
    401491    {
     
    410500        void preCollect(CollectorHints& hints, uint64_t iTick);
    411501        void collect();
     502        int enable();
     503        int disable();
    412504        const char *getUnit() { return "kB"; };
    413505        ULONG getMinValue() { return 0; };
     
    426518        ULONG                  mSharedCurrent;
    427519    };
     520#endif /* VBOX_COLLECTOR_TEST_CASE */
    428521
    429522    class MachineCpuLoad : public BaseMetric
     
    480573
    481574
     575#ifndef VBOX_COLLECTOR_TEST_CASE
    482576    class GuestCpuLoad : public BaseGuestMetric
    483577    {
     
    490584        void preCollect(CollectorHints& hints, uint64_t iTick);
    491585        void collect();
     586        int enable();
     587        int disable();
    492588        const char *getUnit() { return "%"; };
    493589        ULONG getMinValue() { return 0; };
     
    510606        void preCollect(CollectorHints& hints, uint64_t iTick);
    511607        void collect();
     608        int enable();
     609        int disable();
    512610        const char *getUnit() { return "kB"; };
    513611        ULONG getMinValue() { return 0; };
     
    517615        SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
    518616    };
     617#endif /* VBOX_COLLECTOR_TEST_CASE */
    519618
    520619    /* Aggregate Functions **************************************************/
  • trunk/src/VBox/Main/include/PerformanceImpl.h

    r36128 r40358  
    195195    void samplerCallback(uint64_t iTick);
    196196
     197    const Utf8Str& getFailedGuestName();
     198
    197199    typedef std::list<pm::Metric*> MetricList;
    198200    typedef std::list<pm::BaseMetric*> BaseMetricList;
     
    204206
    205207    unsigned int mMagic;
     208    const Utf8Str mUnknownGuest;
    206209
    207210    struct Data
  • trunk/src/VBox/Main/src-server/Performance.cpp

    r40084 r40358  
    109109#ifndef VBOX_COLLECTOR_TEST_CASE
    110110
     111CollectorGuestQueue::CollectorGuestQueue()
     112{
     113    mEvent = NIL_RTSEMEVENT;
     114    RTSemEventCreate(&mEvent);
     115}
     116
     117CollectorGuestQueue::~CollectorGuestQueue()
     118{
     119    RTSemEventDestroy(mEvent);
     120}
     121
     122void CollectorGuestQueue::push(CollectorGuestRequest* rq)
     123{
     124    RTCLock lock(mLockMtx);
     125
     126    mQueue.push(rq);
     127    RTSemEventSignal(mEvent);
     128}
     129
     130CollectorGuestRequest* CollectorGuestQueue::pop()
     131{
     132    int rc = VINF_SUCCESS;
     133    CollectorGuestRequest* rq = NULL;
     134
     135    do
     136    {
     137        {
     138            RTCLock lock(mLockMtx);
     139
     140            if (!mQueue.empty())
     141            {
     142                rq = mQueue.front();
     143                mQueue.pop();
     144            }
     145        }
     146
     147        if (rq)
     148            return rq;
     149        else
     150            rc = RTSemEventWaitNoResume(mEvent, RT_INDEFINITE_WAIT);
     151    }
     152    while (RT_SUCCESS(rc));
     153
     154    return NULL;
     155}
     156
     157int CGRQEnable::execute()
     158{
     159    Assert(mCGuest);
     160    return mCGuest->enableInternal(mMask);
     161}
     162
     163void CGRQEnable::debugPrint(void *aObject, const char *aFunction, const char *aText)
     164{
     165    LogAleksey(("{%p} " LOG_FN_FMT ": CGRQEnable(mask=0x%x) %s\n",
     166                aObject, aFunction, mMask, aText));
     167}
     168
     169int CGRQDisable::execute()
     170{
     171    Assert(mCGuest);
     172    return mCGuest->disableInternal(mMask);
     173}
     174
     175void CGRQDisable::debugPrint(void *aObject, const char *aFunction, const char *aText)
     176{
     177    LogAleksey(("{%p} " LOG_FN_FMT ": CGRQDisable(mask=0x%x) %s\n",
     178                aObject, aFunction, mMask, aText));
     179}
     180
     181int CGRQAbort::execute()
     182{
     183    return E_ABORT;
     184}
     185
     186void CGRQAbort::debugPrint(void *aObject, const char *aFunction, const char *aText)
     187{
     188    LogAleksey(("{%p} " LOG_FN_FMT ": CGRQAbort %s\n",
     189                aObject, aFunction, aText));
     190}
     191
    111192CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) :
    112193    mUnregistered(false), mEnabled(false), mValid(false), mMachine(machine), mProcess(process),
     
    153234}
    154235
    155 int CollectorGuest::enable()
    156 {
    157     mEnabled = true;
    158     /* Must make sure that the machine object does not get uninitialized
    159      * in the middle of enabling this collector. Causes timing-related
    160      * behavior otherwise, which we don't want. In particular the
    161      * GetRemoteConsole call below can hang if the VM didn't completely
    162      * terminate (the VM processes stop processing events shortly before
    163      * closing the session). This avoids the hang. */
    164     AutoCaller autoCaller(mMachine);
    165     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    166 
     236int CollectorGuest::enable(ULONG mask)
     237{
     238    return enqueueRequest(new CGRQEnable(mask));
     239}
     240
     241int CollectorGuest::disable(ULONG mask)
     242{
     243    return enqueueRequest(new CGRQDisable(mask));
     244}
     245
     246int CollectorGuest::enableInternal(ULONG mask)
     247{
    167248    HRESULT ret = S_OK;
    168249
    169     ComPtr<IInternalSessionControl> directControl;
    170 
    171     ret = mMachine->getDirectControl(&directControl);
    172     if (ret != S_OK)
    173         return ret;
    174 
    175     /* get the associated console; this is a remote call (!) */
    176     ret = directControl->GetRemoteConsole(mConsole.asOutParam());
    177     if (ret != S_OK)
    178         return ret;
    179 
    180     ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam());
    181     if (ret == S_OK)
    182     {
    183         ret = mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */);
    184         LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 1 sec (%s)\n",
     250    if ((mEnabled & mask) == mask)
     251        return E_UNEXPECTED;
     252
     253    if (!mEnabled)
     254    {
     255        /* Must make sure that the machine object does not get uninitialized
     256         * in the middle of enabling this collector. Causes timing-related
     257         * behavior otherwise, which we don't want. In particular the
     258         * GetRemoteConsole call below can hang if the VM didn't completely
     259         * terminate (the VM processes stop processing events shortly before
     260         * closing the session). This avoids the hang. */
     261        AutoCaller autoCaller(mMachine);
     262        if (FAILED(autoCaller.rc())) return autoCaller.rc();
     263
     264        mMachineName = mMachine->getName();
     265
     266        ComPtr<IInternalSessionControl> directControl;
     267
     268        ret = mMachine->getDirectControl(&directControl);
     269        if (ret != S_OK)
     270            return ret;
     271
     272        /* get the associated console; this is a remote call (!) */
     273        ret = directControl->GetRemoteConsole(mConsole.asOutParam());
     274        if (ret != S_OK)
     275            return ret;
     276
     277        ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam());
     278        if (ret == S_OK)
     279        {
     280            ret = mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */);
     281            LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 1 sec (%s)\n",
     282                        this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
     283        }
     284    }
     285    if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
     286        enableVMMStats(true);
     287    mEnabled |= mask;
     288
     289    return ret;
     290}
     291
     292int CollectorGuest::disableInternal(ULONG mask)
     293{
     294    if (!(mEnabled & mask))
     295        return E_UNEXPECTED;
     296
     297    if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
     298        enableVMMStats(false);
     299    mEnabled &= ~mask;
     300    if (!mEnabled)
     301    {
     302        Assert(mGuest && mConsole);
     303        HRESULT ret = mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
     304        NOREF(ret);
     305        LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n",
    185306                    this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
    186     }
    187 
    188     return ret;
    189 }
    190 
    191 int CollectorGuest::disable()
    192 {
    193     mEnabled = false;
    194     Assert(mGuest && mConsole);
    195     HRESULT ret = mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
    196     NOREF(ret);
    197     LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n",
    198                 this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
    199     invalidateStats();
     307        invalidate(GUESTSTATS_ALL);
     308    }
    200309
    201310    return S_OK;
     311}
     312
     313int CollectorGuest::enqueueRequest(CollectorGuestRequest *aRequest)
     314{
     315    if (mManager)
     316    {
     317        aRequest->setGuest(this);
     318        return mManager->enqueueRequest(aRequest);
     319    }
     320
     321    LogAleksey(("{%p} " LOG_FN_FMT ": Attempted enqueue guest request when mManager is null\n",
     322                this, __PRETTY_FUNCTION__));
     323    return E_POINTER;
    202324}
    203325
     
    235357}
    236358
    237 void CollectorGuestManager::preCollect(CollectorHints& hints, uint64_t /* iTick */)
    238 {
    239     /*
    240      * Since we are running without a lock the value of mVMMStatsProvider
    241      * can change at any moment. In the worst case we won't collect any data.
    242      */
    243     CollectorGuestList::iterator it;
    244 
    245     LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p ramvmm=%s\n",
    246                 this, __PRETTY_FUNCTION__, mVMMStatsProvider, hints.isHostRamVmmCollected()?"y":"n"));
    247     for (it = mGuests.begin(); it != mGuests.end(); it++)
    248     {
    249         LogAleksey(("{%p} " LOG_FN_FMT ": it=%p pid=%d gueststats=%s...\n",
    250                     this, __PRETTY_FUNCTION__, *it, (*it)->getProcess(),
    251                     hints.isGuestStatsCollected((*it)->getProcess())?"y":"n"));
    252         if ((*it)->isUnregistered())
    253             continue;
    254         if (  (hints.isHostRamVmmCollected() && *it == mVMMStatsProvider)
    255             || hints.isGuestStatsCollected((*it)->getProcess()))
    256         {
    257             /* Guest stats collection needs to be enabled */
    258             if ((*it)->isEnabled())
    259             {
    260                 /* Already enabled, collect the data */
    261                 /*
    262                  * Actually the data will be pushed by Guest object, so
    263                  * we don't need to do anything here.
    264                  */
    265                 //(*it)->updateStats();
    266             }
    267             else
    268             {
    269                 (*it)->invalidateStats();
    270                 (*it)->enable();
    271                 (*it)->enableVMMStats(*it == mVMMStatsProvider);
    272             }
    273         }
    274         else
    275         {
    276             /* Guest stats collection needs to be disabled */
    277             if ((*it)->isEnabled())
    278                 (*it)->disable();
    279         }
     359CollectorGuestManager::CollectorGuestManager()
     360  : mVMMStatsProvider(NULL), mGuestBeingCalled(NULL)
     361{
     362    int rc = RTThreadCreate(&mThread, CollectorGuestManager::requestProcessingThread,
     363                            this, 0, RTTHREADTYPE_MAIN_WORKER, RTTHREADFLAGS_WAITABLE,
     364                            "CGMgr");
     365    LogAleksey(("{%p} " LOG_FN_FMT ": RTThreadCreate returned %u (mThread=%p)\n",
     366                this, __PRETTY_FUNCTION__, rc));
     367}
     368
     369CollectorGuestManager::~CollectorGuestManager()
     370{
     371    Assert(mGuests.size() == 0);
     372    int rcThread = 0;
     373    int rc = enqueueRequest(new CGRQAbort());
     374    if (SUCCEEDED(rc))
     375    {
     376        /* We wait only if we were able to put the abort request to a queue */
     377        LogAleksey(("{%p} " LOG_FN_FMT ": Waiting for CGM request processing thread to stop...\n",
     378                    this, __PRETTY_FUNCTION__));
     379        rc = RTThreadWait(mThread, 1000 /* 1 sec */, &rcThread);
     380        LogAleksey(("{%p} " LOG_FN_FMT ": RTThreadWait returned %u (thread exit code: %u)\n",
     381                    this, __PRETTY_FUNCTION__, rc, rcThread));
    280382    }
    281383}
     
    283385void CollectorGuestManager::registerGuest(CollectorGuest* pGuest)
    284386{
     387    pGuest->setManager(this);
    285388    mGuests.push_back(pGuest);
    286389    /*
     
    296399void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest)
    297400{
     401    int rc = S_OK;
     402
    298403    LogAleksey(("{%p} " LOG_FN_FMT ": About to unregister guest=%p provider=%p\n",
    299404                this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider));
     
    317422                /* Found the guest already collecting stats, elect it */
    318423                mVMMStatsProvider = *it;
    319                 mVMMStatsProvider->enableVMMStats(true);
     424                rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM));
     425                if (FAILED(rc))
     426                {
     427                    /* This is not a good candidate -- try to find another */
     428                    mVMMStatsProvider = NULL;
     429                    continue;
     430                }
    320431                break;
    321432            }
    322             else if (!mVMMStatsProvider)
     433        }
     434        if (!mVMMStatsProvider)
     435        {
     436            /* If nobody collects stats, take the first registered */
     437            for (it = mGuests.begin(); it != mGuests.end(); it++)
    323438            {
    324                 /* If nobody collects stats, take the first registered */
     439                /* Skip unregistered as they are about to be destroyed */
     440                if ((*it)->isUnregistered())
     441                    continue;
     442
    325443                mVMMStatsProvider = *it;
    326                 /*
    327                  * No need to notify the guest at this point as it will be
    328                  * done in CollectorGuestManager::preCollect when it gets
    329                  * enabled.
    330                  */
     444                //mVMMStatsProvider->enable(GUESTSTATS_VMMRAM);
     445                rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM));
     446                if (SUCCEEDED(rc))
     447                    break;
     448                /* This was not a good candidate -- try to find another */
     449                mVMMStatsProvider = NULL;
    331450            }
    332451        }
     
    351470            ++it;
    352471}
     472
     473int CollectorGuestManager::enqueueRequest(CollectorGuestRequest *aRequest)
     474{
     475#ifdef DEBUG
     476    aRequest->debugPrint(this, __PRETTY_FUNCTION__, "added to CGM queue");
     477#endif /* DEBUG */
     478    /*
     479     * It is very unlikely that we will get high frequency calls to configure
     480     * guest metrics collection, so we rely on this fact to detect blocked
     481     * guests. If the guest has not finished processing the previous request
     482     * we consider it blocked.
     483     */
     484    if (aRequest->getGuest() && aRequest->getGuest() == mGuestBeingCalled)
     485    {
     486        /* Request execution got stalled for this guest -- report an error */
     487        return E_FAIL;
     488    }
     489    mQueue.push(aRequest);
     490    return S_OK;
     491}
     492
     493/* static */
     494DECLCALLBACK(int) CollectorGuestManager::requestProcessingThread(RTTHREAD /* aThread */, void *pvUser)
     495{
     496    CollectorGuestRequest *pReq;
     497    CollectorGuestManager *mgr = static_cast<CollectorGuestManager*>(pvUser);
     498
     499    HRESULT rc = S_OK;
     500
     501    LogAleksey(("{%p} " LOG_FN_FMT ": Starting request processing loop...p\n",
     502                mgr, __PRETTY_FUNCTION__));
     503    while ((pReq = mgr->mQueue.pop()) != NULL)
     504    {
     505#ifdef DEBUG
     506        pReq->debugPrint(mgr, __PRETTY_FUNCTION__, "is being executed...");
     507#endif /* DEBUG */
     508        mgr->mGuestBeingCalled = pReq->getGuest();
     509        rc = pReq->execute();
     510        mgr->mGuestBeingCalled = NULL;
     511        delete pReq;
     512        if (rc == E_ABORT)
     513            break;
     514        if (FAILED(rc))
     515            LogAleksey(("{%p} " LOG_FN_FMT ": request::execute returned %u\n",
     516                        mgr, __PRETTY_FUNCTION__, rc));
     517    }
     518    LogAleksey(("{%p} " LOG_FN_FMT ": Exiting request processing loop... rc=%u\n",
     519                        mgr, __PRETTY_FUNCTION__, rc));
     520
     521    return VINF_SUCCESS;
     522}
     523
    353524
    354525#endif /* !VBOX_COLLECTOR_TEST_CASE */
     
    472643}
    473644
     645#ifndef VBOX_COLLECTOR_TEST_CASE
    474646void HostRamVmm::init(ULONG period, ULONG length)
    475647{
     
    482654}
    483655
     656int HostRamVmm::enable()
     657{
     658    int rc = S_OK;
     659    CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
     660    if (provider)
     661        rc = provider->enable(GUESTSTATS_VMMRAM);
     662    BaseMetric::enable();
     663    return rc;
     664}
     665
     666int HostRamVmm::disable()
     667{
     668    int rc = S_OK;
     669    BaseMetric::disable();
     670    CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
     671    if (provider)
     672        rc = provider->disable(GUESTSTATS_VMMRAM);
     673    return rc;
     674}
     675
    484676void HostRamVmm::preCollect(CollectorHints& hints, uint64_t /* iTick */)
    485677{
     
    502694            mBalloonedCurrent = provider->getBalloonedVMM();
    503695            mSharedCurrent    = provider->getSharedVMM();
    504         }
     696            provider->invalidate(GUESTSTATS_VMMRAM);
     697        }
     698        /*
     699         * Note that if there are no new values from the provider we will use
     700         * the ones most recently provided instead of zeros, which is probably
     701         * a desirable behavior.
     702         */
    505703    }
    506704    else
     
    519717    mSharedVMM->put(mSharedCurrent);
    520718}
     719#endif /* !VBOX_COLLECTOR_TEST_CASE */
    521720
    522721
     
    592791
    593792
     793#ifndef VBOX_COLLECTOR_TEST_CASE
    594794void GuestCpuLoad::init(ULONG period, ULONG length)
    595795{
     
    614814        mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuKernel()) / 100);
    615815        mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuIdle()) / 100);
    616     }
     816        mCGuest->invalidate(GUESTSTATS_CPULOAD);
     817    }
     818}
     819
     820int GuestCpuLoad::enable()
     821{
     822    int rc = mCGuest->enable(GUESTSTATS_CPULOAD);
     823    BaseMetric::enable();
     824    return rc;
     825}
     826
     827int GuestCpuLoad::disable()
     828{
     829    BaseMetric::disable();
     830    return mCGuest->disable(GUESTSTATS_CPULOAD);
    617831}
    618832
     
    630844}
    631845
    632 void GuestRamUsage::preCollect(CollectorHints& hints,  uint64_t /* iTick */)
    633 {
    634     hints.collectGuestStats(mCGuest->getProcess());
    635 }
    636 
    637846void GuestRamUsage::collect()
    638847{
     
    645854        mCache->put(mCGuest->getMemCache());
    646855        mPagedTotal->put(mCGuest->getPageTotal());
    647     }
    648 }
     856        mCGuest->invalidate(GUESTSTATS_RAMUSAGE);
     857    }
     858}
     859
     860int GuestRamUsage::enable()
     861{
     862    int rc = mCGuest->enable(GUESTSTATS_RAMUSAGE);
     863    BaseMetric::enable();
     864    return rc;
     865}
     866
     867int GuestRamUsage::disable()
     868{
     869    BaseMetric::disable();
     870    return mCGuest->disable(GUESTSTATS_RAMUSAGE);
     871}
     872
     873void GuestRamUsage::preCollect(CollectorHints& hints,  uint64_t /* iTick */)
     874{
     875    hints.collectGuestStats(mCGuest->getProcess());
     876}
     877#endif /* !VBOX_COLLECTOR_TEST_CASE */
    649878
    650879void CircularBuffer::init(ULONG ulLength)
  • trunk/src/VBox/Main/src-server/PerformanceImpl.cpp

    r37423 r40358  
    139139////////////////////////////////////////////////////////////////////////////////
    140140
    141 PerformanceCollector::PerformanceCollector() : mMagic(0) {}
     141PerformanceCollector::PerformanceCollector()
     142  : mMagic(0), mUnknownGuest("unknown guest")
     143{
     144}
    142145
    143146PerformanceCollector::~PerformanceCollector() {}
     
    299302}
    300303
     304const Utf8Str& PerformanceCollector::getFailedGuestName()
     305{
     306    pm::CollectorGuest *pGuest = m.gm->getBlockedGuest();
     307    if (pGuest)
     308        return pGuest->getVMName();
     309    return mUnknownGuest;
     310}
     311
    301312STDMETHODIMP PerformanceCollector::GetMetrics(ComSafeArrayIn(IN_BSTR, metricNames),
    302313                                              ComSafeArrayIn(IUnknown *, objects),
     
    367378                LogFlow (("PerformanceCollector::SetupMetrics() disabling %s\n",
    368379                          (*it)->getName()));
    369                 (*it)->disable();
     380                rc = (*it)->disable();
     381                if (FAILED(rc))
     382                    break;
    370383            }
    371384            else
     
    373386                LogFlow (("PerformanceCollector::SetupMetrics() enabling %s\n",
    374387                          (*it)->getName()));
    375                 (*it)->enable();
     388                rc = (*it)->enable();
     389                if (FAILED(rc))
     390                    break;
    376391            }
    377392            filteredMetrics.push_back(*it);
     
    386401
    387402    LogFlowThisFuncLeave();
     403
     404    if (FAILED(rc))
     405        return setError(E_FAIL, "Failed to setup metrics for '%s'",
     406                        getFailedGuestName().c_str());
    388407    return rc;
    389408}
     
    409428        if (filter.match((*it)->getObject(), (*it)->getName()))
    410429        {
    411             (*it)->enable();
     430            rc = (*it)->enable();
     431            if (FAILED(rc))
     432                break;
    412433            filteredMetrics.push_back(*it);
    413434        }
     
    421442
    422443    LogFlowThisFuncLeave();
     444
     445    if (FAILED(rc))
     446        return setError(E_FAIL, "Failed to enable metrics for '%s'",
     447                        getFailedGuestName().c_str());
    423448    return rc;
    424449}
     
    444469        if (filter.match((*it)->getObject(), (*it)->getName()))
    445470        {
    446             (*it)->disable();
     471            rc = (*it)->disable();
     472            if (FAILED(rc))
     473                break;
    447474            filteredMetrics.push_back(*it);
    448475        }
     
    456483
    457484    LogFlowThisFuncLeave();
     485
     486    if (FAILED(rc))
     487        return setError(E_FAIL, "Failed to disable metrics for '%s'",
     488                        getFailedGuestName().c_str());
    458489    return rc;
    459490}
     
    694725    /* Let know the platform specific code what is being collected */
    695726    m.hal->preCollect(hints, iTick);
     727#if 0
     728    /* Guest stats are now pushed by guests themselves */
    696729    /* Collect the data in bulk from all hinted guests */
    697730    m.gm->preCollect(hints, iTick);
     731#endif
    698732
    699733    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
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