- Timestamp:
- Aug 6, 2021 1:59:06 PM (4 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PDM.cpp
r90348 r90550 483 483 * Initialize critical sections first. 484 484 */ 485 int rc = pdmR3CritSectBothInitStats (pVM);485 int rc = pdmR3CritSectBothInitStatsAndInfo(pVM); 486 486 if (RT_SUCCESS(rc)) 487 487 rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.CritSect, RT_SRC_POS, "PDM"); -
trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp
r90534 r90550 20 20 * Header Files * 21 21 *********************************************************************************************************************************/ 22 #define LOG_GROUP LOG_GROUP_PDM _CRITSECT22 #define LOG_GROUP LOG_GROUP_PDM//_CRITSECT 23 23 #include "PDMInternal.h" 24 24 #include <VBox/vmm/pdmcritsect.h> … … 33 33 #include <iprt/asm.h> 34 34 #include <iprt/assert.h> 35 #include <iprt/getopt.h> 35 36 #include <iprt/lockvalidator.h> 36 37 #include <iprt/string.h> … … 43 44 static int pdmR3CritSectDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTINT pCritSect, PPDMCRITSECTINT pPrev, bool fFinal); 44 45 static int pdmR3CritSectRwDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTRWINT pCritSect, PPDMCRITSECTRWINT pPrev, bool fFinal); 45 46 47 48 /** 49 * Register statistics related to the critical sections. 46 static FNDBGFINFOARGVINT pdmR3CritSectInfo; 47 48 49 50 /** 51 * Register statistics and info items related to the critical sections. 50 52 * 51 53 * @returns VBox status code. 52 54 * @param pVM The cross context VM structure. 53 55 */ 54 int pdmR3CritSectBothInitStats(PVM pVM) 55 { 56 RT_NOREF_PV(pVM); 56 int pdmR3CritSectBothInitStatsAndInfo(PVM pVM) 57 { 58 /* 59 * Statistics. 60 */ 57 61 STAM_REL_REG(pVM, &pVM->pdm.s.StatQueuedCritSectLeaves, STAMTYPE_COUNTER, "/PDM/CritSects/00-QueuedLeaves", STAMUNIT_OCCURENCES, 58 62 "Number of times a critical section leave request needed to be queued for ring-3 execution."); … … 67 71 STAM_REL_REG(pVM, &pVM->pdm.s.StatCritSectNonInterruptibleWaits, STAMTYPE_COUNTER, "/PDM/CritSects/00-Non-interruptible-Waits-VINF_SUCCESS", 68 72 STAMUNIT_OCCURENCES, "Number of non-interruptible waits for rcBusy=VINF_SUCCESS"); 73 74 /* 75 * Info items. 76 */ 77 DBGFR3InfoRegisterInternalArgv(pVM, "critsect", "Show critical section: critsect [-v] [pattern[...]]", pdmR3CritSectInfo, 0); 78 69 79 return VINF_SUCCESS; 70 80 } … … 163 173 * Initialize the structure (first bit is c&p from RTCritSectInitEx). 164 174 */ 165 Log(("pdmR3CritSectInitOne: %p - %s\n", pCritSect, pszName));166 175 pCritSect->Core.u32Magic = RTCRITSECT_MAGIC; 167 176 pCritSect->Core.fFlags = 0; … … 1069 1078 } 1070 1079 1080 1081 /** 1082 * Display matching critical sections. 1083 */ 1084 static void pdmR3CritSectInfoWorker(PUVM pUVM, const char *pszPatterns, PCDBGFINFOHLP pHlp, unsigned cVerbosity) 1085 { 1086 size_t const cchPatterns = pszPatterns ? strlen(pszPatterns) : 0; 1087 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 1088 1089 for (PPDMCRITSECTINT pCritSect = pUVM->pdm.s.pCritSects; pCritSect; pCritSect = pCritSect->pNext) 1090 if ( !pszPatterns 1091 || RTStrSimplePatternMultiMatch(pszPatterns, cchPatterns, pCritSect->pszName, RTSTR_MAX, NULL)) 1092 { 1093 pHlp->pfnPrintf(pHlp, "%p: '%s'%s\n", pCritSect, pCritSect->pszName, 1094 pCritSect->fAutomaticDefaultCritsect ? " default" : "", 1095 pCritSect->fUsedByTimerOrSimilar ? " used-by-timer-or-similar" : ""); 1096 1097 /* 1098 * Get the volatile data: 1099 */ 1100 RTNATIVETHREAD hOwner; 1101 int32_t cLockers; 1102 int32_t cNestings; 1103 uint32_t fFlags; 1104 uint32_t uMagic; 1105 for (uint32_t iTry = 0; iTry < 16; iTry++) 1106 { 1107 hOwner = pCritSect->Core.NativeThreadOwner; 1108 cLockers = pCritSect->Core.cLockers; 1109 cNestings = pCritSect->Core.cNestings; 1110 fFlags = pCritSect->Core.fFlags; 1111 uMagic = pCritSect->Core.u32Magic; 1112 if ( hOwner == pCritSect->Core.NativeThreadOwner 1113 && cLockers == pCritSect->Core.cLockers 1114 && cNestings == pCritSect->Core.cNestings 1115 && fFlags == pCritSect->Core.fFlags 1116 && uMagic == pCritSect->Core.u32Magic) 1117 break; 1118 } 1119 1120 /* 1121 * Check and resolve the magic to a string, print if not RTCRITSECT_MAGIC. 1122 */ 1123 const char *pszMagic; 1124 switch (uMagic) 1125 { 1126 case RTCRITSECT_MAGIC: pszMagic = NULL; break; 1127 case ~RTCRITSECT_MAGIC: pszMagic = " deleted"; break; 1128 case PDMCRITSECT_MAGIC_CORRUPTED: pszMagic = " PDMCRITSECT_MAGIC_CORRUPTED!"; break; 1129 case PDMCRITSECT_MAGIC_FAILED_ABORT: pszMagic = " PDMCRITSECT_MAGIC_FAILED_ABORT!"; break; 1130 default: pszMagic = " !unknown!"; break; 1131 } 1132 if (pszMagic || cVerbosity > 1) 1133 pHlp->pfnPrintf(pHlp, " uMagic=%#x%s\n", uMagic, pszMagic ? pszMagic : ""); 1134 1135 /* 1136 * If locked, print details 1137 */ 1138 if (cLockers != -1 || cNestings != 1 || hOwner != NIL_RTNATIVETHREAD || cVerbosity > 1) 1139 { 1140 /* Translate the owner to a name if we have one and can. */ 1141 const char *pszOwner = NULL; 1142 if (hOwner != NIL_RTNATIVETHREAD) 1143 { 1144 RTTHREAD hOwnerThread = RTThreadFromNative(hOwner); /* Note! Does not return a reference (crazy). */ 1145 if (hOwnerThread != NIL_RTTHREAD) 1146 pszOwner = RTThreadGetName(hOwnerThread); 1147 } 1148 else 1149 pszOwner = "<no-owner>"; 1150 1151 pHlp->pfnPrintf(pHlp, " cLockers=%d cNestings=%d hOwner=%p %s%s\n", cLockers, cNestings, hOwner, 1152 pszOwner ? pszOwner : "???", fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK ? " pending-unlock" : ""); 1153 } 1154 } 1155 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 1156 } 1157 1158 1159 /** 1160 * @callback_method_impl{FNDBGFINFOARGVINT, critsect} 1161 */ 1162 static DECLCALLBACK(void) pdmR3CritSectInfo(PVM pVM, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs) 1163 { 1164 PUVM pUVM = pVM->pUVM; 1165 1166 /* 1167 * Process arguments. 1168 */ 1169 static const RTGETOPTDEF s_aOptions[] = 1170 { 1171 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 1172 }; 1173 RTGETOPTSTATE State; 1174 int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 1175 AssertRC(rc); 1176 1177 unsigned cVerbosity = 1; 1178 unsigned cProcessed = 0; 1179 1180 RTGETOPTUNION ValueUnion; 1181 while ((rc = RTGetOpt(&State, &ValueUnion)) != 0) 1182 { 1183 switch (rc) 1184 { 1185 case 'v': 1186 cVerbosity++; 1187 break; 1188 1189 case VINF_GETOPT_NOT_OPTION: 1190 pdmR3CritSectInfoWorker(pUVM, ValueUnion.psz, pHlp, cVerbosity); 1191 cProcessed++; 1192 break; 1193 1194 default: 1195 pHlp->pfnGetOptError(pHlp, rc, &ValueUnion, &State); 1196 return; 1197 } 1198 } 1199 1200 /* 1201 * If we did nothing above, dump all. 1202 */ 1203 if (!cProcessed) 1204 pdmR3CritSectInfoWorker(pUVM, NULL, pHlp, cVerbosity); 1205 } 1206 1207 -
trunk/src/VBox/VMM/include/PDMInternal.h
r90504 r90550 1622 1622 bool pdmR3IsValidName(const char *pszName); 1623 1623 1624 int pdmR3CritSectBothInitStats (PVM pVM);1624 int pdmR3CritSectBothInitStatsAndInfo(PVM pVM); 1625 1625 int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns); 1626 1626 int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns);
Note:
See TracChangeset
for help on using the changeset viewer.