Changeset 5254 in vbox
- Timestamp:
- Oct 12, 2007 12:46:15 AM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 25221
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/STAM.cpp
r5211 r5254 86 86 * Init record for a ring-0 statistic sample. 87 87 */ 88 typedef struct STAM INITR0SAMPLE88 typedef struct STAMR0SAMPLE 89 89 { 90 90 /** The VM structure offset of the variable. */ … … 98 98 /** The description. */ 99 99 const char *pszDesc; 100 } STAM INITR0SAMPLE;100 } STAMR0SAMPLE; 101 101 102 102 … … 114 114 static int stamR3PrintOne(PSTAMDESC pDesc, void *pvArg); 115 115 static int stamR3EnumOne(PSTAMDESC pDesc, void *pvArg); 116 static bool stamR3MultiMatch(const char * const *papszExpressions, unsigned cExpressions, unsigned *piExpression, const char *pszName); 117 static char **stamR3SplitPattern(const char *pszPat, unsigned *pcExpressions, char **ppszCopy); 116 118 static int stamR3Enum(PVM pVM, const char *pszPat, bool fUpdateRing0, int (pfnCallback)(PSTAMDESC pDesc, void *pvArg), void *pvArg); 117 119 static void stamR3Ring0StatsRegister(PVM pVM); … … 148 150 149 151 /** 150 * The GVMM initrecords.151 */ 152 static const STAM INITR0SAMPLE g_aGVMMStats[] =153 { 154 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltCalls), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/HaltCalls", "The number of calls to GVMMR0SchedHalt." },155 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltBlocking), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." },156 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltTimeouts), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." },157 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltNotBlocking), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." },158 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltWakeUps), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." },159 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpCalls), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/WakeUpCalls", "The number of calls to GVMMR0WakeUp." },160 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpNotHalted), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." },161 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpWakeUps), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." },162 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollCalls), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/PollCalls", "The number of calls to GVMMR0SchedPoll." },163 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollHalts), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." },164 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollWakeUps), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/VM/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." },165 166 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltCalls), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/HaltCalls", "The number of calls to GVMMR0SchedHalt." },167 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltBlocking), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." },168 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltTimeouts), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." },169 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltNotBlocking), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." },170 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltWakeUps), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." },171 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpCalls), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/WakeUpCalls", "The number of calls to GVMMR0WakeUp." },172 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpNotHalted), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." },173 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpWakeUps), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." },174 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollCalls), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/PollCalls", "The number of calls to GVMMR0SchedPoll." },175 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollHalts), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." },176 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollWakeUps), STAMTYPE_U64 , STAMUNIT_CALLS, "/GVMM/Sum/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." },177 178 { RT_UOFFSETOF(VM, stam.s.GVMMStats.cVMs), STAMTYPE_U32, STAMUNIT_CALLS, "/GVMM/VMs", "The number of VMs accessible to the caller." },152 * The GVMM mapping records. 153 */ 154 static const STAMR0SAMPLE g_aGVMMStats[] = 155 { 156 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltCalls", "The number of calls to GVMMR0SchedHalt." }, 157 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." }, 158 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltTimeouts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." }, 159 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltNotBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." }, 160 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cHaltWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." }, 161 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/WakeUpCalls", "The number of calls to GVMMR0WakeUp." }, 162 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpNotHalted), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." }, 163 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cWakeUpWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." }, 164 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PollCalls", "The number of calls to GVMMR0SchedPoll." }, 165 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollHalts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." }, 166 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedVM.cPollWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/VM/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." }, 167 168 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltCalls", "The number of calls to GVMMR0SchedHalt." }, 169 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltBlocking", "The number of times we did go to sleep in GVMMR0SchedHalt." }, 170 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltTimeouts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltTimeouts", "The number of times we timed out in GVMMR0SchedHalt." }, 171 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltNotBlocking), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltNotBlocking", "The number of times we didn't go to sleep in GVMMR0SchedHalt." }, 172 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cHaltWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/HaltWakeUps", "The number of wake ups done during GVMMR0SchedHalt." }, 173 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpCalls", "The number of calls to GVMMR0WakeUp." }, 174 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpNotHalted), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpNotHalted", "The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp was called." }, 175 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cWakeUpWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/WakeUpWakeUps", "The number of wake ups done during GVMMR0WakeUp (not counting the explicit one)." }, 176 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollCalls), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PollCalls", "The number of calls to GVMMR0SchedPoll." }, 177 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollHalts), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PollHalts", "The number of times the EMT has halted in a GVMMR0SchedPoll call." }, 178 { RT_UOFFSETOF(VM, stam.s.GVMMStats.SchedSum.cPollWakeUps), STAMTYPE_U64_RESET, STAMUNIT_CALLS, "/GVMM/Sum/PollWakeUps", "The number of wake ups done during GVMMR0SchedPoll." }, 179 180 { RT_UOFFSETOF(VM, stam.s.GVMMStats.cVMs), STAMTYPE_U32, STAMUNIT_CALLS, "/GVMM/VMs", "The number of VMs accessible to the caller." }, 179 181 }; 180 182 … … 464 466 */ 465 467 int rc; 466 int cchName = strlen(pszName) + 1;467 int cchDesc = pszDesc ? strlen(pszDesc) + 1 : 0;468 size_t cchName = strlen(pszName) + 1; 469 size_t cchDesc = pszDesc ? strlen(pszDesc) + 1 : 0; 468 470 PSTAMDESC pNew = (PSTAMDESC)RTMemAlloc(sizeof(*pNew) + cchName + cchDesc); 469 471 if (pNew) … … 556 558 * @param pszPat The name matching pattern. See somewhere_where_this_is_described_in_detail. 557 559 * If NULL all samples are reset. 560 * @remarks Don't confuse this with the other 'XYZR3Reset' methods, it's not called at VM reset. 558 561 */ 559 562 STAMR3DECL(int) STAMR3Reset(PVM pVM, const char *pszPat) 560 563 { 564 int rc = VINF_SUCCESS; 565 566 /* ring-0 */ 567 GVMMRESETSTATISTICSSREQ GVMMReq; 568 //GMMRESETSTATISTICSSREQ GMMReq; 569 bool fGVMMMatched = !pszPat || !*pszPat; 570 //bool fGMMMatched = fGVMMMatched; 571 if (fGVMMMatched) 572 memset(&GVMMReq.Stats, 0xff, sizeof(GVMMReq.Stats)); 573 else 574 { 575 char *pszCopy; 576 unsigned cExpressions; 577 char **papszExpressions = stamR3SplitPattern(pszPat, &cExpressions, &pszCopy); 578 if (!papszExpressions) 579 return VERR_NO_MEMORY; 580 581 /* GVMM */ 582 memset(&GVMMReq.Stats, 0, sizeof(GVMMReq.Stats)); 583 for (unsigned i = 0; i < RT_ELEMENTS(g_aGVMMStats); i++) 584 if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGVMMStats[i].pszName)) 585 { 586 *((uint8_t *)&GVMMReq.Stats + (g_aGVMMStats[i].offVar - RT_UOFFSETOF(VM, stam.s.GVMMStats))) = 0xff; 587 fGVMMMatched = true; 588 } 589 590 /* GMM */ 591 // memset(&GMMReq.Stats, 0, sizeof(GMMReq.Stats)); 592 // for (unsigned i = 0; i < RT_ELEMENTS(g_aGMMStats); i++) 593 // if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGMMStats[i].pszName)) 594 // { 595 // *((uint8_t *)&GMMReq.Stats + (g_aGMMStats[i].offVar - RT_UOFFSETOF(VM, stam.s.GMMStats))) = 0xff; 596 // fGMMMatched = true; 597 // } 598 599 RTMemTmpFree(papszExpressions); 600 RTStrFree(pszCopy); 601 } 602 561 603 STAM_LOCK_WR(pVM); 604 if (fGVMMMatched) 605 { 606 GVMMReq.Hdr.cbReq = sizeof(GVMMReq); 607 GVMMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 608 GVMMReq.pSession = pVM->pSession; 609 rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_GVMM_RESET_STATISTICS, 0, &GVMMReq.Hdr); 610 } 611 612 // if (fGMMMatched) 613 // { 614 // GMMReq.Hdr.cbReq = sizeof(Req); 615 // GMMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 616 // GMMReq.pSession = pVM->pSession; 617 // rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_GMM_RESET_STATISTICS, 0, &Req.Hdr); 618 // } 619 620 /* and the reset */ 562 621 stamR3Enum(pVM, pszPat, false /* fUpdateRing0 */, stamR3ResetOne, pVM); 622 563 623 STAM_UNLOCK_WR(pVM); 564 return VINF_SUCCESS;624 return rc; 565 625 } 566 626 … … 1276 1336 1277 1337 1338 /** 1339 * Splits a multi pattern into single ones. 1340 * 1341 * @returns Pointer to an array of single patterns. Free it with RTMemTmpFree. 1342 * @param pszPat The pattern to split. 1343 * @param pcExpressions The number of array elements. 1344 * @param pszCopy The pattern copy to free using RTStrFree. 1345 */ 1346 static char **stamR3SplitPattern(const char *pszPat, unsigned *pcExpressions, char **ppszCopy) 1347 { 1348 Assert(pszPat && *pszPat); 1349 1350 char *pszCopy = RTStrDup(pszPat); 1351 if (!pszCopy) 1352 return NULL; 1353 1354 /* count them & allocate array. */ 1355 char *psz = pszCopy; 1356 unsigned cExpressions = 1; 1357 while ((psz = strchr(psz, '|')) != NULL) 1358 cExpressions++, psz++; 1359 1360 char **papszExpressions = (char **)RTMemTmpAllocZ((cExpressions + 1) * sizeof(char *)); 1361 if (!papszExpressions) 1362 { 1363 RTStrFree(pszCopy); 1364 return NULL; 1365 } 1366 1367 /* split */ 1368 psz = pszCopy; 1369 for (unsigned i = 0;;) 1370 { 1371 papszExpressions[i] = psz; 1372 if (++i >= cExpressions) 1373 break; 1374 psz = strchr(psz, '|'); 1375 *psz++ = '\0'; 1376 } 1377 1378 /* sort the array, putting '*' last. */ 1379 /** @todo sort it... */ 1380 1381 *pcExpressions = cExpressions; 1382 *ppszCopy = pszCopy; 1383 return papszExpressions; 1384 } 1385 1278 1386 1279 1387 /** … … 1341 1449 * Split up the pattern first. 1342 1450 */ 1343 char *pszCopy = RTStrDup(pszPat); 1344 if (!pszCopy) 1451 char *pszCopy; 1452 unsigned cExpressions; 1453 char **papszExpressions = stamR3SplitPattern(pszPat, &cExpressions, &pszCopy); 1454 if (!papszExpressions) 1345 1455 return VERR_NO_MEMORY; 1346 1347 /* count them & allocate array. */1348 char *psz = pszCopy;1349 unsigned cExpressions = 1;1350 while ((psz = strchr(psz, '|')) != NULL)1351 cExpressions++, psz++;1352 1353 char **papszExpressions = (char **)RTMemTmpAlloc((cExpressions + 1) * sizeof(char *));1354 if (!papszExpressions)1355 {1356 RTStrFree(pszCopy);1357 return VERR_NO_TMP_MEMORY;1358 }1359 1360 /* split */1361 psz = pszCopy;1362 for (unsigned i = 0;;)1363 {1364 papszExpressions[i] = psz;1365 if (++i >= cExpressions)1366 break;1367 psz = strchr(psz, '|');1368 *psz++ = '\0';1369 }1370 1371 /* sort the array, putting '*' last. */1372 /** @todo sort it... */1373 1456 1374 1457 /*
Note:
See TracChangeset
for help on using the changeset viewer.