Changeset 25617 in vbox for trunk/src/VBox/Runtime/common/misc
- Timestamp:
- Jan 2, 2010 12:14:47 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56308
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
r25614 r25617 86 86 /** Pointer to a deadlock detction stack. */ 87 87 typedef RTLOCKVALDDSTACK *PRTLOCKVALDDSTACK; 88 89 90 /******************************************************************************* 91 * Defined Constants And Macros * 92 *******************************************************************************/ 93 /** Macro that asserts that a pointer is aligned correctly. 94 * Only used when fighting bugs. */ 95 #if 1 96 # define RTLOCKVAL_ASSERT_PTR_ALIGN(p) \ 97 AssertMsg(!((uintptr_t)(p) & (sizeof(uintptr_t) - 1)), ("%p\n", (p))); 98 #else 99 # define RTLOCKVAL_ASSERT_PTR_ALIGN(p) do { } while (0) 100 #endif 88 101 89 102 … … 121 134 DECL_FORCE_INLINE(PRTLOCKVALRECUNION) rtLockValidatorReadRecUnionPtr(PRTLOCKVALRECUNION volatile *ppRec) 122 135 { 123 return (PRTLOCKVALRECUNION)ASMAtomicReadPtr((void * volatile *)ppRec); 136 PRTLOCKVALRECUNION p = (PRTLOCKVALRECUNION)ASMAtomicReadPtr((void * volatile *)ppRec); 137 RTLOCKVAL_ASSERT_PTR_ALIGN(p); 138 return p; 124 139 } 125 140 … … 128 143 DECL_FORCE_INLINE(void) rtLockValidatorWriteRecUnionPtr(PRTLOCKVALRECUNION volatile *ppRec, PRTLOCKVALRECUNION pRecNew) 129 144 { 145 RTLOCKVAL_ASSERT_PTR_ALIGN(pRecNew); 130 146 ASMAtomicWritePtr((void * volatile *)ppRec, pRecNew); 131 147 } … … 135 151 DECL_FORCE_INLINE(PRTTHREADINT) rtLockValidatorReadThreadHandle(RTTHREAD volatile *phThread) 136 152 { 137 return (PRTTHREADINT)ASMAtomicReadPtr((void * volatile *)phThread); 153 PRTTHREADINT p = (PRTTHREADINT)ASMAtomicReadPtr((void * volatile *)phThread); 154 RTLOCKVAL_ASSERT_PTR_ALIGN(p); 155 return p; 138 156 } 139 157 … … 142 160 DECL_FORCE_INLINE(PRTLOCKVALRECSHRDOWN) rtLockValidatorUoReadSharedOwner(PRTLOCKVALRECSHRDOWN volatile *ppOwner) 143 161 { 144 return (PRTLOCKVALRECSHRDOWN)ASMAtomicUoReadPtr((void * volatile *)ppOwner); 162 PRTLOCKVALRECSHRDOWN p = (PRTLOCKVALRECSHRDOWN)ASMAtomicUoReadPtr((void * volatile *)ppOwner); 163 RTLOCKVAL_ASSERT_PTR_ALIGN(p); 164 return p; 145 165 } 146 166 … … 456 476 457 477 /** 458 * Worker for rtLockValidatorDoDeadlockCheck that checks if there is more work459 * to be done during unwind.460 *461 * @returns true if there is more work left for this lock, false if not.462 * @param pRec The current record.463 * @param iEntry The current index.464 * @param pFirstSibling The first record we examined.465 */466 DECL_FORCE_INLINE(bool) rtLockValidatorDdMoreWorkLeft(PRTLOCKVALRECUNION pRec, uint32_t iEntry, PRTLOCKVALRECUNION pFirstSibling)467 {468 PRTLOCKVALRECUNION pSibling;469 470 switch (pRec->Core.u32Magic)471 {472 case RTLOCKVALRECEXCL_MAGIC:473 pSibling = pRec->Excl.pSibling;474 break;475 476 case RTLOCKVALRECSHRD_MAGIC:477 if (iEntry + 1 < pRec->Shared.cAllocated)478 return true;479 pSibling = pRec->Excl.pSibling;480 break;481 482 default:483 return false;484 }485 return pSibling != NULL486 && pSibling != pFirstSibling;487 }488 489 490 /**491 478 * Worker for rtLockValidatorDeadlockDetection that does the actual deadlock 492 479 * detection. … … 519 506 * Process the current record. 520 507 */ 508 RTLOCKVAL_ASSERT_PTR_ALIGN(pRec); 509 521 510 /* Find the next relevant owner thread. */ 522 511 PRTTHREADINT pNextThread; … … 526 515 Assert(iEntry == UINT32_MAX); 527 516 pNextThread = rtLockValidatorReadThreadHandle(&pRec->Excl.hThread); 528 if ( pNextThread 529 && pNextThread->u32Magic == RTTHREADINT_MAGIC 530 && !RTTHREAD_IS_SLEEPING(pNextThread->enmState) 531 && pNextThread != pThreadSelf) 532 pNextThread = NIL_RTTHREAD; 533 534 if ( pNextThread == NIL_RTTHREAD 535 && pRec->Excl.pSibling 536 && pRec->Excl.pSibling != pFirstSibling) 517 if ( !pNextThread 518 || ( pNextThread != pThreadSelf 519 && ( pNextThread->u32Magic != RTTHREADINT_MAGIC 520 || !RTTHREAD_IS_SLEEPING(rtThreadGetState(pNextThread)) ) 521 ) 522 ) 537 523 { 538 524 pRec = pRec->Excl.pSibling; 539 continue; 525 if ( pRec 526 && pRec != pFirstSibling) 527 continue; 528 pNextThread = NIL_RTTHREAD; 540 529 } 541 530 break; … … 580 569 { 581 570 if ( pNextThread->u32Magic == RTTHREADINT_MAGIC 582 && ( RTTHREAD_IS_SLEEPING( pNextThread->enmState)571 && ( RTTHREAD_IS_SLEEPING(rtThreadGetState(pNextThread)) 583 572 || pNextThread == pThreadSelf)) 584 573 break; … … 589 578 Assert(!pEntry || pEntry->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC_DEAD); 590 579 } 591 if (pNextThread == NIL_RTTHREAD)580 if (pNextThread != NIL_RTTHREAD) 592 581 break; 593 582 } 594 583 595 584 /* Advance to the next sibling, if any. */ 596 if ( pRec->Shared.pSibling != NULL 597 && pRec->Shared.pSibling != pFirstSibling) 585 pRec = pRec->Shared.pSibling; 586 if ( pRec != NULL 587 && pRec != pFirstSibling) 598 588 { 599 pRec = pRec->Shared.pSibling;600 589 iEntry = UINT32_MAX; 601 590 continue; 602 591 } 592 Assert(pNextThread == NIL_RTTHREAD); 603 593 break; 604 594 … … 673 663 return VINF_SUCCESS; 674 664 i--; 675 676 /* examine it. */ 677 pRec = pStack->a[i].pRec; 678 pFirstSibling = pStack->a[i].pFirstSibling; 679 iEntry = pStack->a[i].iEntry; 680 if (rtLockValidatorDdMoreWorkLeft(pRec, iEntry, pFirstSibling)) 665 pRec = pStack->a[i].pRec; 666 iEntry = pStack->a[i].iEntry; 667 668 /* Examine it. */ 669 uint32_t u32Magic = pRec->Core.u32Magic; 670 if (u32Magic == RTLOCKVALRECEXCL_MAGIC) 671 pRec = pRec->Excl.pSibling; 672 else if (u32Magic == RTLOCKVALRECSHRD_MAGIC) 681 673 { 682 enmState = pStack->a[i].enmState; 683 pThread = pStack->a[i].pThread; 684 pStack->c = i; 685 break; 674 if (iEntry + 1 < pRec->Shared.cAllocated) 675 break; /* continue processing this record. */ 676 pRec = pRec->Shared.pSibling; 686 677 } 678 else 679 { 680 Assert( u32Magic == RTLOCKVALRECEXCL_MAGIC_DEAD 681 || u32Magic == RTLOCKVALRECSHRD_MAGIC_DEAD); 682 continue; 683 } 684 685 /* Any next record to advance to? */ 686 if ( !pRec 687 || pRec == pStack->a[i].pFirstSibling) 688 continue; 689 iEntry = UINT32_MAX; 690 break; 687 691 } 692 693 /* Restore the rest of the state and update the stack. */ 694 pFirstSibling = pStack->a[i].pFirstSibling; 695 enmState = pStack->a[i].enmState; 696 pThread = pStack->a[i].pThread; 697 pStack->c = i; 688 698 } 689 699 /* else: see if there is another thread to check for this lock. */ … … 888 898 uint32_t uSubClass, const char *pszName, void *hLock) 889 899 { 900 RTLOCKVAL_ASSERT_PTR_ALIGN(pRec); 901 RTLOCKVAL_ASSERT_PTR_ALIGN(hLock); 902 890 903 pRec->Core.u32Magic = RTLOCKVALRECEXCL_MAGIC; 891 904 pRec->fEnabled = RTLockValidatorIsEnabled(); … … 1187 1200 uint32_t uSubClass, const char *pszName, void *hLock) 1188 1201 { 1202 RTLOCKVAL_ASSERT_PTR_ALIGN(pRec); 1203 RTLOCKVAL_ASSERT_PTR_ALIGN(hLock); 1204 1189 1205 pRec->Core.u32Magic = RTLOCKVALRECSHRD_MAGIC; 1190 1206 pRec->uSubClass = uSubClass; … … 1770 1786 1771 1787 1788 RTDECL(void *) RTLockValidatorQueryBlocking(RTTHREAD hThread) 1789 { 1790 void *pvLock = NULL; 1791 PRTTHREADINT pThread = rtThreadGet(hThread); 1792 if (pThread) 1793 { 1794 RTTHREADSTATE enmState = rtThreadGetState(pThread); 1795 if (RTTHREAD_IS_SLEEPING(enmState)) 1796 { 1797 rtLockValidatorSerializeDetectionEnter(); 1798 1799 enmState = rtThreadGetState(pThread); 1800 if (RTTHREAD_IS_SLEEPING(enmState)) 1801 { 1802 PRTLOCKVALRECUNION pRec = rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pRec); 1803 if (pRec) 1804 { 1805 switch (pRec->Core.u32Magic) 1806 { 1807 case RTLOCKVALRECEXCL_MAGIC: 1808 pvLock = pRec->Excl.hLock; 1809 break; 1810 1811 case RTLOCKVALRECSHRDOWN_MAGIC: 1812 pRec = (PRTLOCKVALRECUNION)pRec->ShrdOwner.pSharedRec; 1813 if (!pRec || pRec->Core.u32Magic != RTLOCKVALRECSHRD_MAGIC) 1814 break; 1815 case RTLOCKVALRECSHRD_MAGIC: 1816 pvLock = pRec->Shared.hLock; 1817 break; 1818 } 1819 if (RTThreadGetState(pThread) != enmState) 1820 pvLock = NULL; 1821 } 1822 } 1823 1824 rtLockValidatorSerializeDetectionLeave(); 1825 } 1826 rtThreadRelease(pThread); 1827 } 1828 return pvLock; 1829 } 1830 RT_EXPORT_SYMBOL(RTLockValidatorQueryBlocking); 1831 1832 1772 1833 RTDECL(bool) RTLockValidatorSetEnabled(bool fEnabled) 1773 1834 {
Note:
See TracChangeset
for help on using the changeset viewer.