Changeset 36128 in vbox
- Timestamp:
- Mar 2, 2011 5:44:04 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 70296
- Location:
- trunk/src/VBox/Main
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r36099 r36128 14484 14484 <li>CPU/MHz</li> 14485 14485 <li>RAM/Usage</li> 14486 <li>RAM/VMM</li> 14486 14487 </ul> 14487 14488 -
trunk/src/VBox/Main/include/MachineImpl.h
r36082 r36128 860 860 void registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid); 861 861 862 pm::CollectorGuest HAL *mGuestHAL;862 pm::CollectorGuest *mCollectorGuest; 863 863 #endif /* VBOX_WITH_RESOURCE_USAGE_API */ 864 864 -
trunk/src/VBox/Main/include/Performance.h
r36036 r36128 73 73 74 74 75 /* Collector Hardware Abstraction Layer *********************************/76 75 enum { 77 76 COLLECT_NONE = 0x0, 78 77 COLLECT_CPU_LOAD = 0x1, 79 COLLECT_RAM_USAGE = 0x2 78 COLLECT_RAM_USAGE = 0x2, 79 COLLECT_GUEST_STATS = 0x4 80 80 }; 81 81 typedef int HintFlags; … … 92 92 void collectHostRamUsage() 93 93 { mHostFlags |= COLLECT_RAM_USAGE; } 94 void collectHostRamVmm() 95 { mHostFlags |= COLLECT_GUEST_STATS; } 94 96 void collectProcessCpuLoad(RTPROCESS process) 95 97 { findProcess(process).second |= COLLECT_CPU_LOAD; } 96 98 void collectProcessRamUsage(RTPROCESS process) 97 99 { findProcess(process).second |= COLLECT_RAM_USAGE; } 100 void collectGuestStats(RTPROCESS process) 101 { findProcess(process).second |= COLLECT_GUEST_STATS; } 98 102 bool isHostCpuLoadCollected() const 99 103 { return (mHostFlags & COLLECT_CPU_LOAD) != 0; } 100 104 bool isHostRamUsageCollected() const 101 105 { return (mHostFlags & COLLECT_RAM_USAGE) != 0; } 106 bool isHostRamVmmCollected() const 107 { return (mHostFlags & COLLECT_GUEST_STATS) != 0; } 102 108 bool isProcessCpuLoadCollected(RTPROCESS process) 103 109 { return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; } 104 110 bool isProcessRamUsageCollected(RTPROCESS process) 105 111 { return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; } 112 bool isGuestStatsCollected(RTPROCESS process) 113 { return (findProcess(process).second & COLLECT_GUEST_STATS) != 0; } 106 114 void getProcesses(std::vector<RTPROCESS>& processes) const 107 115 { … … 132 140 }; 133 141 142 /* Guest Collector Classes *********************************/ 143 class CollectorGuest 144 { 145 public: 146 CollectorGuest(Machine *machine, RTPROCESS process); 147 ~CollectorGuest(); 148 149 bool isEnabled() { return mEnabled; }; 150 bool isValid() { return mValid; }; 151 void invalidateStats() { mValid = false; }; 152 int updateStats(); 153 int enable(); 154 int disable(); 155 156 RTPROCESS getProcess() { return mProcess; }; 157 ULONG getCpuUser() { return mCpuUser; }; 158 ULONG getCpuKernel() { return mCpuKernel; }; 159 ULONG getCpuIdle() { return mCpuIdle; }; 160 ULONG getMemTotal() { return mMemTotal; }; 161 ULONG getMemFree() { return mMemFree; }; 162 ULONG getMemBalloon() { return mMemBalloon; }; 163 ULONG getMemShared() { return mMemShared; }; 164 ULONG getMemCache() { return mMemCache; }; 165 ULONG getPageTotal() { return mPageTotal; }; 166 ULONG getAllocVMM() { return mAllocVMM; }; 167 ULONG getFreeVMM() { return mFreeVMM; }; 168 ULONG getBalloonedVMM() { return mBalloonedVMM; }; 169 ULONG getSharedVMM() { return mSharedVMM; }; 170 171 private: 172 bool mEnabled; 173 bool mValid; 174 Machine *mMachine; 175 RTPROCESS mProcess; 176 ComPtr<IConsole> mConsole; 177 ComPtr<IGuest> mGuest; 178 ULONG mCpuUser; 179 ULONG mCpuKernel; 180 ULONG mCpuIdle; 181 ULONG mMemTotal; 182 ULONG mMemFree; 183 ULONG mMemBalloon; 184 ULONG mMemShared; 185 ULONG mMemCache; 186 ULONG mPageTotal; 187 ULONG mAllocVMM; 188 ULONG mFreeVMM; 189 ULONG mBalloonedVMM; 190 ULONG mSharedVMM; 191 }; 192 193 typedef std::list<CollectorGuest*> CollectorGuestList; 194 class CollectorGuestManager 195 { 196 public: 197 CollectorGuestManager() : mVMMStatsProvider(NULL) {}; 198 void registerGuest(CollectorGuest* pGuest); 199 void unregisterGuest(CollectorGuest* pGuest); 200 CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; }; 201 void preCollect(CollectorHints& hints, uint64_t iTick); 202 private: 203 CollectorGuestList mGuests; 204 CollectorGuest *mVMMStatsProvider; 205 }; 206 207 /* Collector Hardware Abstraction Layer *********************************/ 134 208 class CollectorHAL 135 209 { 136 210 public: 137 CollectorHAL() : mMemAllocVMM(0), mMemFreeVMM(0), mMemBalloonedVMM(0), mMemSharedVMM(0){};211 CollectorHAL() {}; 138 212 virtual ~CollectorHAL() { }; 139 213 virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; } … … 153 227 /** Returns process' CPU usage counter in platform-specific units. */ 154 228 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total); 155 156 /** Enable metrics collecting (if applicable) */157 virtual int enable();158 /** Disable metrics collecting (if applicable) */159 virtual int disable();160 161 virtual int setMemHypervisorStats(ULONG memAlloc, ULONG memFree, ULONG memBallooned, ULONG memShared)162 {163 mMemAllocVMM = memAlloc;164 mMemFreeVMM = memFree;165 mMemBalloonedVMM = memBallooned;166 mMemSharedVMM = memShared;167 return S_OK;168 }169 170 virtual void getMemHypervisorStats(ULONG *pMemAlloc, ULONG *pMemFree, ULONG *pMemBallooned, ULONG *pMemShared)171 {172 *pMemAlloc = mMemAllocVMM;173 *pMemFree = mMemFreeVMM;174 *pMemBallooned = mMemBalloonedVMM;175 *pMemShared = mMemSharedVMM;176 }177 178 private:179 ULONG mMemAllocVMM;180 ULONG mMemFreeVMM;181 ULONG mMemBalloonedVMM;182 ULONG mMemSharedVMM;183 };184 185 class CollectorGuestHAL : public CollectorHAL186 {187 public:188 CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL);189 ~CollectorGuestHAL();190 191 virtual int preCollect(const CollectorHints& hints, uint64_t iTick);192 193 /** Enable metrics collecting (if applicable) */194 virtual int enable();195 /** Disable metrics collecting (if applicable) */196 virtual int disable();197 198 /** Return guest cpu absolute load values (0-100). */199 void getGuestCpuLoad(ULONG *pulCpuUser, ULONG *pulCpuKernel, ULONG *pulCpuIdle)200 {201 *pulCpuUser = mCpuUser;202 *pulCpuKernel = mCpuKernel;203 *pulCpuIdle = mCpuIdle;204 }205 206 /** Return guest memory information in KB. */207 void getGuestMemLoad(ULONG *pulMemTotal, ULONG *pulMemFree, ULONG *pulMemBalloon, ULONG *pulMemShared, ULONG *pulMemCache, ULONG *pulPageTotal)208 {209 *pulMemTotal = mMemTotal;210 *pulMemFree = mMemFree;211 *pulMemBalloon = mMemBalloon;212 *pulMemShared = mMemShared;213 *pulMemCache = mMemCache;214 *pulPageTotal = mPageTotal;215 }216 217 218 protected:219 uint32_t cEnabled;220 Machine *mMachine;221 ComPtr<IConsole> mConsole;222 ComPtr<IGuest> mGuest;223 uint64_t mLastTick;224 225 CollectorHAL *mHostHAL;226 227 ULONG mCpuUser;228 ULONG mCpuKernel;229 ULONG mCpuIdle;230 ULONG mMemTotal;231 ULONG mMemFree;232 ULONG mMemBalloon;233 ULONG mMemShared;234 ULONG mMemCache;235 ULONG mPageTotal;236 237 private:238 static uint32_t cVMsEnabled;239 229 }; 240 230 … … 259 249 bool collectorBeat(uint64_t nowAt); 260 250 261 void enable() 262 { 263 mEnabled = true; 264 mHAL->enable(); 265 }; 266 void disable() 267 { 268 mHAL->disable(); 269 mEnabled = false; 270 }; 251 void enable() { mEnabled = true; }; 252 void disable() { mEnabled = false; }; 271 253 272 254 bool isEnabled() { return mEnabled; }; … … 287 269 }; 288 270 271 class BaseGuestMetric : public BaseMetric 272 { 273 public: 274 BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object) 275 : BaseMetric(NULL, name, object), mCGuest(cguest) {}; 276 protected: 277 CollectorGuest *mCGuest; 278 }; 279 289 280 class HostCpuLoad : public BaseMetric 290 281 { … … 363 354 { 364 355 public: 365 HostRamVmm(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM) 366 : BaseMetric(hal, "RAM/VMM", object), mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM) {}; 356 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM) 357 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm), 358 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM), 359 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {}; 367 360 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; }; 368 361 … … 374 367 ULONG getMaxValue() { return INT32_MAX; }; 375 368 ULONG getScale() { return 1; } 376 private: 377 SubMetric *mAllocVMM; 378 SubMetric *mFreeVMM; 379 SubMetric *mBalloonVMM; 380 SubMetric *mSharedVMM; 369 370 private: 371 CollectorGuestManager *mCollectorGuestManager; 372 SubMetric *mAllocVMM; 373 SubMetric *mFreeVMM; 374 SubMetric *mBalloonVMM; 375 SubMetric *mSharedVMM; 376 ULONG mAllocCurrent; 377 ULONG mFreeCurrent; 378 ULONG mBalloonedCurrent; 379 ULONG mSharedCurrent; 381 380 }; 382 381 … … 434 433 435 434 436 class GuestCpuLoad : public Base Metric437 { 438 public: 439 GuestCpuLoad(CollectorGuest HAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)440 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle), mGuestHAL(hal) {};435 class GuestCpuLoad : public BaseGuestMetric 436 { 437 public: 438 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle) 439 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {}; 441 440 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; }; 442 441 … … 452 451 SubMetric *mKernel; 453 452 SubMetric *mIdle; 454 CollectorGuestHAL *mGuestHAL; 455 }; 456 457 class GuestRamUsage : public BaseMetric 458 { 459 public: 460 GuestRamUsage(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal) 461 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared), mGuestHAL(hal) {}; 453 }; 454 455 class GuestRamUsage : public BaseGuestMetric 456 { 457 public: 458 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal) 459 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {}; 462 460 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; }; 463 461 … … 471 469 private: 472 470 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared; 473 CollectorGuestHAL *mGuestHAL;474 471 }; 475 472 -
trunk/src/VBox/Main/include/PerformanceImpl.h
r35638 r36128 36 36 class BaseMetric; 37 37 class CollectorHAL; 38 class CollectorGuest; 39 class CollectorGuestManager; 38 40 } 39 41 … … 174 176 void unregisterBaseMetricsFor (const ComPtr<IUnknown> &object); 175 177 void unregisterMetricsFor (const ComPtr<IUnknown> &object); 178 void registerGuest(pm::CollectorGuest* pGuest); 179 void unregisterGuest(pm::CollectorGuest* pGuest); 176 180 177 181 void suspendSampling(); … … 181 185 // (ensure there is a caller and a read lock before calling them!) 182 186 183 pm::CollectorHAL *getHAL() { return m.hal; }; 187 pm::CollectorHAL *getHAL() { return m.hal; }; 188 pm::CollectorGuestManager *getGuestManager() { return m.gm; }; 184 189 185 190 private: … … 204 209 Data() : hal(0) {}; 205 210 206 BaseMetricList baseMetrics; 207 MetricList metrics; 208 RTTIMERLR sampler; 209 pm::CollectorHAL *hal; 211 BaseMetricList baseMetrics; 212 MetricList metrics; 213 RTTIMERLR sampler; 214 pm::CollectorHAL *hal; 215 pm::CollectorGuestManager *gm; 210 216 }; 211 217 -
trunk/src/VBox/Main/src-client/GuestImpl.cpp
r36069 r36128 392 392 *aMemSharedTotal = (ULONG)(uSharedTotal / _1K); 393 393 } 394 else 395 return E_FAIL; 394 396 395 397 /* Query the missing per-VM memory statistics. */ … … 401 403 *aMemShared = (ULONG)(uSharedMem / _1K); 402 404 } 405 else 406 return E_FAIL; 403 407 } 404 408 else … … 409 413 *aMemSharedTotal = 0; 410 414 *aMemShared = 0; 415 return E_FAIL; 411 416 } 412 417 -
trunk/src/VBox/Main/src-server/HostImpl.cpp
r36121 r36128 2794 2794 ramUsageFree); 2795 2795 aCollector->registerBaseMetric (ramUsage); 2796 pm::BaseMetric *ramVmm = new pm::HostRamVmm( hal, objptr,2796 pm::BaseMetric *ramVmm = new pm::HostRamVmm(aCollector->getGuestManager(), objptr, 2797 2797 ramVMMUsed, 2798 2798 ramVMMFree, -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r36091 r36128 227 227 228 228 Machine::Machine() 229 : m GuestHAL(NULL),229 : mCollectorGuest(NULL), 230 230 mPeer(NULL), 231 231 mParent(NULL) … … 10067 10067 10068 10068 10069 /* Guest metrics */ 10070 mGuestHAL = new pm::CollectorGuestHAL(this, hal); 10069 /* Guest metrics collector */ 10070 mCollectorGuest = new pm::CollectorGuest(aMachine, pid); 10071 aCollector->registerGuest(mCollectorGuest); 10072 LogAleksey(("{%p} " LOG_FN_FMT ": mCollectorGuest=%p\n", 10073 this, __PRETTY_FUNCTION__, mCollectorGuest)); 10071 10074 10072 10075 /* Create sub metrics */ … … 10088 10091 10089 10092 /* Create and register base metrics */ 10090 pm::BaseMetric *guestCpuLoad = new pm::GuestCpuLoad(mGuestHAL, aMachine, guestLoadUser, guestLoadKernel, guestLoadIdle); 10093 pm::BaseMetric *guestCpuLoad = new pm::GuestCpuLoad(mCollectorGuest, aMachine, 10094 guestLoadUser, guestLoadKernel, guestLoadIdle); 10091 10095 aCollector->registerBaseMetric(guestCpuLoad); 10092 10096 10093 pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mGuestHAL, aMachine, guestMemTotal, guestMemFree, guestMemBalloon, guestMemShared, 10097 pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mCollectorGuest, aMachine, 10098 guestMemTotal, guestMemFree, 10099 guestMemBalloon, guestMemShared, 10094 10100 guestMemCache, guestPagedTotal); 10095 10101 aCollector->registerBaseMetric(guestCpuMem); … … 10149 10155 aCollector->unregisterMetricsFor(aMachine); 10150 10156 aCollector->unregisterBaseMetricsFor(aMachine); 10151 }10152 10153 if (mGuestHAL)10154 {10155 delete mGuestHAL;10156 mGuestHAL = NULL;10157 10157 } 10158 10158 } … … 10465 10465 AutoMultiWriteLock3 multilock(mParent, mParent->host(), this COMMA_LOCKVAL_SRC_POS); 10466 10466 10467 LogAleksey(("{%p} " LOG_FN_FMT ": mCollectorGuest=%p\n", 10468 this, __PRETTY_FUNCTION__, mCollectorGuest)); 10469 if (mCollectorGuest) 10470 { 10471 mParent->performanceCollector()->unregisterGuest(mCollectorGuest); 10472 delete mCollectorGuest; 10473 mCollectorGuest = NULL; 10474 } 10467 10475 // Trigger async cleanup tasks, avoid doing things here which are not 10468 10476 // vital to be done immediately and maybe need more locks. This calls -
trunk/src/VBox/Main/src-server/Performance.cpp
r36070 r36128 76 76 } 77 77 78 int CollectorHAL::enable()79 {80 return E_NOTIMPL;81 }82 83 int CollectorHAL::disable()84 {85 return E_NOTIMPL;86 }87 88 78 /* Generic implementations */ 89 79 … … 121 111 #ifndef VBOX_COLLECTOR_TEST_CASE 122 112 123 uint32_t CollectorGuestHAL::cVMsEnabled = 0; 124 125 CollectorGuestHAL::CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL) 126 : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL), 127 mGuest(NULL), mLastTick(0), mHostHAL(hostHAL), mCpuUser(0), 128 mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0), 129 mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0) 113 CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) : 114 mEnabled(false), mValid(false), mMachine(machine), mProcess(process), 115 mCpuUser(0), mCpuKernel(0), mCpuIdle(0), 116 mMemTotal(0), mMemFree(0), mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0), 117 mAllocVMM(0), mFreeVMM(0), mBalloonedVMM(0), mSharedVMM(0) 130 118 { 131 119 Assert(mMachine); … … 134 122 } 135 123 136 CollectorGuest HAL::~CollectorGuestHAL()124 CollectorGuest::~CollectorGuest() 137 125 { 138 126 /* cannot use ComObjPtr<Machine> in Performance.h, do it manually */ 139 127 mMachine->Release(); 140 Assert(!cEnabled); 141 } 142 143 int CollectorGuestHAL::enable() 144 { 128 // Assert(!cEnabled); why? 129 } 130 131 int CollectorGuest::enable() 132 { 133 mEnabled = true; 145 134 /* Must make sure that the machine object does not get uninitialized 146 135 * in the middle of enabling this collector. Causes timing-related … … 154 143 HRESULT ret = S_OK; 155 144 156 if (ASMAtomicIncU32(&cEnabled) == 1) 157 { 158 ASMAtomicIncU32(&cVMsEnabled); 159 ComPtr<IInternalSessionControl> directControl; 160 161 ret = mMachine->getDirectControl(&directControl); 162 if (ret != S_OK) 163 return ret; 164 165 /* get the associated console; this is a remote call (!) */ 166 ret = directControl->GetRemoteConsole(mConsole.asOutParam()); 167 if (ret != S_OK) 168 return ret; 169 170 ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam()); 171 if (ret == S_OK) 172 mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */); 173 } 145 ComPtr<IInternalSessionControl> directControl; 146 147 ret = mMachine->getDirectControl(&directControl); 148 if (ret != S_OK) 149 return ret; 150 151 /* get the associated console; this is a remote call (!) */ 152 ret = directControl->GetRemoteConsole(mConsole.asOutParam()); 153 if (ret != S_OK) 154 return ret; 155 156 ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam()); 157 if (ret == S_OK) 158 { 159 ret = mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */); 160 LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 1 sec (%s)\n", 161 this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed")); 162 } 163 174 164 return ret; 175 165 } 176 166 177 int CollectorGuestHAL::disable() 178 { 179 if (ASMAtomicDecU32(&cEnabled) == 0) 180 { 181 if (ASMAtomicDecU32(&cVMsEnabled) == 0) 182 { 183 if (mHostHAL) 184 mHostHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */); 185 } 186 Assert(mGuest && mConsole); 187 mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */); 188 } 167 int CollectorGuest::disable() 168 { 169 mEnabled = false; 170 Assert(mGuest && mConsole); 171 HRESULT ret = mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */); 172 LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n", 173 this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed")); 174 invalidateStats(); 175 189 176 return S_OK; 190 177 } 191 178 192 int CollectorGuestHAL::preCollect(const CollectorHints& /* hints */, uint64_t iTick) 193 { 194 if ( mGuest 195 && iTick != mLastTick) 196 { 197 ULONG ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal; 198 199 mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle, 200 &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache, 201 &mPageTotal, &ulMemAllocTotal, &ulMemFreeTotal, &ulMemBalloonTotal, &ulMemSharedTotal); 202 203 if (mHostHAL) 204 mHostHAL->setMemHypervisorStats(ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal); 205 206 mLastTick = iTick; 207 } 179 int CollectorGuest::updateStats() 180 { 181 if (mGuest) 182 { 183 HRESULT rc; 184 rc = mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle, 185 &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache, 186 &mPageTotal, &mAllocVMM, &mFreeVMM, &mBalloonedVMM, &mSharedVMM); 187 if (SUCCEEDED(rc)) 188 { 189 mValid = true; 190 } 191 LogAleksey(("{%p} " LOG_FN_FMT ": mValid=%s mCpuUser=%u mCpuKernel=%u mCpuIdle=%u\n" 192 "mMemTotal=%u mMemFree=%u mMemBalloon=%u mMemShared=%u mMemCache=%u\n" 193 "mPageTotal=%u mAllocVMM=%u mFreeVMM=%u mBalloonedVMM=%u mSharedVMM=%u\n", 194 this, __PRETTY_FUNCTION__, mValid?"y":"n", 195 mCpuUser, mCpuKernel, mCpuIdle, 196 mMemTotal, mMemFree, mMemBalloon, mMemShared, mMemCache, 197 mPageTotal, mAllocVMM, mFreeVMM, mBalloonedVMM, mSharedVMM)); 198 } 199 208 200 return S_OK; 209 201 } 202 203 void CollectorGuestManager::preCollect(CollectorHints& hints, uint64_t /* iTick */) 204 { 205 CollectorGuestList::iterator it; 206 207 LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p ramvmm=%s\n", 208 this, __PRETTY_FUNCTION__, mVMMStatsProvider, hints.isHostRamVmmCollected()?"y":"n")); 209 for (it = mGuests.begin(); it != mGuests.end(); it++) 210 { 211 LogAleksey(("{%p} " LOG_FN_FMT ": it=%p pid=%d gueststats=%s...\n", 212 this, __PRETTY_FUNCTION__, *it, (*it)->getProcess(), 213 hints.isGuestStatsCollected((*it)->getProcess())?"y":"n")); 214 if ( (hints.isHostRamVmmCollected() && *it == mVMMStatsProvider) 215 || hints.isGuestStatsCollected((*it)->getProcess())) 216 { 217 /* Guest stats collection needs to be enabled */ 218 if ((*it)->isEnabled()) 219 { 220 /* Already enabled, collect the data */ 221 (*it)->updateStats(); 222 } 223 else 224 { 225 (*it)->invalidateStats(); 226 (*it)->enable(); 227 } 228 } 229 else 230 { 231 /* Guest stats collection needs to be disabled */ 232 if ((*it)->isEnabled()) 233 (*it)->disable(); 234 } 235 } 236 } 237 238 void CollectorGuestManager::registerGuest(CollectorGuest* pGuest) 239 { 240 mGuests.push_back(pGuest); 241 /* 242 * If no VMM stats provider was elected previously than this is our 243 * candidate. 244 */ 245 if (!mVMMStatsProvider) 246 mVMMStatsProvider = pGuest; 247 LogAleksey(("{%p} " LOG_FN_FMT ": Registered guest=%p provider=%p\n", 248 this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider)); 249 } 250 251 void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest) 252 { 253 LogAleksey(("{%p} " LOG_FN_FMT ": About to unregister guest=%p provider=%p\n", 254 this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider)); 255 mGuests.remove(pGuest); 256 LogAleksey(("{%p} " LOG_FN_FMT ": Number of guests after remove is %d\n", 257 this, __PRETTY_FUNCTION__, mGuests.size())); 258 if (pGuest == mVMMStatsProvider) 259 { 260 /* This was our VMM stats provider, it is time to re-elect */ 261 if (mGuests.empty()) 262 { 263 /* Nobody can provide VMM stats */ 264 mVMMStatsProvider = NULL; 265 } 266 else 267 { 268 /* First let's look for a guest already collecting stats */ 269 CollectorGuestList::iterator it; 270 271 for (it = mGuests.begin(); it != mGuests.end(); it++) 272 if ((*it)->isEnabled()) 273 { 274 /* Found one, elect it */ 275 mVMMStatsProvider = *it; 276 LogAleksey(("{%p} " LOG_FN_FMT ": LEAVE new provider=%p\n", 277 this, __PRETTY_FUNCTION__, mVMMStatsProvider)); 278 return; 279 } 280 281 /* Nobody collects stats, take the first one */ 282 mVMMStatsProvider = mGuests.front(); 283 } 284 } 285 LogAleksey(("{%p} " LOG_FN_FMT ": LEAVE new provider=%p\n", 286 this, __PRETTY_FUNCTION__, mVMMStatsProvider)); 287 } 288 210 289 211 290 #endif /* !VBOX_COLLECTOR_TEST_CASE */ … … 225 304 return false; 226 305 } 227 228 /*bool BaseMetric::associatedWith(ComPtr<IUnknown> object)229 {230 LogFlowThisFunc(("mObject(%p) == object(%p) is %s.\n", mObject, object, mObject == object ? "true" : "false"));231 return mObject == object;232 }*/233 306 234 307 void HostCpuLoad::init(ULONG period, ULONG length) … … 345 418 } 346 419 347 void HostRamVmm::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) 348 { 349 /* 350 * This is an ugly ugly hack to force VMM metrics to 0s if no VM is 351 * running. The reason it should work is that the VMM stats are 352 * stored in CollectorHAL in preCollect methods of guest base metrics 353 * which are always added after HostRamVmm. So each pass of collector 354 * first clears the metrics then gets new values. 355 */ 356 mHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */); 420 void HostRamVmm::preCollect(CollectorHints& hints, uint64_t /* iTick */) 421 { 422 hints.collectHostRamVmm(); 357 423 } 358 424 359 425 void HostRamVmm::collect() 360 426 { 361 ULONG allocVMM, freeVMM, balloonVMM, sharedVMM; 362 363 mHAL->getMemHypervisorStats(&allocVMM, &freeVMM, &balloonVMM, &sharedVMM); 364 mAllocVMM->put(allocVMM); 365 mFreeVMM->put(freeVMM); 366 mBalloonVMM->put(balloonVMM); 367 mSharedVMM->put(sharedVMM); 427 CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider(); 428 if (provider) 429 { 430 LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p enabled=%s valid=%s...\n", 431 this, __PRETTY_FUNCTION__, provider, provider->isEnabled()?"y":"n", 432 provider->isValid()?"y":"n")); 433 if (provider->isValid()) 434 { 435 /* Provider is ready, get updated stats */ 436 mAllocCurrent = provider->getAllocVMM(); 437 mFreeCurrent = provider->getFreeVMM(); 438 mBalloonedCurrent = provider->getBalloonedVMM(); 439 mSharedCurrent = provider->getSharedVMM(); 440 } 441 } 442 else 443 { 444 mAllocCurrent = 0; 445 mFreeCurrent = 0; 446 mBalloonedCurrent = 0; 447 mSharedCurrent = 0; 448 } 449 LogAleksey(("{%p} " LOG_FN_FMT ": mAllocCurrent=%u mFreeCurrent=%u mBalloonedCurrent=%u mSharedCurrent=%u\n", 450 this, __PRETTY_FUNCTION__, 451 mAllocCurrent, mFreeCurrent, mBalloonedCurrent, mSharedCurrent)); 452 mAllocVMM->put(mAllocCurrent); 453 mFreeVMM->put(mFreeCurrent); 454 mBalloonVMM->put(mBalloonedCurrent); 455 mSharedVMM->put(mSharedCurrent); 368 456 } 369 457 … … 450 538 } 451 539 452 void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t iTick)453 { 454 mHAL->preCollect(hints, iTick);540 void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t /* iTick */) 541 { 542 hints.collectGuestStats(mCGuest->getProcess()); 455 543 } 456 544 457 545 void GuestCpuLoad::collect() 458 546 { 459 ULONG CpuUser = 0, CpuKernel = 0, CpuIdle = 0;460 461 mGuestHAL->getGuestCpuLoad(&CpuUser, &CpuKernel, &CpuIdle);462 mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuUser) / 100);463 mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuKernel) / 100);464 mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * CpuIdle) / 100);547 if (mCGuest->isValid()) 548 { 549 mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuUser()) / 100); 550 mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuKernel()) / 100); 551 mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuIdle()) / 100); 552 } 465 553 } 466 554 … … 478 566 } 479 567 480 void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t iTick)481 { 482 mHAL->preCollect(hints, iTick);568 void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t /* iTick */) 569 { 570 hints.collectGuestStats(mCGuest->getProcess()); 483 571 } 484 572 485 573 void GuestRamUsage::collect() 486 574 { 487 ULONG ulMemTotal = 0, ulMemFree = 0, ulMemBalloon = 0, ulMemShared = 0, ulMemCache = 0, ulPageTotal = 0;488 489 mGuestHAL->getGuestMemLoad(&ulMemTotal, &ulMemFree, &ulMemBalloon, &ulMemShared, &ulMemCache, &ulPageTotal);490 mTotal->put(ulMemTotal);491 mFree->put(ulMemFree);492 mBallooned->put(ulMemBalloon);493 mShared->put(ulMemShared);494 mCache->put(ulMemCache);495 mPagedTotal->put(ulPageTotal);575 if (mCGuest->isValid()) 576 { 577 mTotal->put(mCGuest->getMemTotal()); 578 mFree->put(mCGuest->getMemFree()); 579 mBallooned->put(mCGuest->getMemBalloon()); 580 mShared->put(mCGuest->getMemShared()); 581 mCache->put(mCGuest->getMemCache()); 582 mPagedTotal->put(mCGuest->getPageTotal()); 583 } 496 584 } 497 585 … … 792 880 ElementList::const_iterator it; 793 881 794 LogAleksey(("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str()));882 //LogAleksey(("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str())); 795 883 for (it = mElements.begin(); it != mElements.end(); it++) 796 884 { 797 LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str()));885 //LogAleksey(("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str())); 798 886 if ((*it).first.isNull() || (*it).first == object) 799 887 { … … 806 894 } 807 895 } 808 LogAleksey(("...no matches!\n"));896 //LogAleksey(("...no matches!\n")); 809 897 return false; 810 898 } -
trunk/src/VBox/Main/src-server/PerformanceImpl.cpp
r35638 r36128 159 159 160 160 m.hal = pm::createHAL(); 161 m.gm = new pm::CollectorGuestManager; 161 162 162 163 /* Let the sampler know it gets a valid collector. */ … … 208 209 //m.factory = NULL; 209 210 211 delete m.gm; 212 m.gm = NULL; 210 213 delete m.hal; 211 214 m.hal = NULL; … … 565 568 } 566 569 570 void PerformanceCollector::registerGuest(pm::CollectorGuest* pGuest) 571 { 572 AutoCaller autoCaller(this); 573 if (!SUCCEEDED(autoCaller.rc())) return; 574 575 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 576 m.gm->registerGuest(pGuest); 577 } 578 579 void PerformanceCollector::unregisterGuest(pm::CollectorGuest* pGuest) 580 { 581 AutoCaller autoCaller(this); 582 if (!SUCCEEDED(autoCaller.rc())) return; 583 584 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 585 m.gm->unregisterGuest(pGuest); 586 } 587 567 588 void PerformanceCollector::suspendSampling() 568 589 { … … 600 621 } 601 622 623 /* 624 * Metrics collection is a three stage process: 625 * 1) Pre-collection (hinting) 626 * At this stage we compose the list of all metrics to be collected 627 * If any metrics cannot be collected separately or if it is more 628 * efficient to collect several metric at once, these metrics should 629 * use hints to mark that they will need to be collected. 630 * 2) Pre-collection (bulk) 631 * Using hints set at stage 1 platform-specific HAL 632 * instance collects all marked host-related metrics. 633 * Hinted guest-related metrics then get collected by CollectorGuestManager. 634 * 3) Collection 635 * Metrics that are collected individually get collected and stored. Values 636 * saved in HAL and CollectorGuestManager are extracted and stored to 637 * individual metrics. 638 */ 602 639 void PerformanceCollector::samplerCallback(uint64_t iTick) 603 640 { … … 618 655 619 656 if (toBeCollected.size() == 0) 657 { 658 Log4(("{%p} " LOG_FN_FMT ": LEAVE (nothing to collect)\n", this, __PRETTY_FUNCTION__)); 620 659 return; 660 } 621 661 622 662 /* Let know the platform specific code what is being collected */ 623 663 m.hal->preCollect(hints, iTick); 664 /* Collect the data in bulk from all hinted guests */ 665 m.gm->preCollect(hints, iTick); 624 666 625 667 /* Finally, collect the data */ -
trunk/src/VBox/Main/testcase/tstAPI.cpp
r33595 r36128 1222 1222 1223 1223 // Fill base metrics array 1224 Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" }; 1224 //Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" }; 1225 Bstr baseMetricNames[] = { L"RAM/VMM" }; 1225 1226 com::SafeArray<BSTR> baseMetrics(1); 1226 1227 baseMetricNames[0].cloneTo(&baseMetrics[0]); … … 1235 1236 Bstr sessionType = argc > 2 ? argv[2] : "headless"; 1236 1237 RTPrintf("Getting a machine object named '%ls'...\n", name.raw()); 1237 CHECK_ RC_BREAK(virtualBox->FindMachine(name, machine.asOutParam()));1238 CHECK_ERROR_BREAK(virtualBox, FindMachine(name.raw(), machine.asOutParam())); 1238 1239 1239 1240 // Open session 1240 Guid guid;1241 CHECK_RC_BREAK(machine->COMGETTER(Id)(guid.asOutParam()));1242 RTPrintf("Opening a remote session for this machine...\n");1243 1241 ComPtr<IProgress> progress; 1244 CHECK_RC_BREAK(virtualBox->OpenRemoteSession(session, guid, sessionType, 1245 NULL, progress.asOutParam())); 1246 RTPrintf("Waiting for the session to open...\n"); 1247 CHECK_RC_BREAK(progress->WaitForCompletion(-1)); 1248 ComPtr<IMachine> sessionMachine; 1249 RTPrintf("Getting machine session object...\n"); 1250 CHECK_RC_BREAK(session->COMGETTER(Machine)(sessionMachine.asOutParam())); 1242 RTPrintf("Launching VM process...\n"); 1243 CHECK_ERROR_BREAK(machine, LaunchVMProcess(session, sessionType.raw(), 1244 NULL, progress.asOutParam())); 1245 RTPrintf("Waiting for the VM to power on...\n"); 1246 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1)); 1247 1248 // ComPtr<IMachine> sessionMachine; 1249 // RTPrintf("Getting machine session object...\n"); 1250 // CHECK_ERROR_BREAK(session, COMGETTER(Machine)(sessionMachine.asOutParam())); 1251 1251 1252 1252 // Setup base metrics 1253 1253 // Note that one needs to set up metrics after a session is open for a machine. 1254 1254 com::SafeIfaceArray<IPerformanceMetric> affectedMetrics; 1255 com::SafeIfaceArray<IUnknown> objects( 2);1255 com::SafeIfaceArray<IUnknown> objects(1); 1256 1256 host.queryInterfaceTo(&objects[0]); 1257 machine.queryInterfaceTo(&objects[1]);1257 //machine.queryInterfaceTo(&objects[1]); 1258 1258 CHECK_ERROR_BREAK(collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics), 1259 1259 ComSafeArrayAsInParam(objects), 1u, 10u, … … 1266 1266 ComPtr<IConsole> console; 1267 1267 RTPrintf("Getting console object...\n"); 1268 CHECK_ RC_BREAK(session->COMGETTER(Console)(console.asOutParam()));1268 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam())); 1269 1269 1270 1270 RTThreadSleep(5000); // Sleep for 5 seconds … … 1276 1276 //RTPrintf("Press enter to pause the VM execution in the remote session..."); 1277 1277 //getchar(); 1278 CHECK_ RC(console->Pause());1278 CHECK_ERROR_BREAK(console, Pause()); 1279 1279 1280 1280 RTThreadSleep(5000); // Sleep for 5 seconds … … 1321 1321 RTPrintf("Press enter to power off VM..."); 1322 1322 getchar(); 1323 CHECK_RC(console->PowerDown()); 1323 CHECK_ERROR_BREAK(console, PowerDown(progress.asOutParam())); 1324 RTPrintf("Waiting for the VM to power down...\n"); 1325 CHECK_ERROR_BREAK(progress, WaitForCompletion(-1)); 1324 1326 RTPrintf("Press enter to close this session..."); 1325 1327 getchar(); 1326 session-> Close();1328 session->UnlockMachine(); 1327 1329 } while (false); 1328 1330 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
Note:
See TracChangeset
for help on using the changeset viewer.