Changeset 25611 in vbox
- Timestamp:
- Dec 31, 2009 2:54:25 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56302
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
r25609 r25611 55 55 * Deadlock detection stack entry. 56 56 */ 57 typedef struct RTLOCKVAL IDATORDDENTRY57 typedef struct RTLOCKVALDDENTRY 58 58 { 59 59 /** The current record. */ 60 PRTLOCKVALRECUNION pRec;60 PRTLOCKVALRECUNION pRec; 61 61 /** The current entry number if pRec is a shared one. */ 62 uint32_t 62 uint32_t iEntry; 63 63 /** The thread state of the thread we followed to get to pFirstSibling. 64 64 * This is only used for validating a deadlock stack. */ 65 RTTHREADSTATE 65 RTTHREADSTATE enmState; 66 66 /** The thread we followed to get to pFirstSibling. 67 67 * This is only used for validating a deadlock stack. */ 68 PRTTHREADINT 68 PRTTHREADINT pThread; 69 69 /** What pThread is waiting on, i.e. where we entered the circular list of 70 70 * siblings. This is used for validating a deadlock stack as well as 71 71 * terminating the sibling walk. */ 72 PRTLOCKVALRECUNION pFirstSibling;73 } RTLOCKVAL IDATORDDENTRY;72 PRTLOCKVALRECUNION pFirstSibling; 73 } RTLOCKVALDDENTRY; 74 74 75 75 … … 77 77 * Deadlock detection stack. 78 78 */ 79 typedef struct RTLOCKVAL IDATORDDSTACK79 typedef struct RTLOCKVALDDSTACK 80 80 { 81 81 /** The number stack entries. */ 82 uint32_t 82 uint32_t c; 83 83 /** The stack entries. */ 84 RTLOCKVAL IDATORDDENTRYa[32];85 } RTLOCKVAL IDATORDDSTACK;84 RTLOCKVALDDENTRY a[32]; 85 } RTLOCKVALDDSTACK; 86 86 /** Pointer to a deadlock detction stack. */ 87 typedef RTLOCKVAL IDATORDDSTACK *PRTLOCKVALIDATORDDSTACK;87 typedef RTLOCKVALDDSTACK *PRTLOCKVALDDSTACK; 88 88 89 89 … … 92 92 *******************************************************************************/ 93 93 /** Serializing object destruction and deadlock detection. 94 * NS: RTLOCKVALIDATORREC* and RTTHREADINT destruction. 95 * EW: Deadlock detection. 94 * 95 * This makes sure that none of the memory examined by the deadlock detection 96 * code will become invalid (reused for other purposes or made not present) 97 * while the detection is in progress. 98 * 99 * NS: RTLOCKVALREC*, RTTHREADINT and RTLOCKVALDRECSHRD::papOwners destruction. 100 * EW: Deadlock detection and some related activities. 96 101 */ 97 102 static RTSEMXROADS g_hLockValidatorXRoads = NIL_RTSEMXROADS; … … 320 325 321 326 /** 322 * Serializes destruction of RTLOCKVAL IDATORREC* and RTTHREADINT structures.327 * Serializes destruction of RTLOCKVALREC* and RTTHREADINT structures. 323 328 */ 324 329 DECLHIDDEN(void) rtLockValidatorSerializeDestructEnter(void) … … 361 366 if (hXRoads != NIL_RTSEMXROADS) 362 367 RTSemXRoadsEWLeave(hXRoads); 368 } 369 370 371 /** 372 * Initializes the per thread lock validator data. 373 * 374 * @param pPerThread The data. 375 */ 376 DECLHIDDEN(void) rtLockValidatorInitPerThread(RTLOCKVALPERTHREAD *pPerThread) 377 { 378 pPerThread->bmFreeShrdOwners = UINT32_MAX; 379 380 /* ASSUMES the rest has already been zeroed. */ 381 Assert(pPerThread->pRec == NULL); 382 Assert(pPerThread->cWriteLocks == 0); 383 Assert(pPerThread->cReadLocks == 0); 363 384 } 364 385 … … 401 422 } 402 423 } 424 425 426 RTDECL(int) RTLockValidatorRecMakeSiblings(PRTLOCKVALRECCORE pRec1, PRTLOCKVALRECCORE pRec2) 427 { 428 /* 429 * Validate input. 430 */ 431 PRTLOCKVALRECUNION p1 = (PRTLOCKVALRECUNION)pRec1; 432 PRTLOCKVALRECUNION p2 = (PRTLOCKVALRECUNION)pRec2; 433 434 AssertPtrReturn(p1, VERR_SEM_LV_INVALID_PARAMETER); 435 AssertReturn( p1->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC 436 || p1->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC 437 , VERR_SEM_LV_INVALID_PARAMETER); 438 439 AssertPtrReturn(p2, VERR_SEM_LV_INVALID_PARAMETER); 440 AssertReturn( p2->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC 441 || p2->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC 442 , VERR_SEM_LV_INVALID_PARAMETER); 443 444 /* 445 * Link them (circular list). 446 */ 447 if ( p1->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC 448 && p2->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC) 449 { 450 p1->Excl.pSibling = p2; 451 p2->Shared.pSibling = p1; 452 } 453 else if ( p1->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC 454 && p2->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC) 455 { 456 p1->Shared.pSibling = p2; 457 p2->Excl.pSibling = p1; 458 } 459 else 460 AssertFailedReturn(VERR_SEM_LV_INVALID_PARAMETER); /* unsupported mix */ 461 462 return VINF_SUCCESS; 463 } 464 465 403 466 404 467 … … 538 601 539 602 /** 540 * Locates a threadin a shared lock record.541 * 542 * @returns Pointer to the thread recordon success, NULL on failure..603 * Locates an owner (thread) in a shared lock record. 604 * 605 * @returns Pointer to the owner entry on success, NULL on failure.. 543 606 * @param pShared The shared lock record. 544 * @param hThread The thread to find.607 * @param hThread The thread (owner) to find. 545 608 * @param piEntry Where to optionally return the table in index. 609 * Optional. 546 610 */ 547 611 DECLINLINE(PRTLOCKVALRECSHRDOWN) 548 rtLockValidator SharedRecFindThread(PRTLOCKVALRECSHRD pShared, RTTHREAD hThread, uint32_t *piEntry)612 rtLockValidatorRecSharedFindOwner(PRTLOCKVALRECSHRD pShared, RTTHREAD hThread, uint32_t *piEntry) 549 613 { 550 614 rtLockValidatorSerializeDetectionEnter(); … … 573 637 574 638 /** 575 * Allocates and initializes a threadentry for the shared lock record.576 * 577 * @returns The new threadentry.639 * Allocates and initializes an owner entry for the shared lock record. 640 * 641 * @returns The new owner entry. 578 642 * @param pShared The shared lock record. 579 * @param hThread The thread handle. 643 * @param pThreadSelf The calling thread and owner. Used for record 644 * initialization and allocation. 580 645 * @param pSrcPos The source position. 581 646 */ 582 647 DECLINLINE(PRTLOCKVALRECSHRDOWN) 583 rtLockValidator SharedRecAllocThread(PRTLOCKVALRECSHRD pRead, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos)648 rtLockValidatorRecSharedAllocOwner(PRTLOCKVALRECSHRD pRead, PRTTHREADINT pThreadSelf, PCRTLOCKVALSRCPOS pSrcPos) 584 649 { 585 650 PRTLOCKVALRECSHRDOWN pEntry; 586 651 587 pEntry = (PRTLOCKVALRECSHRDOWN)RTMemAlloc(sizeof(RTLOCKVALRECSHRDOWN)); 652 /* 653 * Check if the thread has any statically allocated records we can use. 654 */ 655 unsigned iEntry = ASMBitFirstSetU32(pThreadSelf->LockValidator.bmFreeShrdOwners); 656 if (iEntry > 0) 657 { 658 iEntry--; 659 pThreadSelf->LockValidator.bmFreeShrdOwners |= RT_BIT_32(iEntry); 660 pEntry = &pThreadSelf->LockValidator.aShrdOwners[iEntry]; 661 Assert(!pEntry->fReserved); 662 pEntry->fStaticAlloc = true; 663 } 664 else 665 { 666 pEntry = (PRTLOCKVALRECSHRDOWN)RTMemAlloc(sizeof(RTLOCKVALRECSHRDOWN)); 667 if (RT_UNLIKELY(!pEntry)) 668 return NULL; 669 pEntry->fStaticAlloc = false; 670 } 671 672 pEntry->Core.u32Magic = RTLOCKVALRECSHRDOWN_MAGIC; 673 pEntry->cRecursion = 1; 674 pEntry->fReserved = true; 675 pEntry->hThread = pThreadSelf; 676 pEntry->pDown = NULL; 677 pEntry->pSharedRec = pRead; 678 #if HC_ARCH_BITS == 32 679 pEntry->pvReserved = NULL; 680 #endif 681 if (pSrcPos) 682 pEntry->SrcPos = *pSrcPos; 683 else 684 rtLockValidatorInitSrcPos(&pEntry->SrcPos); 685 return pEntry; 686 } 687 688 689 /** 690 * Frees an owner entry allocated by rtLockValidatorRecSharedAllocOwner. 691 * 692 * @param pEntry The owner entry. 693 */ 694 DECLINLINE(void) rtLockValidatorRecSharedFreeOwner(PRTLOCKVALRECSHRDOWN pEntry) 695 { 588 696 if (pEntry) 589 697 { 590 pEntry->Core.u32Magic = RTLOCKVALRECSHRDOWN_MAGIC; 591 pEntry->cRecursion = 1; 592 pEntry->hThread = hThread; 593 pEntry->pDown = NULL; 594 pEntry->pSharedRec = pRead; 595 #if HC_ARCH_BITS == 32 596 pEntry->pvReserved = NULL; 597 #endif 598 if (pSrcPos) 599 pEntry->SrcPos = *pSrcPos; 698 ASMAtomicWriteU32(&pEntry->Core.u32Magic, RTLOCKVALRECSHRDOWN_MAGIC_DEAD); 699 700 PRTTHREADINT pThreadSelf = pEntry->hThread; 701 ASMAtomicXchgHandle(&pEntry->hThread, NIL_RTTHREAD, &pThreadSelf); 702 Assert(pThreadSelf == RTThreadSelf()); 703 704 pEntry->fReserved = false; 705 706 Assert(pEntry->fReserved); 707 if (pEntry->fStaticAlloc) 708 { 709 uintptr_t iEntry = pEntry - &pThreadSelf->LockValidator.aShrdOwners[0]; 710 AssertReleaseReturnVoid(iEntry < RT_ELEMENTS(pThreadSelf->LockValidator.aShrdOwners)); 711 pThreadSelf->LockValidator.bmFreeShrdOwners &= ~RT_BIT_32(iEntry); 712 } 600 713 else 601 rtLockValidatorInitSrcPos(&pEntry->SrcPos); 602 } 603 604 return pEntry; 605 } 606 607 /** 608 * Frees a thread entry allocated by rtLockValidatorSharedRecAllocThread. 609 * 610 * @param pEntry The thread entry. 611 */ 612 DECLINLINE(void) rtLockValidatorSharedRecFreeThread(PRTLOCKVALRECSHRDOWN pEntry) 613 { 614 if (pEntry) 615 { 616 rtLockValidatorSerializeDestructEnter(); 617 ASMAtomicWriteU32(&pEntry->Core.u32Magic, RTLOCKVALRECSHRDOWN_MAGIC_DEAD); 618 ASMAtomicWriteHandle(&pEntry->hThread, NIL_RTTHREAD); 619 rtLockValidatorSerializeDestructLeave(); 620 621 RTMemFree(pEntry); 714 { 715 rtLockValidatorSerializeDestructEnter(); 716 rtLockValidatorSerializeDestructLeave(); 717 718 RTMemFree(pEntry); 719 } 622 720 } 623 721 } … … 633 731 * @param pShared The shared lock record. 634 732 */ 635 static bool rtLockValidator SharedRecMakeRoom(PRTLOCKVALRECSHRD pShared)733 static bool rtLockValidatorRecSharedMakeRoom(PRTLOCKVALRECSHRD pShared) 636 734 { 637 735 for (unsigned i = 0; i < 1000; i++) … … 704 802 705 803 /** 706 * Adds a threadentry to a shared lock record.804 * Adds an owner entry to a shared lock record. 707 805 * 708 806 * @returns true on success, false on serious race or we're if out of memory. 709 807 * @param pShared The shared lock record. 710 * @param pEntry The threadentry.711 */ 712 DECLINLINE(bool) rtLockValidator SharedRecAddThread(PRTLOCKVALRECSHRD pShared, PRTLOCKVALRECSHRDOWN pEntry)808 * @param pEntry The owner entry. 809 */ 810 DECLINLINE(bool) rtLockValidatorRecSharedAddOwner(PRTLOCKVALRECSHRD pShared, PRTLOCKVALRECSHRDOWN pEntry) 713 811 { 714 812 rtLockValidatorSerializeDetectionEnter(); … … 716 814 { 717 815 if ( ASMAtomicIncU32(&pShared->cEntries) > pShared->cAllocated /** @todo add fudge */ 718 && !rtLockValidator SharedRecMakeRoom(pShared))816 && !rtLockValidatorRecSharedMakeRoom(pShared)) 719 817 return false; /* the worker leave the lock */ 720 818 … … 741 839 742 840 /** 743 * Remove a threadentry from a shared lock record and free it.841 * Remove an owner entry from a shared lock record and free it. 744 842 * 745 843 * @param pShared The shared lock record. 746 * @param pEntry The threadentry to remove.844 * @param pEntry The owner entry to remove. 747 845 * @param iEntry The last known index. 748 846 */ 749 DECLINLINE(void) rtLockValidator SharedRecRemoveAndFree(PRTLOCKVALRECSHRD pShared, PRTLOCKVALRECSHRDOWN pEntry,750 uint32_t iEntry)847 DECLINLINE(void) rtLockValidatorRecSharedRemoveAndFreeOwner(PRTLOCKVALRECSHRD pShared, PRTLOCKVALRECSHRDOWN pEntry, 848 uint32_t iEntry) 751 849 { 752 850 /* … … 774 872 * Successfully removed, now free it. 775 873 */ 776 rtLockValidatorSharedRecFreeThread(pEntry); 777 } 778 779 780 RTDECL(int) RTLockValidatorRecMakeSiblings(PRTLOCKVALRECCORE pRec1, PRTLOCKVALRECCORE pRec2) 781 { 782 /* 783 * Validate input. 784 */ 785 PRTLOCKVALRECUNION p1 = (PRTLOCKVALRECUNION)pRec1; 786 PRTLOCKVALRECUNION p2 = (PRTLOCKVALRECUNION)pRec2; 787 788 AssertPtrReturn(p1, VERR_SEM_LV_INVALID_PARAMETER); 789 AssertReturn( p1->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC 790 || p1->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC 791 , VERR_SEM_LV_INVALID_PARAMETER); 792 793 AssertPtrReturn(p2, VERR_SEM_LV_INVALID_PARAMETER); 794 AssertReturn( p2->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC 795 || p2->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC 796 , VERR_SEM_LV_INVALID_PARAMETER); 797 798 /* 799 * Link them (circular list). 800 */ 801 if ( p1->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC 802 && p2->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC) 803 { 804 p1->Excl.pSibling = p2; 805 p2->Shared.pSibling = p1; 806 } 807 else if ( p1->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC 808 && p2->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC) 809 { 810 p1->Shared.pSibling = p2; 811 p2->Excl.pSibling = p1; 812 } 813 else 814 AssertFailedReturn(VERR_SEM_LV_INVALID_PARAMETER); /* unsupported mix */ 815 816 return VINF_SUCCESS; 874 rtLockValidatorRecSharedFreeOwner(pEntry); 817 875 } 818 876 … … 860 918 */ 861 919 uint32_t iEntry = 0; 862 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidator SharedRecFindThread(pRead, hThread, &iEntry);920 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(pRead, hThread, &iEntry); 863 921 AssertReturn(pEntry, VERR_SEM_LV_NOT_OWNER); 864 922 … … 878 936 pEntry->cRecursion--; 879 937 else 880 rtLockValidator SharedRecRemoveAndFree(pRead, pEntry, iEntry);938 rtLockValidatorRecSharedRemoveAndFreeOwner(pRead, pEntry, iEntry); 881 939 882 940 return VINF_SUCCESS; … … 1014 1072 return; 1015 1073 AssertReturnVoid(hThread != NIL_RTTHREAD); 1074 AssertReturnVoid(hThread->u32Magic == RTTHREADINT_MAGIC); 1016 1075 1017 1076 /* … … 1022 1081 * so it can wait til later sometime. 1023 1082 */ 1024 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidator SharedRecFindThread(pRead, hThread, NULL);1083 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(pRead, hThread, NULL); 1025 1084 if (pEntry) 1026 1085 { … … 1030 1089 1031 1090 /* 1032 * Allocate a new threadentry and insert it into the table.1033 */ 1034 pEntry = rtLockValidator SharedRecAllocThread(pRead, hThread, pSrcPos);1091 * Allocate a new owner entry and insert it into the table. 1092 */ 1093 pEntry = rtLockValidatorRecSharedAllocOwner(pRead, hThread, pSrcPos); 1035 1094 if ( pEntry 1036 && !rtLockValidator SharedRecAddThread(pRead, pEntry))1037 rtLockValidator SharedRecFreeThread(pEntry);1095 && !rtLockValidatorRecSharedAddOwner(pRead, pEntry)) 1096 rtLockValidatorRecSharedFreeOwner(pEntry); 1038 1097 } 1039 1098 … … 1049 1108 * Find the entry hope it's a recursive one. 1050 1109 */ 1051 uint32_t iEntry ;1052 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidator SharedRecFindThread(pRead, hThread, &iEntry);1110 uint32_t iEntry = UINT32_MAX; /* shuts up gcc */ 1111 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(pRead, hThread, &iEntry); 1053 1112 AssertReturnVoid(pEntry); 1054 1113 if (pEntry->cRecursion > 1) 1055 1114 pEntry->cRecursion--; 1056 1115 else 1057 rtLockValidator SharedRecRemoveAndFree(pRead, pEntry, iEntry);1116 rtLockValidatorRecSharedRemoveAndFreeOwner(pRead, pEntry, iEntry); 1058 1117 } 1059 1118 … … 1137 1196 * @param pStack The deadlock detection stack. 1138 1197 */ 1139 static int rtLockValidatorDdVerifyDeadlock(PRTLOCKVAL IDATORDDSTACK pStack)1198 static int rtLockValidatorDdVerifyDeadlock(PRTLOCKVALDDSTACK pStack) 1140 1199 { 1141 1200 uint32_t const c = pStack->c; … … 1167 1226 * @param pStack The deadlock detection stack. 1168 1227 */ 1169 static int rtLockValidatorDdHandleStackOverflow(PRTLOCKVAL IDATORDDSTACK pStack)1228 static int rtLockValidatorDdHandleStackOverflow(PRTLOCKVALDDSTACK pStack) 1170 1229 { 1171 1230 for (size_t i = 0; i < RT_ELEMENTS(pStack->a) - 1; i++) … … 1232 1291 * @param pThreadSelf The calling thread. 1233 1292 */ 1234 static int rtLockValidatorDdDoDetection(PRTLOCKVAL IDATORDDSTACK pStack, PRTLOCKVALRECUNION const pOriginalRec,1293 static int rtLockValidatorDdDoDetection(PRTLOCKVALDDSTACK pStack, PRTLOCKVALRECUNION const pOriginalRec, 1235 1294 PRTTHREADINT const pThreadSelf) 1236 1295 { 1237 1296 pStack->c = 0; 1238 1297 1239 /* We could use a single RTLOCKVAL IDATORDDENTRY variable here, but the1298 /* We could use a single RTLOCKVALDDENTRY variable here, but the 1240 1299 compiler may make a better job of it when using individual variables. */ 1241 PRTLOCKVALRECUNION 1242 PRTLOCKVALRECUNION 1243 uint32_t 1244 PRTTHREADINT 1245 RTTHREADSTATE 1300 PRTLOCKVALRECUNION pRec = pOriginalRec; 1301 PRTLOCKVALRECUNION pFirstSibling = pOriginalRec; 1302 uint32_t iEntry = UINT32_MAX; 1303 PRTTHREADINT pThread = NIL_RTTHREAD; 1304 RTTHREADSTATE enmState = RTTHREADSTATE_RUNNING; 1246 1305 for (;;) 1247 1306 { … … 1294 1353 1295 1354 /* Scan the owner table for blocked owners. */ 1355 pNextThread = NIL_RTTHREAD; 1296 1356 if (ASMAtomicUoReadU32(&pRec->Shared.cEntries) > 0) 1297 1357 { … … 1344 1404 1345 1405 /* If we found a thread, check if it is still waiting for something. */ 1346 RTTHREADSTATE 1347 PRTLOCKVALRECUNION 1406 RTTHREADSTATE enmNextState = RTTHREADSTATE_RUNNING; 1407 PRTLOCKVALRECUNION pNextRec = NULL; 1348 1408 if ( pNextThread != NIL_RTTHREAD 1349 1409 && RT_LIKELY(pNextThread->u32Magic == RTTHREADINT_MAGIC)) … … 1452 1512 * @param rc The return code. 1453 1513 */ 1454 static void rcLockValidatorDoDeadlockComplaining(PRTLOCKVAL IDATORDDSTACK pStack, PRTLOCKVALRECUNION pRec,1514 static void rcLockValidatorDoDeadlockComplaining(PRTLOCKVALDDSTACK pStack, PRTLOCKVALRECUNION pRec, 1455 1515 PRTTHREADINT pThreadSelf, PCRTLOCKVALSRCPOS pSrcPos, int rc) 1456 1516 { … … 1500 1560 { 1501 1561 #ifdef DEBUG_bird 1502 RTLOCKVAL IDATORDDSTACK Stack;1562 RTLOCKVALDDSTACK Stack; 1503 1563 int rc = rtLockValidatorDdDoDetection(&Stack, pRec, pThreadSelf); 1504 1564 if (RT_SUCCESS(rc)) … … 1539 1599 AssertPtrReturn(pWriteU, VERR_SEM_LV_INVALID_PARAMETER); 1540 1600 AssertReturn(pWriteU->Core.u32Magic == RTLOCKVALRECEXCL_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 1601 1541 1602 PRTLOCKVALRECUNION pReadU = (PRTLOCKVALRECUNION)pRead; 1542 1603 AssertPtrReturn(pRead, VERR_SEM_LV_INVALID_PARAMETER); 1543 1604 AssertReturn(pReadU->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 1605 1544 1606 AssertReturn(pReadU->Shared.fEnabled == pWriteU->Excl.fEnabled, VERR_SEM_LV_INVALID_PARAMETER); 1545 1607 if (!pWriteU->Excl.fEnabled) 1546 1608 return VINF_SUCCESS; 1609 1547 1610 AssertReturn(RTTHREAD_IS_SLEEPING(enmState), VERR_SEM_LV_INVALID_PARAMETER); 1611 1548 1612 PRTTHREADINT pThread = hThread; 1549 1613 AssertPtrReturn(pThread, VERR_SEM_LV_INVALID_PARAMETER); … … 1558 1622 * Check for attempts at doing a read upgrade. 1559 1623 */ 1560 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidator SharedRecFindThread(&pReadU->Shared, hThread, NULL);1624 PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(&pReadU->Shared, hThread, NULL); 1561 1625 if (pEntry) 1562 1626 { … … 1614 1678 if (!pRecU->Excl.fEnabled) 1615 1679 return VINF_SUCCESS; 1680 1616 1681 AssertReturn(RTTHREAD_IS_SLEEPING(enmState), VERR_SEM_LV_INVALID_PARAMETER); 1682 1617 1683 PRTTHREADINT pThreadSelf = hThread; 1618 1684 AssertPtrReturn(pThreadSelf, VERR_SEM_LV_INVALID_PARAMETER); 1619 1685 AssertReturn(pThreadSelf->u32Magic == RTTHREADINT_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 1686 1620 1687 RTTHREADSTATE enmThreadState = rtThreadGetState(pThreadSelf); 1621 1688 AssertReturn( enmThreadState == RTTHREADSTATE_RUNNING -
trunk/src/VBox/Runtime/common/misc/thread.cpp
r25598 r25611 367 367 pThread->fIntFlags = fIntFlags; 368 368 pThread->enmState = RTTHREADSTATE_INITIALIZING; 369 #ifdef IN_RING3 370 rtLockValidatorInitPerThread(&pThread->LockValidator); 371 #endif 369 372 int rc = RTSemEventMultiCreate(&pThread->EventUser); 370 373 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Runtime/include/internal/lockvalidator.h
r25609 r25611 55 55 * This is part of the RTTHREADINT structure. 56 56 */ 57 typedef struct RTLOCKVAL IDATORPERTHREAD57 typedef struct RTLOCKVALPERTHREAD 58 58 { 59 /** Where we are blocking. */ 60 RTLOCKVALSRCPOS SrcPos; 59 61 /** What we're blocking on. */ 60 62 PRTLOCKVALRECUNION volatile pRec; 61 /** Where we are blocking. */62 RTLOCKVALSRCPOS SrcPos;63 63 /** Number of registered write locks, mutexes and critsects that this thread owns. */ 64 64 int32_t volatile cWriteLocks; 65 65 /** Number of registered read locks that this thread owns, nesting included. */ 66 66 int32_t volatile cReadLocks; 67 } RTLOCKVALIDATORPERTHREAD; 67 /** Bitmap indicating which entires are free (set) and allocated (clear). */ 68 uint32_t bmFreeShrdOwners; 69 /** Reserved for alignment purposes. */ 70 uint32_t u32Reserved; 71 /** Statically allocated shared owner records */ 72 RTLOCKVALRECSHRDOWN aShrdOwners[32]; 73 } RTLOCKVALPERTHREAD; 68 74 69 75 76 DECLHIDDEN(void) rtLockValidatorInitPerThread(RTLOCKVALPERTHREAD *pPerThread); 70 77 DECLHIDDEN(void) rtLockValidatorSerializeDestructEnter(void); 71 78 DECLHIDDEN(void) rtLockValidatorSerializeDestructLeave(void); -
trunk/src/VBox/Runtime/include/internal/magics.h
r25608 r25611 67 67 /** The magic value for RTLOCALIPCSERVER::u32Magic. (Katsuhiro Otomo) */ 68 68 #define RTLOCALIPCSESSION_MAGIC UINT32_C(0x19530414) 69 /** The magic value for RTLOCKVAL IDATORREC::u32Magic. (Vladimir Vladimirovich Nabokov) */69 /** The magic value for RTLOCKVALRECEXCL::u32Magic. (Vladimir Vladimirovich Nabokov) */ 70 70 #define RTLOCKVALRECEXCL_MAGIC UINT32_C(0x18990422) 71 /** The dead magic value for RTLOCKVAL IDATORREC::u32Magic. */71 /** The dead magic value for RTLOCKVALRECEXCL::u32Magic. */ 72 72 #define RTLOCKVALRECEXCL_MAGIC_DEAD UINT32_C(0x19770702) 73 73 /** The magic value for RTLOCKVALRECSHRD::u32Magic. (Agnar Mykle) */ -
trunk/src/VBox/Runtime/include/internal/strict.h
r25482 r25611 35 35 * @{ */ 36 36 37 #ifdef DEBUG_bird /** @todo reenable this for everyone. Just being a little be cautious right now... */ 37 38 /** @def RTCRITSECT_STRICT 38 39 * Enables strictness checks and lock accounting of the RTCritSect API. … … 57 58 # define RTSEMRW_STRICT 58 59 #endif 59 60 #endif /* DEBUG_bird */ 60 61 61 62 -
trunk/src/VBox/Runtime/include/internal/thread.h
r25597 r25611 92 92 #ifdef IN_RING3 93 93 /** The lock validator data. */ 94 RTLOCKVAL IDATORPERTHREADLockValidator;94 RTLOCKVALPERTHREAD LockValidator; 95 95 #endif /* IN_RING3 */ 96 96 #ifdef IPRT_WITH_GENERIC_TLS
Note:
See TracChangeset
for help on using the changeset viewer.