Changeset 36128 in vbox for trunk/src/VBox/Main/src-server
- Timestamp:
- Mar 2, 2011 5:44:04 AM (14 years ago)
- Location:
- trunk/src/VBox/Main/src-server
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
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 */
Note:
See TracChangeset
for help on using the changeset viewer.