Changeset 25603 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Dec 31, 2009 2:11:27 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
r25602 r25603 1128 1128 1129 1129 /** 1130 * Verifies the deadlock stack before calling it a deadlock. 1131 * 1132 * @retval VERR_SEM_LV_DEADLOCK if it's a deadlock. 1133 * @retval VERR_TRY_AGAIN if something changed. 1134 * 1135 * @param pStack The deadlock detection stack. 1136 */ 1137 static int rtLockValidatorDdVerifyDeadlock(PRTLOCKVALIDATORDDSTACK pStack) 1138 { 1139 uint32_t const c = pStack->c; 1140 for (uint32_t iPass = 0; iPass < 3; iPass++) 1141 { 1142 for (uint32_t i = 1; i < c; i++) 1143 { 1144 PRTTHREADINT pThread = pStack->a[i].pThread; 1145 if (pThread->u32Magic != RTTHREADINT_MAGIC) 1146 return VERR_TRY_AGAIN; 1147 if (rtThreadGetState(pThread) != pStack->a[i].enmState) 1148 return VERR_TRY_AGAIN; 1149 if (rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pRec) != pStack->a[i].pFirstSibling) 1150 return VERR_TRY_AGAIN; 1151 } 1152 RTThreadYield(); 1153 } 1154 1155 return VERR_SEM_LV_DEADLOCK; 1156 } 1157 1158 1159 /** 1130 1160 * Checks for stack cycles caused by another deadlock before returning. 1131 1161 * … … 1191 1221 * detection. 1192 1222 * 1193 * @returns Same as rtLockValidatorDeadlockDetection. 1223 * @retval VINF_SUCCESS 1224 * @retval VERR_SEM_LV_DEADLOCK 1225 * @retval VERR_SEM_LV_EXISTING_DEADLOCK 1226 * @retval VERR_TRY_AGAIN 1227 * 1194 1228 * @param pStack The stack to use. 1195 1229 * @param pOriginalRec The original record. … … 1213 1247 * Process the current record. 1214 1248 */ 1215 /* Extract the (next)thread. */1249 /* Find the next relevan owner thread. */ 1216 1250 PRTTHREADINT pNextThread; 1217 1251 switch (pRec->Core.u32Magic) … … 1224 1258 && pNextThread != pThreadSelf) 1225 1259 pNextThread = NIL_RTTHREAD; 1260 1226 1261 if ( pNextThread == NIL_RTTHREAD 1227 1262 && pRec->Excl.pSibling … … 1268 1303 { 1269 1304 pNextThread = rtLockValidatorReadThreadHandle(&pEntry->hThread); 1270 if ( pNextThread 1271 && !RTTHREAD_IS_SLEEPING(pNextThread->enmState) 1272 && pNextThread != pThreadSelf) 1305 if (pNextThread) 1306 { 1307 if ( pNextThread->u32Magic == RTTHREADINT_MAGIC 1308 && RTTHREAD_IS_SLEEPING(pNextThread->enmState)) 1309 break; 1273 1310 pNextThread = NIL_RTTHREAD; 1311 } 1274 1312 } 1275 1313 else 1276 1314 Assert(!pEntry || pEntry->Core.u32Magic == RTLOCKVALIDATORSHAREDONE_MAGIC_DEAD); 1277 1315 } 1316 if (pNextThread == NIL_RTTHREAD) 1317 break; 1278 1318 } 1279 1319 1280 1320 /* Advance to the next sibling, if any. */ 1281 Assert(pNextThread == NIL_RTTHREAD);1282 1321 if ( pRec->Shared.pSibling != NULL 1283 1322 && pRec->Shared.pSibling != pFirstSibling) … … 1302 1341 } 1303 1342 1304 /* I s that thread waiting for something?*/1343 /* If we found a thread, check if it is still waiting for something. */ 1305 1344 RTTHREADSTATE enmNextState = RTTHREADSTATE_RUNNING; 1306 1345 PRTLOCKVALIDATORRECUNION pNextRec = NULL; … … 1338 1377 1339 1378 if (RT_UNLIKELY(pNextThread == pThreadSelf)) 1340 return VERR_SEM_LV_DEADLOCK;1379 return rtLockValidatorDdVerifyDeadlock(pStack); 1341 1380 1342 1381 pRec = pNextRec; … … 1457 1496 RTLOCKVALIDATORDDSTACK Stack; 1458 1497 int rc = rtLockValidatorDdDoDetection(&Stack, pRec, pThreadSelf); 1459 if (RT_FAILURE(rc)) 1460 rcLockValidatorDoDeadlockComplaining(&Stack, pThreadSelf, pSrcPos, rc); 1498 if (RT_SUCCESS(rc)) 1499 return VINF_SUCCESS; 1500 1501 if (rc == VERR_TRY_AGAIN) 1502 { 1503 for (uint32_t iLoop = 0; ; iLoop++) 1504 { 1505 rc = rtLockValidatorDdDoDetection(&Stack, pRec, pThreadSelf); 1506 if (RT_SUCCESS_NP(rc)) 1507 return VINF_SUCCESS; 1508 if (rc != VERR_TRY_AGAIN) 1509 break; 1510 RTThreadYield(); 1511 if (iLoop >= 3) 1512 return VINF_SUCCESS; 1513 } 1514 } 1515 1516 rcLockValidatorDoDeadlockComplaining(&Stack, pThreadSelf, pSrcPos, rc); 1461 1517 return rc; 1462 1518 #else
Note:
See TracChangeset
for help on using the changeset viewer.