Changeset 25690 in vbox for trunk/src/VBox/Runtime/common/misc
- Timestamp:
- Jan 8, 2010 1:20:15 PM (15 years ago)
- Location:
- trunk/src/VBox/Runtime/common/misc
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
r25689 r25690 194 194 195 195 /** The max value for RTLOCKVALCLASSINT::cRefs. */ 196 #define RTLOCKVALCLASS_MAX_REFS UINT32_C(0xffff0000)196 #define RTLOCKVALCLASS_MAX_REFS UINT32_C(0xffff0000) 197 197 /** The max value for RTLOCKVALCLASSREF::cLookups. */ 198 #define RTLOCKVALCLASSREF_MAX_LOOKUPS UINT32_C(0xfffe0000)198 #define RTLOCKVALCLASSREF_MAX_LOOKUPS UINT32_C(0xfffe0000) 199 199 /** The absolute max value for RTLOCKVALCLASSREF::cLookups at which it will 200 200 * be set back to RTLOCKVALCLASSREF_MAX_LOOKUPS. */ 201 #define RTLOCKVALCLASSREF_MAX_LOOKUPS_FIX UINT32_C(0xffff0000) 201 #define RTLOCKVALCLASSREF_MAX_LOOKUPS_FIX UINT32_C(0xffff0000) 202 203 204 /** @def RTLOCKVAL_WITH_RECURSION_RECORDS 205 * Enable recursion records. */ 206 #if defined(IN_RING3) || defined(DOXYGEN_RUNNING) 207 # define RTLOCKVAL_WITH_RECURSION_RECORDS 1 208 #endif 209 210 /** @def RTLOCKVAL_WITH_VERBOSE_DUMPS 211 * Enables some extra verbosity in the lock dumping. */ 212 #if defined(DOXYGEN_RUNNING) 213 # define RTLOCKVAL_WITH_VERBOSE_DUMPS 214 #endif 202 215 203 216 … … 359 372 360 373 /** 374 * Helper for rtLockValComplainAboutLock. 375 */ 376 DECL_FORCE_INLINE(void) rtLockValComplainAboutLockHlp(const char *pszPrefix, PRTLOCKVALRECUNION pRec, const char *pszSuffix, 377 uint32_t u32Magic, PCRTLOCKVALSRCPOS pSrcPos, uint32_t cRecursion, 378 const char *pszSuffix2) 379 { 380 switch (u32Magic) 381 { 382 case RTLOCKVALRECEXCL_MAGIC: 383 #ifdef RTLOCKVAL_WITH_VERBOSE_DUMPS 384 RTAssertMsg2AddWeak("%s%p %s xrec=%p own=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix, 385 pRec->Excl.hLock, pRec->Excl.pszName, pRec, 386 rtLockValidatorNameThreadHandle(&pRec->Excl.hThread), cRecursion, 387 pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId, 388 pszSuffix2, pszSuffix); 389 #else 390 RTAssertMsg2AddWeak("%s%p %s own=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix, 391 pRec->Excl.hLock, pRec->Excl.pszName, 392 rtLockValidatorNameThreadHandle(&pRec->Excl.hThread), cRecursion, 393 pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId, 394 pszSuffix2, pszSuffix); 395 #endif 396 break; 397 398 case RTLOCKVALRECSHRD_MAGIC: 399 RTAssertMsg2AddWeak("%s%p %s srec=%p%s", pszPrefix, 400 pRec->Shared.hLock, pRec->Shared.pszName, pRec, 401 pszSuffix); 402 break; 403 404 case RTLOCKVALRECSHRDOWN_MAGIC: 405 { 406 PRTLOCKVALRECSHRD pShared = pRec->ShrdOwner.pSharedRec; 407 if ( VALID_PTR(pShared) 408 && pShared->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC) 409 #ifdef RTLOCKVAL_WITH_VERBOSE_DUMPS 410 RTAssertMsg2AddWeak("%s%p %s srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix, 411 pShared->hLock, pShared->pszName, pShared, 412 pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), cRecursion, 413 pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId, 414 pszSuffix2, pszSuffix); 415 #else 416 RTAssertMsg2AddWeak("%s%p %s thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix, 417 pShared->hLock, pShared->pszName, 418 rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), cRecursion, 419 pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId, 420 pszSuffix2, pszSuffix); 421 #endif 422 else 423 RTAssertMsg2AddWeak("%sbad srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s%s", pszPrefix, 424 pShared, 425 pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), cRecursion, 426 pSrcPos->pszFile, pSrcPos->uLine, pSrcPos->pszFunction, pSrcPos->uId, 427 pszSuffix2, pszSuffix); 428 break; 429 } 430 431 default: 432 AssertMsgFailed(("%#x\n", u32Magic)); 433 } 434 } 435 436 437 /** 361 438 * Describes the lock. 362 439 * … … 373 450 { 374 451 case RTLOCKVALRECEXCL_MAGIC: 375 RTAssertMsg2AddWeak("%s%p %s xrec=%p own=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix, 376 pRec->Excl.hLock, pRec->Excl.pszName, pRec, 377 rtLockValidatorNameThreadHandle(&pRec->Excl.hThread), pRec->Excl.cRecursion, 378 pRec->Excl.SrcPos.pszFile, pRec->Excl.SrcPos.uLine, pRec->Excl.SrcPos.pszFunction, pRec->Excl.SrcPos.uId, 379 pszSuffix); 452 rtLockValComplainAboutLockHlp(pszPrefix, pRec, pszSuffix, RTLOCKVALRECEXCL_MAGIC, 453 &pRec->Excl.SrcPos, pRec->Excl.cRecursion, ""); 380 454 break; 381 455 382 456 case RTLOCKVALRECSHRD_MAGIC: 383 RTAssertMsg2AddWeak("%s%p %s srec=%p%s", pszPrefix, 384 pRec->Shared.hLock, pRec->Shared.pszName, pRec, 385 pszSuffix); 457 rtLockValComplainAboutLockHlp(pszPrefix, pRec, pszSuffix, RTLOCKVALRECSHRD_MAGIC, NULL, 0, ""); 386 458 break; 387 459 388 460 case RTLOCKVALRECSHRDOWN_MAGIC: 461 rtLockValComplainAboutLockHlp(pszPrefix, pRec, pszSuffix, RTLOCKVALRECSHRDOWN_MAGIC, 462 &pRec->ShrdOwner.SrcPos, pRec->ShrdOwner.cRecursion, ""); 463 break; 464 465 case RTLOCKVALRECNEST_MAGIC: 389 466 { 390 PRTLOCKVALRECSHRD pShared = pRec->ShrdOwner.pSharedRec; 391 if ( VALID_PTR(pShared) 392 && pShared->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC) 393 RTAssertMsg2AddWeak("%s%p %s srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix, 394 pShared->hLock, pShared->pszName, pShared, 395 pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), pRec->ShrdOwner.cRecursion, 396 pRec->ShrdOwner.SrcPos.pszFile, pRec->ShrdOwner.SrcPos.uLine, pRec->ShrdOwner.SrcPos.pszFunction, pRec->ShrdOwner.SrcPos.uId, 397 pszSuffix); 467 PRTLOCKVALRECUNION pRealRec = pRec->Nest.pRec; 468 uint32_t u32Magic; 469 if ( VALID_PTR(pRealRec) 470 && ( (u32Magic = pRealRec->Core.u32Magic) == RTLOCKVALRECEXCL_MAGIC 471 || u32Magic == RTLOCKVALRECSHRD_MAGIC 472 || u32Magic == RTLOCKVALRECSHRDOWN_MAGIC) 473 ) 474 rtLockValComplainAboutLockHlp(pszPrefix, pRealRec, pszSuffix, u32Magic, 475 &pRec->Nest.SrcPos, pRec->Nest.cRecursion, " [recursion]"); 398 476 else 399 RTAssertMsg2AddWeak("%sbad srec=%p trec=%p thr=%s nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix, 400 pShared, 401 pRec, rtLockValidatorNameThreadHandle(&pRec->ShrdOwner.hThread), pRec->ShrdOwner.cRecursion, 402 pRec->ShrdOwner.SrcPos.pszFile, pRec->ShrdOwner.SrcPos.uLine, pRec->ShrdOwner.SrcPos.pszFunction, pRec->ShrdOwner.SrcPos.uId, 477 RTAssertMsg2AddWeak("%sbad rrec=%p nrec=%p nest=%u pos={%Rbn(%u) %Rfn %p}%s", pszPrefix, 478 pRealRec, pRec, pRec->Nest.cRecursion, 479 pRec->Nest.SrcPos.pszFile, pRec->Nest.SrcPos.uLine, pRec->Nest.SrcPos.pszFunction, pRec->Nest.SrcPos.uId, 403 480 pszSuffix); 404 481 break; … … 431 508 if (cEntries >= cMinFrames) 432 509 { 433 RTAssertMsg2AddWeak("%*s---- start of lock stack - %u entr%s ----\n", cchIndent, "", cEntries,434 cEntries == 1 ? "y" : "ies");510 RTAssertMsg2AddWeak("%*s---- start of lock stack for %p %s - %u entr%s ----\n", cchIndent, "", 511 pThread, pThread->szName, cEntries, cEntries == 1 ? "y" : "ies"); 435 512 PRTLOCKVALRECUNION pCur = rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pStackTop); 436 for (uint32_t i = 0; pCur; i++)513 for (uint32_t i = 0; VALID_PTR(pCur); i++) 437 514 { 438 515 char szPrefix[80]; … … 443 520 case RTLOCKVALRECEXCL_MAGIC: pCur = rtLockValidatorReadRecUnionPtr(&pCur->Excl.pDown); break; 444 521 case RTLOCKVALRECSHRDOWN_MAGIC: pCur = rtLockValidatorReadRecUnionPtr(&pCur->ShrdOwner.pDown); break; 522 case RTLOCKVALRECNEST_MAGIC: pCur = rtLockValidatorReadRecUnionPtr(&pCur->Nest.pDown); break; 445 523 default: 446 524 RTAssertMsg2AddWeak("%*s<bad stack frame>\n", cchIndent, ""); … … 690 768 Assert(pPerThread->fInValidator == false); 691 769 Assert(pPerThread->pStackTop == NULL); 770 } 771 772 773 /** 774 * Delete the per thread lock validator data. 775 * 776 * @param pPerThread The data. 777 */ 778 DECLHIDDEN(void) rtLockValidatorDeletePerThread(RTLOCKVALPERTHREAD *pPerThread) 779 { 780 /* 781 * Check that the thread doesn't own any locks at this time. 782 */ 783 if (pPerThread->pStackTop) 784 { 785 rtLockValComplainFirst("Thread terminating owning locks!", NULL, 786 RT_FROM_MEMBER(pPerThread, RTTHREADINT, LockValidator), 787 pPerThread->pStackTop); 788 rtLockValComplainPanic(); 789 } 790 791 /* 792 * Free the recursion records. 793 */ 794 PRTLOCKVALRECNEST pCur = pPerThread->pFreeNestRecs; 795 pPerThread->pFreeNestRecs = NULL; 796 while (pCur) 797 { 798 PRTLOCKVALRECNEST pNext = pCur->pNextFree; 799 RTMemFree(pNext); 800 pCur = pNext; 801 } 692 802 } 693 803 … … 1084 1194 uint32_t cEntries = 0; 1085 1195 PRTLOCKVALRECUNION pCur = rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pStackTop); 1086 while ( pCur)1196 while (VALID_PTR(pCur)) 1087 1197 { 1088 1198 switch (pCur->Core.u32Magic) … … 1096 1206 break; 1097 1207 1208 case RTLOCKVALRECNEST_MAGIC: 1209 pCur = rtLockValidatorReadRecUnionPtr(&pCur->Nest.pDown); 1210 break; 1211 1098 1212 default: 1099 1213 AssertMsgFailedReturn(("%#x\n", pCur->Core.u32Magic), cEntries); … … 1117 1231 while (pCur) 1118 1232 { 1233 AssertPtrReturn(pCur, false); 1234 if (pCur == pRec) 1235 return true; 1119 1236 switch (pCur->Core.u32Magic) 1120 1237 { 1121 1238 case RTLOCKVALRECEXCL_MAGIC: 1122 1239 Assert(pRec->Excl.cRecursion >= 1); 1123 if (pCur->Excl.pDown == pRec)1124 return true;1125 1240 pCur = pCur->Excl.pDown; 1126 1241 break; … … 1128 1243 case RTLOCKVALRECSHRDOWN_MAGIC: 1129 1244 Assert(pCur->ShrdOwner.cRecursion >= 1); 1130 if (pCur->ShrdOwner.pDown == pRec)1131 return true;1132 1245 pCur = pCur->ShrdOwner.pDown; 1133 1246 break; 1134 1247 1248 case RTLOCKVALRECNEST_MAGIC: 1249 Assert(pCur->Nest.cRecursion > 1); 1250 pCur = pCur->Nest.pDown; 1251 break; 1252 1135 1253 default: 1136 1254 AssertMsgFailedReturn(("%#x\n", pCur->Core.u32Magic), false); … … 1142 1260 1143 1261 /** 1144 * Pushes a lock onto the stack.1262 * Pushes a lock record onto the stack. 1145 1263 * 1146 1264 * @param pThreadSelf The current thread. … … 1157 1275 Assert(pRec->Excl.cRecursion == 1); 1158 1276 Assert(pRec->Excl.pDown == NULL); 1159 pRec->Excl.pDown = pThreadSelf->LockValidator.pStackTop;1277 rtLockValidatorWriteRecUnionPtr(&pRec->Excl.pDown, pThreadSelf->LockValidator.pStackTop); 1160 1278 break; 1161 1279 … … 1163 1281 Assert(pRec->ShrdOwner.cRecursion == 1); 1164 1282 Assert(pRec->ShrdOwner.pDown == NULL); 1165 pRec->ShrdOwner.pDown = pThreadSelf->LockValidator.pStackTop;1283 rtLockValidatorWriteRecUnionPtr(&pRec->ShrdOwner.pDown, pThreadSelf->LockValidator.pStackTop); 1166 1284 break; 1167 1285 1168 case RTLOCKVALRECSHRD_MAGIC:1169 1286 default: 1170 1287 AssertMsgFailedReturnVoid(("%#x\n", pRec->Core.u32Magic)); 1171 1288 } 1172 pThreadSelf->LockValidator.pStackTop = pRec;1173 } 1174 1175 1176 /** 1177 * Pops a lock off the stack.1289 rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, pRec); 1290 } 1291 1292 1293 /** 1294 * Pops a lock record off the stack. 1178 1295 * 1179 1296 * @param pThreadSelf The current thread. … … 1190 1307 Assert(pRec->Excl.cRecursion == 0); 1191 1308 pDown = pRec->Excl.pDown; 1192 pRec->Excl.pDown = NULL;1309 rtLockValidatorWriteRecUnionPtr(&pRec->Excl.pDown, NULL); /* lazy bird */ 1193 1310 break; 1194 1311 … … 1196 1313 Assert(pRec->ShrdOwner.cRecursion == 0); 1197 1314 pDown = pRec->ShrdOwner.pDown; 1198 pRec->ShrdOwner.pDown = NULL;1315 rtLockValidatorWriteRecUnionPtr(&pRec->ShrdOwner.pDown, NULL); 1199 1316 break; 1200 1317 … … 1203 1320 } 1204 1321 if (pThreadSelf->LockValidator.pStackTop == pRec) 1205 pThreadSelf->LockValidator.pStackTop = pDown;1322 rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, pDown); 1206 1323 else 1207 1324 { 1208 /* find the record on top of ours*/1325 /* Find the record above ours. */ 1209 1326 PRTLOCKVALRECUNION pAbove = pThreadSelf->LockValidator.pStackTop; 1210 1327 while (pAbove) … … 1216 1333 if (pAbove->Excl.pDown == pRec) 1217 1334 { 1218 pAbove->Excl.pDown = pDown;1335 rtLockValidatorWriteRecUnionPtr(&pAbove->Excl.pDown, pDown); 1219 1336 return; 1220 1337 } … … 1226 1343 if (pAbove->ShrdOwner.pDown == pRec) 1227 1344 { 1228 pAbove->ShrdOwner.pDown = pDown;1345 rtLockValidatorWriteRecUnionPtr(&pAbove->ShrdOwner.pDown, pDown); 1229 1346 return; 1230 1347 } … … 1232 1349 break; 1233 1350 1351 case RTLOCKVALRECNEST_MAGIC: 1352 Assert(pAbove->Nest.cRecursion >= 1); 1353 if (pAbove->Nest.pDown == pRec) 1354 { 1355 rtLockValidatorWriteRecUnionPtr(&pAbove->Nest.pDown, pDown); 1356 return; 1357 } 1358 pAbove = pAbove->Nest.pDown; 1359 break; 1360 1234 1361 default: 1235 1362 AssertMsgFailedReturnVoid(("%#x\n", pAbove->Core.u32Magic)); … … 1241 1368 1242 1369 1370 /** 1371 * Creates and pushes lock recursion record onto the stack. 1372 * 1373 * @param pThreadSelf The current thread. 1374 * @param pRec The lock record. 1375 * @param pSrcPos Where the recursion occured. 1376 */ 1243 1377 static void rtLockValidatorStackPushRecursion(PRTTHREADINT pThreadSelf, PRTLOCKVALRECUNION pRec, PCRTLOCKVALSRCPOS pSrcPos) 1244 1378 { 1245 1379 Assert(pThreadSelf == RTThreadSelf()); 1246 /** @todo insert a recursion record onto the stack. Keep a reasonally big pool 1247 * of them associated with each thread. */ 1380 Assert(rtLockValidatorStackContainsRec(pThreadSelf, pRec)); 1381 1382 #ifdef RTLOCKVAL_WITH_RECURSION_RECORDS 1383 /* 1384 * Allocate a new recursion record 1385 */ 1386 PRTLOCKVALRECNEST pRecursionRec = pThreadSelf->LockValidator.pFreeNestRecs; 1387 if (pRecursionRec) 1388 pThreadSelf->LockValidator.pFreeNestRecs = pRecursionRec->pNextFree; 1389 else 1390 { 1391 pRecursionRec = (PRTLOCKVALRECNEST)RTMemAlloc(sizeof(*pRecursionRec)); 1392 if (!pRecursionRec) 1393 return; 1394 } 1395 1396 /* 1397 * Initialize it. 1398 */ 1248 1399 switch (pRec->Core.u32Magic) 1249 1400 { 1250 1401 case RTLOCKVALRECEXCL_MAGIC: 1251 Assert(pRec->Excl.cRecursion > 1);1402 pRecursionRec->cRecursion = pRec->Excl.cRecursion; 1252 1403 break; 1253 1404 1254 1405 case RTLOCKVALRECSHRDOWN_MAGIC: 1255 Assert(pRec->ShrdOwner.cRecursion > 1);1406 pRecursionRec->cRecursion = pRec->ShrdOwner.cRecursion; 1256 1407 break; 1257 1408 1258 1409 default: 1259 AssertMsgFailedReturnVoid(("%#x\n", pRec->Core.u32Magic)); 1260 } 1261 } 1262 1263 1410 AssertMsgFailed(("%#x\n", pRec->Core.u32Magic)); 1411 rtLockValidatorSerializeDestructEnter(); 1412 rtLockValidatorSerializeDestructLeave(); 1413 RTMemFree(pRecursionRec); 1414 return; 1415 } 1416 Assert(pRecursionRec->cRecursion > 1); 1417 pRecursionRec->pRec = pRec; 1418 pRecursionRec->pDown = NULL; 1419 pRecursionRec->pNextFree = NULL; 1420 rtLockValidatorSrcPosCopy(&pRecursionRec->SrcPos, pSrcPos); 1421 pRecursionRec->Core.u32Magic = RTLOCKVALRECNEST_MAGIC; 1422 1423 /* 1424 * Link it. 1425 */ 1426 pRecursionRec->pDown = pThreadSelf->LockValidator.pStackTop; 1427 rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, (PRTLOCKVALRECUNION)pRecursionRec); 1428 #endif /* RTLOCKVAL_WITH_RECURSION_RECORDS */ 1429 } 1430 1431 1432 /** 1433 * Pops a lock recursion record off the stack. 1434 * 1435 * @param pThreadSelf The current thread. 1436 * @param pRec The lock record. 1437 */ 1264 1438 static void rtLockValidatorStackPopRecursion(PRTTHREADINT pThreadSelf, PRTLOCKVALRECUNION pRec) 1265 1439 { 1266 1440 Assert(pThreadSelf == RTThreadSelf()); 1441 Assert(rtLockValidatorStackContainsRec(pThreadSelf, pRec)); 1442 1443 uint32_t cRecursion; 1267 1444 switch (pRec->Core.u32Magic) 1268 1445 { 1269 case RTLOCKVALRECEXCL_MAGIC: 1270 Assert(pRec->Excl.cRecursion >= 1); 1271 break; 1272 1273 case RTLOCKVALRECSHRDOWN_MAGIC: 1274 Assert(pRec->ShrdOwner.cRecursion >= 1); 1275 break; 1276 1277 default: 1278 AssertMsgFailedReturnVoid(("%#x\n", pRec->Core.u32Magic)); 1279 } 1446 case RTLOCKVALRECEXCL_MAGIC: cRecursion = pRec->Excl.cRecursion; break; 1447 case RTLOCKVALRECSHRDOWN_MAGIC: cRecursion = pRec->ShrdOwner.cRecursion; break; 1448 default: AssertMsgFailedReturnVoid(("%#x\n", pRec->Core.u32Magic)); 1449 } 1450 Assert(cRecursion >= 1); 1451 1452 #ifdef RTLOCKVAL_WITH_RECURSION_RECORDS 1453 /* 1454 * Pop the recursion record. 1455 */ 1456 PRTLOCKVALRECUNION pNest = pThreadSelf->LockValidator.pStackTop; 1457 if ( pNest != NULL 1458 && pNest->Core.u32Magic == RTLOCKVALRECNEST_MAGIC 1459 && pNest->Nest.pRec == pRec 1460 ) 1461 { 1462 Assert(pNest->Nest.cRecursion == cRecursion + 1); 1463 rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pStackTop, pNest->Nest.pDown); 1464 } 1465 else 1466 { 1467 /* Find the record above ours. */ 1468 PRTLOCKVALRECUNION pAbove = NULL; 1469 while (pNest) 1470 { 1471 switch (pNest->Core.u32Magic) 1472 { 1473 case RTLOCKVALRECEXCL_MAGIC: 1474 pAbove = pNest; 1475 pNest = pNest->Excl.pDown; 1476 break; 1477 case RTLOCKVALRECSHRDOWN_MAGIC: 1478 pAbove = pNest; 1479 pNest = pNest->ShrdOwner.pDown; 1480 break; 1481 case RTLOCKVALRECNEST_MAGIC: 1482 if (pNest->Nest.pRec == pRec) 1483 { 1484 pNest = pNest; 1485 break; 1486 } 1487 pAbove = pNest; 1488 pNest = pNest->Nest.pDown; 1489 break; 1490 default: 1491 AssertMsgFailedReturnVoid(("%#x\n", pNest->Core.u32Magic)); 1492 } 1493 } 1494 AssertMsg(pNest, ("%p %p\n", pRec, pThreadSelf)); 1495 AssertMsg(pAbove, ("%p %p\n", pRec, pThreadSelf)); 1496 Assert(pNest->Nest.cRecursion == cRecursion + 1); 1497 switch (pAbove->Core.u32Magic) 1498 { 1499 case RTLOCKVALRECEXCL_MAGIC: 1500 rtLockValidatorWriteRecUnionPtr(&pNest->Excl.pDown, pNest->Nest.pDown); 1501 break; 1502 case RTLOCKVALRECSHRDOWN_MAGIC: 1503 rtLockValidatorWriteRecUnionPtr(&pNest->ShrdOwner.pDown, pNest->Nest.pDown); 1504 break; 1505 case RTLOCKVALRECNEST_MAGIC: 1506 rtLockValidatorWriteRecUnionPtr(&pNest->Nest.pDown, pNest->Nest.pDown); 1507 break; 1508 default: 1509 AssertMsgFailedReturnVoid(("%#x\n", pNest->Core.u32Magic)); 1510 } 1511 } 1512 1513 /* 1514 * Invalidate and free the record. 1515 */ 1516 ASMAtomicWriteU32(&pNest->Core.u32Magic, RTLOCKVALRECNEST_MAGIC); 1517 rtLockValidatorWriteRecUnionPtr(&pNest->Nest.pDown, NULL); 1518 rtLockValidatorWriteRecUnionPtr(&pNest->Nest.pRec, NULL); 1519 pNest->Nest.cRecursion = 0; 1520 pNest->Nest.pNextFree = pThreadSelf->LockValidator.pFreeNestRecs; 1521 pThreadSelf->LockValidator.pFreeNestRecs = &pNest->Nest; 1522 #endif /* RTLOCKVAL_WITH_RECURSION_RECORDS */ 1280 1523 } 1281 1524 … … 1702 1945 pShrdOwner = pStack->a[i].pRec->Shared.papOwners[pStack->a[i].iEntry]; 1703 1946 if (VALID_PTR(pShrdOwner) && pShrdOwner->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC) 1947 { 1704 1948 rtLockValComplainAboutLock(szPrefix, (PRTLOCKVALRECUNION)pShrdOwner, "\n"); 1949 rtLockValComplainAboutLockStack(pShrdOwner->hThread, 5, 2); 1950 } 1705 1951 else 1952 { 1706 1953 rtLockValComplainAboutLock(szPrefix, pStack->a[i].pRec, "\n"); 1954 if (pStack->a[i].pRec->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC); 1955 rtLockValComplainAboutLockStack(pStack->a[i].pRec->Excl.hThread, 5, 2); 1956 } 1707 1957 } 1708 1958 rtLockValComplainMore("---- end of deadlock chain ----\n"); … … 1852 2102 case RTLOCKVALRECSHRDOWN_MAGIC: 1853 2103 return pRec->ShrdOwner.pSharedRec ? pRec->ShrdOwner.pSharedRec->pszName : "orphaned"; 2104 case RTLOCKVALRECNEST_MAGIC: 2105 pRec = rtLockValidatorReadRecUnionPtr(&pRec->Nest.pRec); 2106 if (VALID_PTR(pRec)) 2107 { 2108 switch (pRec->Core.u32Magic) 2109 { 2110 case RTLOCKVALRECEXCL_MAGIC: 2111 return pRec->Excl.pszName; 2112 case RTLOCKVALRECSHRD_MAGIC: 2113 return pRec->Shared.pszName; 2114 case RTLOCKVALRECSHRDOWN_MAGIC: 2115 return pRec->ShrdOwner.pSharedRec ? pRec->ShrdOwner.pSharedRec->pszName : "orphaned"; 2116 default: 2117 return "unknown-nested"; 2118 } 2119 } 2120 return "orphaned-nested"; 1854 2121 default: 1855 2122 return "unknown"; … … 2017 2284 && !pRecU->Excl.hClass->fRecursionOk) 2018 2285 { 2019 rtLockValComplainFirst("Recursion not allowed by the class ",2020 2286 rtLockValComplainFirst("Recursion not allowed by the class!", 2287 pSrcPos, pRecU->Excl.hThread, (PRTLOCKVALRECUNION)pRec); 2021 2288 rtLockValComplainPanic(); 2022 2289 return VERR_SEM_LV_NESTED; … … 2061 2328 && !pRecU->Excl.hClass->fRecursionOk) 2062 2329 { 2063 rtLockValComplainFirst("Mixed recursion not allowed by the class ",2064 2330 rtLockValComplainFirst("Mixed recursion not allowed by the class!", 2331 pSrcPos, pRecU->Excl.hThread, (PRTLOCKVALRECUNION)pRec); 2065 2332 rtLockValComplainPanic(); 2066 2333 return VERR_SEM_LV_NESTED; … … 2160 2427 && !pRecU->Excl.hClass->fRecursionOk)) 2161 2428 { 2162 rtLockValComplainFirst("Recursion not allowed ", pSrcPos, pThreadSelf, pRecU);2429 rtLockValComplainFirst("Recursion not allowed!", pSrcPos, pThreadSelf, pRecU); 2163 2430 rtLockValComplainPanic(); 2164 2431 rc = VERR_SEM_LV_NESTED; … … 2369 2636 ) 2370 2637 { 2371 rtLockValComplainFirst("Recursion not allowed ", pSrcPos, pThreadSelf, pRecU);2638 rtLockValComplainFirst("Recursion not allowed!", pSrcPos, pThreadSelf, pRecU); 2372 2639 rtLockValComplainPanic(); 2373 2640 rc = VERR_SEM_LV_NESTED; … … 2809 3076 if (RT_UNLIKELY(!pEntry)) 2810 3077 { 2811 rtLockValComplainFirst("Not owner (shared) ", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);3078 rtLockValComplainFirst("Not owner (shared)!", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec); 2812 3079 rtLockValComplainPanic(); 2813 3080 return VERR_SEM_LV_NOT_OWNER; … … 2862 3129 if (RT_UNLIKELY(!pEntry)) 2863 3130 { 2864 rtLockValComplainFirst("Invalid signaller ", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);3131 rtLockValComplainFirst("Invalid signaller!", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec); 2865 3132 rtLockValComplainPanic(); 2866 3133 return VERR_SEM_LV_NOT_SIGNALLER; -
trunk/src/VBox/Runtime/common/misc/thread.cpp
r25660 r25690 577 577 #ifdef IN_RING3 578 578 rtLockValidatorSerializeDestructEnter(); 579 580 rtLockValidatorDeletePerThread(&pThread->LockValidator); 579 581 #endif 580 581 582 ASMAtomicXchgU32(&pThread->u32Magic, RTTHREADINT_MAGIC_DEAD); 582 583 ASMAtomicWritePtr(&pThread->Core.Key, (void *)NIL_RTTHREAD);
Note:
See TracChangeset
for help on using the changeset viewer.