Changeset 25682 in vbox
- Timestamp:
- Jan 7, 2010 3:23:30 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56400
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/lockvalidator.h
r25645 r25682 98 98 #define RTLOCKVALSRCPOS_INIT_NORMAL_API() \ 99 99 RTLOCKVALSRCPOS_INIT(__FILE__, __LINE__, __PRETTY_FUNCTION__, (uintptr_t)ASMReturnAddress()) 100 101 /** @def RTLOCKVALSRCPOS_INIT_POS_NO_ID 102 * Initializer for a RTLOCKVALSRCPOS variable when no @c uId is present. 103 * Assumes iprt/asm.h is included. 104 */ 105 #define RTLOCKVALSRCPOS_INIT_POS_NO_ID() \ 106 RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, (uintptr_t)ASMReturnAddress()) 100 107 101 108 /** Pointer to a record of one ownership share. */ … … 142 149 uint32_t volatile uSubClass; 143 150 /** The lock class. */ 144 RTLOCKVAL IDATORCLASShClass;151 RTLOCKVALCLASS hClass; 145 152 /** Pointer to the lock. */ 146 153 RTHCPTR hLock; … … 197 204 uint32_t volatile uSubClass; 198 205 /** The lock class. */ 199 RTLOCKVAL IDATORCLASShClass;206 RTLOCKVALCLASS hClass; 200 207 /** Pointer to the lock. */ 201 208 RTHCPTR hLock; … … 240 247 /** Not allowed to be taken with any other locks in the same class. 241 248 * This is the recommended value. */ 242 #define RTLOCKVAL IDATOR_SUB_CLASS_NONEUINT32_C(0)249 #define RTLOCKVAL_SUB_CLASS_NONE UINT32_C(0) 243 250 /** Any order is allowed within the class. */ 244 #define RTLOCKVAL IDATOR_SUB_CLASS_ANYUINT32_C(1)251 #define RTLOCKVAL_SUB_CLASS_ANY UINT32_C(1) 245 252 /** The first user value. */ 246 #define RTLOCKVAL IDATOR_SUB_CLASS_USERUINT32_C(16)253 #define RTLOCKVAL_SUB_CLASS_USER UINT32_C(16) 247 254 /** @} */ 248 255 … … 263 270 * 264 271 * @param pRec The record. 265 * @param hClass The class. If NIL, the no lock order 266 * validation will be performed on this lock. 272 * @param hClass The class (no reference consumed). If NIL, the 273 * no lock order validation will be performed on 274 * this lock. 267 275 * @param uSubClass The sub-class. This is used to define lock 268 276 * order inside the same class. If you don't know, 269 * then pass RTLOCKVAL IDATOR_SUB_CLASS_NONE.277 * then pass RTLOCKVAL_SUB_CLASS_NONE. 270 278 * @param pszName The lock name (optional). 271 279 * @param hLock The lock handle. 272 280 */ 273 RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVAL IDATORCLASS hClass,281 RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, 274 282 uint32_t uSubClass, const char *pszName, void *hLock); 275 283 /** … … 289 297 * @return VINF_SUCCESS or VERR_NO_MEMORY. 290 298 * @param ppRec Where to return the record pointer. 291 * @param hClass The class. If NIL, the no lock order 292 * validation will be performed on this lock. 299 * @param hClass The class (no reference consumed). If NIL, the 300 * no lock order validation will be performed on 301 * this lock. 293 302 * @param uSubClass The sub-class. This is used to define lock 294 303 * order inside the same class. If you don't know, 295 * then pass RTLOCKVAL IDATOR_SUB_CLASS_NONE.304 * then pass RTLOCKVAL_SUB_CLASS_NONE. 296 305 * @param pszName The lock name (optional). 297 306 * @param hLock The lock handle. 298 307 */ 299 RTDECL(int) RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVAL IDATORCLASS hClass,308 RTDECL(int) RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, 300 309 uint32_t uSubClass, const char *pszName, void *hLock); 301 310 … … 486 495 * 487 496 * @param pRec The shared lock record. 488 * @param hClass The class. If NIL, the no lock order 489 * validation will be performed on this lock. 497 * @param hClass The class (no reference consumed). If NIL, the 498 * no lock order validation will be performed on 499 * this lock. 490 500 * @param uSubClass The sub-class. This is used to define lock 491 501 * order inside the same class. If you don't know, 492 * then pass RTLOCKVAL IDATOR_SUB_CLASS_NONE.502 * then pass RTLOCKVAL_SUB_CLASS_NONE. 493 503 * @param pszName The lock name (optional). 494 504 * @param hLock The lock handle. … … 497 507 * semaphore logic should be used. 498 508 */ 499 RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVAL IDATORCLASS hClass, uint32_t uSubClass,509 RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, 500 510 const char *pszName, void *hLock, bool fSignaller); 501 511 /** … … 711 721 712 722 713 /*RTDECL(int) RTLockValidatorClassCreate();*/ 714 715 723 724 /** 725 * Creates a new lock validator class, all properties specified. 726 * 727 * @returns IPRT status code 728 * @param phClass Where to return the class handle. 729 * @param pSrcPos The source position of the create call. 730 * @param fAutodidact Whether the class should be allowed to teach 731 * itself new locking order rules (true), or if the 732 * user will teach it all it needs to know (false). 733 * @param cMsMinDeadlock Used to raise the sleep interval at which 734 * deadlock detection kicks in. Minimum is 1 ms, 735 * while RT_INDEFINITE_WAIT will disable it. 736 * @param cMsMinOrder Used to raise the sleep interval at which lock 737 * order validation kicks in. Minimum is 1 ms, 738 * while RT_INDEFINITE_WAIT will disable it. 739 */ 740 RTDECL(int) RTLockValidatorClassCreateEx(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos, 741 bool fAutodidact, RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder); 742 743 /** 744 * Creates a new lock validator class. 745 * 746 * @returns IPRT status code 747 * @param phClass Where to return the class handle. 748 * @param fAutodidact Whether the class should be allowed to teach 749 * itself new locking order rules (true), or if the 750 * user will teach it all it needs to know (false). 751 * @param pszFile The source position of the call, file. 752 * @param iLine The source position of the call, line. 753 * @param pszFunction The source position of the call, function. 754 */ 755 RTDECL(int) RTLockValidatorClassCreate(PRTLOCKVALCLASS phClass, bool fAutodidact, RT_SRC_POS_DECL); 756 757 /** 758 * Finds a class for the specified source position. 759 * 760 * @returns A handle to the class (not retained!) or NIL_RTLOCKVALCLASS. 761 * @param pSrcPos The source position. 762 */ 763 RTDECL(RTLOCKVALCLASS) RTLockValidatorClassFindForSrcPos(PRTLOCKVALSRCPOS pSrcPos); 764 765 /** 766 * Finds or creates a class given the source position. 767 * 768 * @returns Class handle (not retained!) or NIL_RTLOCKVALCLASS. 769 * @param pszFile The source file. 770 * @param iLine The line in that source file. 771 * @param pszFunction The function name. 772 */ 773 RTDECL(RTLOCKVALCLASS) RTLockValidatorClassForSrcPos(RT_SRC_POS_DECL); 774 775 /** 776 * Retains a reference to a lock validator class. 777 * 778 * @returns New reference count; UINT32_MAX if the handle is invalid. 779 * @param hClass Handle to the class. 780 */ 781 RTDECL(uint32_t) RTLockValidatorClassRetain(RTLOCKVALCLASS hClass); 782 783 /** 784 * Releases a reference to a lock validator class. 785 * 786 * @returns New reference count; UINT32_MAX if the handle is invalid. 787 * @param hClass Handle to the class. 788 */ 789 RTDECL(uint32_t) RTLockValidatorClassRelease(RTLOCKVALCLASS hClass); 790 791 /** 792 * Teaches the class @a hClass that locks in the class @a hPriorClass can be 793 * held when taking a lock of class @hClass 794 * 795 * @returns IPRT status. 796 * @param hClass Handle to the pupil class. 797 * @param hPriorClass Handle to the class that can be held prior to 798 * taking a lock in the pupil class. (No reference 799 * is consumed.) 800 */ 801 RTDECL(int) RTLockValidatorClassAddPriorClass(RTLOCKVALCLASS hClass, RTLOCKVALCLASS hPriorClass); 716 802 717 803 /** -
trunk/include/iprt/types.h
r25645 r25682 355 355 356 356 /** Generic function pointer. 357 * With -pedantic, gcc-4 complains when casting a function to a data object, for example 357 * With -pedantic, gcc-4 complains when casting a function to a data object, for 358 * example: 358 359 * 359 360 * @code … … 365 366 * @endcode 366 367 * 367 * The compiler would warn with "ISO C++ forbids casting between pointer-to-function and368 * pointer-to- object". The purpose of this warning is not to bother the programmer but to369 * point out that he is probably doing something dangerous, assigning a pointer to executable370 * code to a data object.368 * The compiler would warn with "ISO C++ forbids casting between 369 * pointer-to-function and pointer-to-object". The purpose of this warning is 370 * not to bother the programmer but to point out that he is probably doing 371 * something dangerous, assigning a pointer to executable code to a data object. 371 372 */ 372 373 typedef FNRT *PFNRT; 374 375 /** Millisecond interval. */ 376 typedef uint32_t RTMSINTERVAL; 377 /** Pointer to a millisecond interval. */ 378 typedef RTMSINTERVAL *PRTMSINTERVAL; 379 /** Pointer to a const millisecond interval. */ 380 typedef const RTMSINTERVAL *PCRTMSINTERVAL; 373 381 374 382 … … 1127 1135 1128 1136 /** Lock validator class handle. */ 1129 typedef R3R0PTRTYPE(struct RTLOCKVAL IDATORCLASSINT *) RTLOCKVALIDATORCLASS;1137 typedef R3R0PTRTYPE(struct RTLOCKVALCLASSINT *) RTLOCKVALCLASS; 1130 1138 /** Pointer to a lock validator class handle. */ 1131 typedef RTLOCKVAL IDATORCLASS *PRTLOCKVALIDATORCLASS;1139 typedef RTLOCKVALCLASS *PRTLOCKVALCLASS; 1132 1140 /** Nil lock validator class handle. */ 1133 #define NIL_RTLOCKVAL IDATORCLASS ((RTLOCKVALIDATORCLASS)0)1141 #define NIL_RTLOCKVALCLASS ((RTLOCKVALCLASS)0) 1134 1142 1135 1143 /** Ring-0 memory object handle. */ -
trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
r25662 r25682 5 5 6 6 /* 7 * Copyright (C) 2009 Sun Microsystems, Inc.7 * Copyright (C) 2009-2010 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 88 88 89 89 90 /** 91 * Reference to another class. 92 */ 93 typedef struct RTLOCKVALCLASSREF 94 { 95 /** The class. */ 96 RTLOCKVALCLASS hClass; 97 /** The number of lookups of this class. */ 98 uint32_t volatile cLookups; 99 /** Indicates whether the entry was added automatically during order checking 100 * (true) or manually via the API (false). */ 101 bool fAutodidacticism; 102 /** Reserved / explicit alignment padding. */ 103 bool afReserved[3]; 104 } RTLOCKVALCLASSREF; 105 /** Pointer to a class reference. */ 106 typedef RTLOCKVALCLASSREF *PRTLOCKVALCLASSREF; 107 108 109 /** Pointer to a chunk of class references. */ 110 typedef struct RTLOCKVALCLASSREFCHUNK *PRTLOCKVALCLASSREFCHUNK; 111 /** 112 * Chunk of class references. 113 */ 114 typedef struct RTLOCKVALCLASSREFCHUNK 115 { 116 /** Array of refs. */ 117 #if 0 /** @todo for testing alloction of new chunks. */ 118 RTLOCKVALCLASSREF aRefs[ARCH_BITS == 32 ? 10 : 8]; 119 #else 120 RTLOCKVALCLASSREF aRefs[2]; 121 #endif 122 /** Pointer to the next chunk. */ 123 PRTLOCKVALCLASSREFCHUNK volatile pNext; 124 } RTLOCKVALCLASSREFCHUNK; 125 126 127 /** 128 * Lock class. 129 */ 130 typedef struct RTLOCKVALCLASSINT 131 { 132 /** AVL node core. */ 133 AVLLU32NODECORE Core; 134 /** Magic value (RTLOCKVALCLASS_MAGIC). */ 135 uint32_t volatile u32Magic; 136 /** Reference counter. See RTLOCKVALCLASS_MAX_REFS. */ 137 uint32_t volatile cRefs; 138 /** Whether the class is allowed to teach it self new locking order rules. */ 139 bool fAutodidact; 140 /** Whether this class is in the tree. */ 141 bool fInTree; 142 bool afReserved[2]; /**< Explicit padding */ 143 /** The minimum wait interval for which we do deadlock detection 144 * (milliseconds). */ 145 RTMSINTERVAL cMsMinDeadlock; 146 /** The minimum wait interval for which we do order checks (milliseconds). */ 147 RTMSINTERVAL cMsMinOrder; 148 /** More padding. */ 149 uint32_t au32Reserved[ARCH_BITS == 32 ? 6 : 3]; 150 /** Classes that may be taken prior to this one. 151 * This is a linked list where each node contains a chunk of locks so that we 152 * reduce the number of allocations as well as localize the data. */ 153 RTLOCKVALCLASSREFCHUNK PriorLocks; 154 /** Hash table containing frequently encountered prior locks. */ 155 PRTLOCKVALCLASSREF apPriorLocksHash[11]; 156 #define RTLOCKVALCLASS_HASH_STATS 157 #ifdef RTLOCKVALCLASS_HASH_STATS 158 /** Hash hits. */ 159 uint32_t volatile cHashHits; 160 /** Hash misses. */ 161 uint32_t volatile cHashMisses; 162 #endif 163 /** Where this class was created. 164 * This is mainly used for finding automatically created lock classes. 165 * @remarks The strings are stored after this structure so we won't crash 166 * if the class lives longer than the module (dll/so/dylib) that 167 * spawned it. */ 168 RTLOCKVALSRCPOS CreatePos; 169 } RTLOCKVALCLASSINT; 170 AssertCompileSize(AVLLU32NODECORE, ARCH_BITS == 32 ? 20 : 32); 171 AssertCompileMemberOffset(RTLOCKVALCLASSINT, PriorLocks, 64); 172 173 90 174 /******************************************************************************* 91 175 * Defined Constants And Macros * … … 94 178 * Only used when fighting bugs. */ 95 179 #if 1 96 # define RTLOCKVAL_ASSERT_PTR_ALIGN(p) 180 # define RTLOCKVAL_ASSERT_PTR_ALIGN(p) \ 97 181 AssertMsg(!((uintptr_t)(p) & (sizeof(uintptr_t) - 1)), ("%p\n", (p))); 98 182 #else 99 183 # define RTLOCKVAL_ASSERT_PTR_ALIGN(p) do { } while (0) 100 184 #endif 185 186 /** Hashes the class handle (pointer) into an apPriorLocksHash index. */ 187 #define RTLOCKVALCLASS_HASH(hClass) \ 188 ( (uintptr_t)(hClass) \ 189 % ( RT_SIZEOFMEMB(RTLOCKVALCLASSINT, apPriorLocksHash) \ 190 / sizeof(PRTLOCKVALCLASSREF)) ) 191 192 /** The max value for RTLOCKVALCLASSINT::cRefs. */ 193 #define RTLOCKVALCLASS_MAX_REFS UINT32_C(0xffff0000) 194 /** The max value for RTLOCKVALCLASSREF::cLookups. */ 195 #define RTLOCKVALCLASSREF_MAX_LOOKUPS UINT32_C(0xfffe0000) 196 /** The absolute max value for RTLOCKVALCLASSREF::cLookups at which it will 197 * be set back to RTLOCKVALCLASSREF_MAX_LOOKUPS. */ 198 #define RTLOCKVALCLASSREF_MAX_LOOKUPS_FIX UINT32_C(0xffff0000) 101 199 102 200 … … 129 227 static bool volatile g_fLockValidatorMayPanic = false; 130 228 #endif 229 /** Serializing class tree insert and lookups. */ 230 static RTSEMRW g_hLockValClassTreeRWLock = NIL_RTSEMRW; 231 /** Class tree. */ 232 static PAVLLU32NODECORE g_LockValClassTree = NULL; 233 /** Critical section serializing the teaching new rules to the classes. */ 234 static RTCRITSECT g_LockValClassTeachCS; 235 236 237 /******************************************************************************* 238 * Internal Functions * 239 *******************************************************************************/ 240 static void rtLockValidatorClassDestroy(RTLOCKVALCLASSINT *pClass); 241 242 243 /** 244 * Lazy initialization of the lock validator globals. 245 */ 246 static void rtLockValidatorLazyInit(void) 247 { 248 static uint32_t volatile s_fInitializing = false; 249 if (ASMAtomicCmpXchgU32(&s_fInitializing, true, false)) 250 { 251 if (!RTCritSectIsInitialized(&g_LockValClassTeachCS)) 252 RTCritSectInit(&g_LockValClassTeachCS); 253 254 if (g_hLockValClassTreeRWLock == NIL_RTSEMRW) 255 { 256 RTSEMRW hSemRW; 257 int rc = RTSemRWCreate(&hSemRW); 258 if (RT_SUCCESS(rc)) 259 ASMAtomicWriteHandle(&g_hLockValClassTreeRWLock, hSemRW); 260 } 261 262 if (g_hLockValidatorXRoads == NIL_RTSEMXROADS) 263 { 264 RTSEMXROADS hXRoads; 265 int rc = RTSemXRoadsCreate(&hXRoads); 266 if (RT_SUCCESS(rc)) 267 ASMAtomicWriteHandle(&g_hLockValidatorXRoads, hXRoads); 268 } 269 270 /** @todo register some cleanup callback if we care. */ 271 272 ASMAtomicWriteU32(&s_fInitializing, false); 273 } 274 else 275 RTThreadYield(); 276 } 277 131 278 132 279 … … 321 468 * @param pSrc The source. Can be NULL. 322 469 */ 323 DECL_FORCE_INLINE(void) rtLockValidator CopySrcPos(PRTLOCKVALSRCPOS pDst, PCRTLOCKVALSRCPOS pSrc)470 DECL_FORCE_INLINE(void) rtLockValidatorSrcPosCopy(PRTLOCKVALSRCPOS pDst, PCRTLOCKVALSRCPOS pSrc) 324 471 { 325 472 if (pSrc) … … 345 492 * @param pSrcPos The source position record. 346 493 */ 347 DECL_FORCE_INLINE(void) rtLockValidator InitSrcPos(PRTLOCKVALSRCPOS pSrcPos)494 DECL_FORCE_INLINE(void) rtLockValidatorSrcPosInit(PRTLOCKVALSRCPOS pSrcPos) 348 495 { 349 496 pSrcPos->pszFile = NULL; … … 357 504 358 505 506 /* sdbm: 507 This algorithm was created for sdbm (a public-domain reimplementation of 508 ndbm) database library. it was found to do well in scrambling bits, 509 causing better distribution of the keys and fewer splits. it also happens 510 to be a good general hashing function with good distribution. the actual 511 function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below 512 is the faster version used in gawk. [there is even a faster, duff-device 513 version] the magic constant 65599 was picked out of thin air while 514 experimenting with different constants, and turns out to be a prime. 515 this is one of the algorithms used in berkeley db (see sleepycat) and 516 elsewhere. */ 517 DECL_FORCE_INLINE(uint32_t) sdbm(const char *str, uint32_t hash) 518 { 519 uint8_t *pu8 = (uint8_t *)str; 520 int c; 521 522 while ((c = *pu8++)) 523 hash = c + (hash << 6) + (hash << 16) - hash; 524 525 return hash; 526 } 527 528 529 /** 530 * Hashes the specified source position. 531 * 532 * @returns Hash. 533 * @param pSrcPos The source position record. 534 */ 535 static uint32_t rtLockValidatorSrcPosHash(PCRTLOCKVALSRCPOS pSrcPos) 536 { 537 uint32_t uHash; 538 if ( ( pSrcPos->pszFile 539 || pSrcPos->pszFunction) 540 && pSrcPos->uLine != 0) 541 { 542 uHash = 0; 543 if (pSrcPos->pszFile) 544 uHash = sdbm(pSrcPos->pszFile, uHash); 545 if (pSrcPos->pszFunction) 546 uHash = sdbm(pSrcPos->pszFunction, uHash); 547 uHash += pSrcPos->uLine; 548 } 549 else 550 { 551 Assert(pSrcPos->uId); 552 uHash = (uint32_t)pSrcPos->uId; 553 } 554 555 return uHash; 556 } 557 558 559 /** 560 * Compares two source positions. 561 * 562 * @returns 0 if equal, < 0 if pSrcPos1 is smaller than pSrcPos2, > 0 if 563 * otherwise. 564 * @param pSrcPos1 The first source position. 565 * @param pSrcPos2 The second source position. 566 */ 567 static int rtLockValidatorSrcPosCompare(PCRTLOCKVALSRCPOS pSrcPos1, PCRTLOCKVALSRCPOS pSrcPos2) 568 { 569 if (pSrcPos1->uLine != pSrcPos2->uLine) 570 return pSrcPos1->uLine < pSrcPos2->uLine ? -1 : 1; 571 572 int iDiff = RTStrCmp(pSrcPos1->pszFile, pSrcPos2->pszFile); 573 if (iDiff != 0) 574 return iDiff; 575 576 iDiff = RTStrCmp(pSrcPos1->pszFunction, pSrcPos2->pszFunction); 577 if (iDiff != 0) 578 return iDiff; 579 580 if (pSrcPos1->uId != pSrcPos2->uId) 581 return pSrcPos1->uId < pSrcPos2->uId ? -1 : 1; 582 return 0; 583 } 584 585 586 359 587 /** 360 588 * Serializes destruction of RTLOCKVALREC* and RTTHREADINT structures. … … 416 644 Assert(pPerThread->cReadLocks == 0); 417 645 Assert(pPerThread->fInValidator == false); 646 } 647 648 649 RTDECL(int) RTLockValidatorClassCreateEx(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos, 650 bool fAutodidact, RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder) 651 { 652 Assert(cMsMinDeadlock >= 1); 653 Assert(cMsMinOrder >= 1); 654 AssertPtr(pSrcPos); 655 656 size_t const cbFile = pSrcPos->pszFile ? strlen(pSrcPos->pszFile) + 1 : 0; 657 size_t const cbFunction = pSrcPos->pszFile ? strlen(pSrcPos->pszFunction) + 1 : 0; 658 RTLOCKVALCLASSINT *pThis = (RTLOCKVALCLASSINT *)RTMemAlloc(sizeof(*pThis) + cbFile + cbFunction); 659 if (!pThis) 660 return VERR_NO_MEMORY; 661 662 pThis->Core.Key = rtLockValidatorSrcPosHash(pSrcPos); 663 pThis->Core.uchHeight = 0; 664 pThis->Core.pLeft = NULL; 665 pThis->Core.pRight = NULL; 666 pThis->Core.pList = NULL; 667 pThis->u32Magic = RTLOCKVALCLASS_MAGIC; 668 pThis->cRefs = 1; 669 pThis->fAutodidact = fAutodidact; 670 pThis->fInTree = false; 671 for (unsigned i = 0; i < RT_ELEMENTS(pThis->afReserved); i++) 672 pThis->afReserved[i] = false; 673 pThis->cMsMinDeadlock = cMsMinDeadlock; 674 pThis->cMsMinOrder = cMsMinOrder; 675 for (unsigned i = 0; i < RT_ELEMENTS(pThis->au32Reserved); i++) 676 pThis->au32Reserved[i] = 0; 677 for (unsigned i = 0; i < RT_ELEMENTS(pThis->au32Reserved); i++) 678 { 679 pThis->PriorLocks.aRefs[i].hClass = NIL_RTLOCKVALCLASS; 680 pThis->PriorLocks.aRefs[i].cLookups = 0; 681 pThis->PriorLocks.aRefs[i].fAutodidacticism = false; 682 pThis->PriorLocks.aRefs[i].afReserved[0] = false; 683 pThis->PriorLocks.aRefs[i].afReserved[1] = false; 684 pThis->PriorLocks.aRefs[i].afReserved[2] = false; 685 } 686 pThis->PriorLocks.pNext = NULL; 687 for (unsigned i = 0; i < RT_ELEMENTS(pThis->apPriorLocksHash); i++) 688 pThis->apPriorLocksHash[i] = NULL; 689 rtLockValidatorSrcPosCopy(&pThis->CreatePos, pSrcPos); 690 char *pszDst = (char *)(pThis + 1); 691 pThis->CreatePos.pszFile = pSrcPos->pszFile ? (char *)memcpy(pszDst, pSrcPos->pszFile, cbFile) : NULL; 692 pszDst += cbFile; 693 pThis->CreatePos.pszFunction= pSrcPos->pszFunction ? (char *)memcpy(pszDst, pSrcPos->pszFunction, cbFunction) : NULL; 694 Assert(rtLockValidatorSrcPosHash(&pThis->CreatePos) == pThis->Core.Key); 695 696 *phClass = pThis; 697 return VINF_SUCCESS; 698 } 699 700 701 RTDECL(int) RTLockValidatorClassCreate(PRTLOCKVALCLASS phClass, bool fAutodidact, RT_SRC_POS_DECL) 702 { 703 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_POS_NO_ID(); 704 return RTLockValidatorClassCreateEx(phClass, &SrcPos, fAutodidact, 705 1 /*cMsMinDeadlock*/, 1 /*cMsMinOrder*/); 706 } 707 708 709 /** 710 * Internal class retainer. 711 * @returns The new reference count. 712 * @param pClass The class. 713 */ 714 DECL_FORCE_INLINE(uint32_t) rtLockValidatorClassRetain(RTLOCKVALCLASSINT *pClass) 715 { 716 uint32_t cRefs = ASMAtomicIncU32(&pClass->cRefs); 717 if (cRefs > RTLOCKVALCLASS_MAX_REFS) 718 ASMAtomicWriteU32(&pClass->cRefs, RTLOCKVALCLASS_MAX_REFS); 719 return cRefs; 720 } 721 722 723 /** 724 * Validates and retains a lock validator class. 725 * 726 * @returns @a hClass on success, NIL_RTLOCKVALCLASS on failure. 727 * @param hClass The class handle. NIL_RTLOCKVALCLASS is ok. 728 */ 729 DECL_FORCE_INLINE(RTLOCKVALCLASS) rtLockValidatorClassValidateAndRetain(RTLOCKVALCLASS hClass) 730 { 731 if (hClass == NIL_RTLOCKVALCLASS) 732 return hClass; 733 AssertPtrReturn(hClass, NIL_RTLOCKVALCLASS); 734 AssertReturn(hClass->u32Magic == RTLOCKVALCLASS_MAGIC, NIL_RTLOCKVALCLASS); 735 rtLockValidatorClassRetain(hClass); 736 return hClass; 737 } 738 739 740 /** 741 * Internal class releaser. 742 * @returns The new reference count. 743 * @param pClass The class. 744 */ 745 DECL_FORCE_INLINE(uint32_t) rtLockValidatorClassRelease(RTLOCKVALCLASSINT *pClass) 746 { 747 uint32_t cRefs = ASMAtomicDecU32(&pClass->cRefs); 748 if (cRefs + 1 == RTLOCKVALCLASS_MAX_REFS) 749 ASMAtomicWriteU32(&pClass->cRefs, RTLOCKVALCLASS_MAX_REFS); 750 else if (!cRefs) 751 rtLockValidatorClassDestroy(pClass); 752 return cRefs; 753 } 754 755 756 /** 757 * Destroys a class once there are not more references to it. 758 * 759 * @param Class The class. 760 */ 761 static void rtLockValidatorClassDestroy(RTLOCKVALCLASSINT *pClass) 762 { 763 AssertReturnVoid(pClass->fInTree); 764 ASMAtomicWriteU32(&pClass->u32Magic, RTLOCKVALCLASS_MAGIC_DEAD); 765 766 PRTLOCKVALCLASSREFCHUNK pChunk = &pClass->PriorLocks; 767 while (pChunk) 768 { 769 for (uint32_t i = 0; i < RT_ELEMENTS(pChunk->aRefs); i++) 770 { 771 RTLOCKVALCLASSINT *pClass2 = pChunk->aRefs[i].hClass; 772 if (pClass2 != NIL_RTLOCKVALCLASS) 773 { 774 pChunk->aRefs[i].hClass = NIL_RTLOCKVALCLASS; 775 rtLockValidatorClassRelease(pClass2); 776 } 777 } 778 779 PRTLOCKVALCLASSREFCHUNK pNext = pChunk->pNext; 780 pChunk->pNext = NULL; 781 if (pChunk != &pClass->PriorLocks) 782 RTMemFree(pChunk); 783 pNext = pChunk; 784 } 785 786 RTMemFree(pClass); 787 } 788 789 790 RTDECL(RTLOCKVALCLASS) RTLockValidatorClassFindForSrcPos(PRTLOCKVALSRCPOS pSrcPos) 791 { 792 if (g_hLockValClassTreeRWLock == NIL_RTSEMRW) 793 rtLockValidatorLazyInit(); 794 int rcLock = RTSemRWRequestRead(g_hLockValClassTreeRWLock, RT_INDEFINITE_WAIT); 795 796 uint32_t uSrcPosHash = rtLockValidatorSrcPosHash(pSrcPos); 797 RTLOCKVALCLASSINT *pClass = (RTLOCKVALCLASSINT *)RTAvllU32Get(&g_LockValClassTree, uSrcPosHash); 798 while (pClass) 799 { 800 if (rtLockValidatorSrcPosCompare(&pClass->CreatePos, pSrcPos) == 0) 801 { 802 rtLockValidatorClassRetain(pClass); 803 break; 804 } 805 pClass = (RTLOCKVALCLASSINT *)pClass->Core.pList; 806 } 807 808 if (RT_SUCCESS(rcLock)) 809 RTSemRWReleaseRead(g_hLockValClassTreeRWLock); 810 return pClass; 811 } 812 813 814 RTDECL(RTLOCKVALCLASS) RTLockValidatorClassForSrcPos(RT_SRC_POS_DECL) 815 { 816 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_POS_NO_ID(); 817 RTLOCKVALCLASS hClass = RTLockValidatorClassFindForSrcPos(&SrcPos); 818 if (hClass == NIL_RTLOCKVALCLASS) 819 { 820 /* 821 * Create a new class and insert it into the tree. 822 */ 823 int rc = RTLockValidatorClassCreateEx(&hClass, &SrcPos, true /*fAutodidact*/, 824 1 /*cMsMinDeadlock*/, 1 /*cMsMinOrder*/); 825 if (RT_SUCCESS(rc)) 826 { 827 if (g_hLockValClassTreeRWLock == NIL_RTSEMRW) 828 rtLockValidatorLazyInit(); 829 int rcLock = RTSemRWRequestWrite(g_hLockValClassTreeRWLock, RT_INDEFINITE_WAIT); 830 831 Assert(!hClass->fInTree); 832 hClass->fInTree = RTAvllU32Insert(&g_LockValClassTree, &hClass->Core); 833 Assert(hClass->fInTree); 834 835 if (RT_SUCCESS(rcLock)) 836 RTSemRWReleaseWrite(g_hLockValClassTreeRWLock); 837 return hClass; 838 } 839 } 840 return hClass; 841 } 842 843 844 RTDECL(uint32_t) RTLockValidatorClassRetain(RTLOCKVALCLASS hClass) 845 { 846 RTLOCKVALCLASSINT *pClass = hClass; 847 AssertPtrReturn(pClass, UINT32_MAX); 848 AssertReturn(pClass->u32Magic == RTLOCKVALCLASS_MAGIC, UINT32_MAX); 849 return rtLockValidatorClassRetain(pClass); 850 } 851 852 853 RTDECL(uint32_t) RTLockValidatorClassRelease(RTLOCKVALCLASS hClass) 854 { 855 RTLOCKVALCLASSINT *pClass = hClass; 856 AssertPtrReturn(pClass, UINT32_MAX); 857 AssertReturn(pClass->u32Magic == RTLOCKVALCLASS_MAGIC, UINT32_MAX); 858 return rtLockValidatorClassRelease(pClass); 859 } 860 861 862 /** 863 * Worker for rtLockValidatorClassIsPriorClass that does a linear search thru 864 * all the chunks for @a pPriorClass. 865 * 866 * @returns true / false. 867 * @param pClass The class to search. 868 * @param pPriorClass The class to search for. 869 */ 870 static bool rtLockValidatorClassIsPriorClassByLinearSearch(RTLOCKVALCLASSINT *pClass, RTLOCKVALCLASSINT *pPriorClass) 871 { 872 for (PRTLOCKVALCLASSREFCHUNK pChunk = &pClass->PriorLocks; pChunk; pChunk = pChunk->pNext) 873 for (uint32_t i = 0; i < RT_ELEMENTS(pChunk->aRefs); i++) 874 { 875 if (pChunk->aRefs[i].hClass == pPriorClass) 876 { 877 uint32_t cLookups = ASMAtomicIncU32(&pChunk->aRefs[i].cLookups); 878 if (RT_UNLIKELY(cLookups >= RTLOCKVALCLASSREF_MAX_LOOKUPS_FIX)) 879 { 880 ASMAtomicWriteU32(&pChunk->aRefs[i].cLookups, RTLOCKVALCLASSREF_MAX_LOOKUPS); 881 cLookups = RTLOCKVALCLASSREF_MAX_LOOKUPS; 882 } 883 884 /* update the hash table entry. */ 885 PRTLOCKVALCLASSREF *ppHashEntry = &pClass->apPriorLocksHash[RTLOCKVALCLASS_HASH(pPriorClass)]; 886 if ( !(*ppHashEntry) 887 || (*ppHashEntry)->cLookups + 128 < cLookups) 888 ASMAtomicWritePtr((void * volatile *)ppHashEntry, &pChunk->aRefs[i]); 889 890 #ifdef RTLOCKVALCLASS_HASH_STATS 891 ASMAtomicIncU32(&pClass->cHashMisses); 892 #endif 893 return true; 894 } 895 } 896 897 return false; 898 } 899 900 901 /** 902 * Checks if @a pPriorClass is a known prior class. 903 * 904 * @returns true / false. 905 * @param pClass The class to search. 906 * @param pPriorClass The class to search for. 907 */ 908 DECL_FORCE_INLINE(bool) rtLockValidatorClassIsPriorClass(RTLOCKVALCLASSINT *pClass, RTLOCKVALCLASSINT *pPriorClass) 909 { 910 /* 911 * Hash lookup here. 912 */ 913 PRTLOCKVALCLASSREF pRef = pClass->apPriorLocksHash[RTLOCKVALCLASS_HASH(pPriorClass)]; 914 if ( pRef 915 && pRef->hClass == pPriorClass) 916 { 917 uint32_t cLookups = ASMAtomicIncU32(&pRef->cLookups); 918 if (RT_UNLIKELY(cLookups >= RTLOCKVALCLASSREF_MAX_LOOKUPS_FIX)) 919 ASMAtomicWriteU32(&pRef->cLookups, RTLOCKVALCLASSREF_MAX_LOOKUPS); 920 #ifdef RTLOCKVALCLASS_HASH_STATS 921 ASMAtomicIncU32(&pClass->cHashHits); 922 #endif 923 return true; 924 } 925 926 return rtLockValidatorClassIsPriorClassByLinearSearch(pClass, pPriorClass); 927 } 928 929 930 /** 931 * Adds a class to the prior list. 932 * 933 * @returns VINF_SUCCESS, VERR_NO_MEMORY or VERR_SEM_LV_WRONG_ORDER. 934 * @param pClass The class to work on. 935 * @param pPriorClass The class to add. 936 * @param fAutodidacticism Whether we're teaching ourselfs (true) or 937 * somebody is teaching us via the API (false). 938 */ 939 static int rtLockValidatorClassAddPriorClass(RTLOCKVALCLASSINT *pClass, RTLOCKVALCLASSINT *pPriorClass, bool fAutodidacticism) 940 { 941 if (!RTCritSectIsInitialized(&g_LockValClassTeachCS)) 942 rtLockValidatorLazyInit(); 943 int rcLock = RTCritSectEnter(&g_LockValClassTeachCS); 944 945 /* 946 * Check that there are no conflict (no assert since we might race each other). 947 */ 948 int rc = VERR_INTERNAL_ERROR_5; 949 if (!rtLockValidatorClassIsPriorClass(pPriorClass, pClass)) 950 { 951 if (!rtLockValidatorClassIsPriorClass(pClass, pPriorClass)) 952 { 953 /* 954 * Scan the table for a free entry, allocating a new chunk if necessary. 955 */ 956 for (PRTLOCKVALCLASSREFCHUNK pChunk = &pClass->PriorLocks; ; pChunk = pChunk->pNext) 957 { 958 bool fDone = false; 959 for (uint32_t i = 0; i < RT_ELEMENTS(pChunk->aRefs); i++) 960 { 961 ASMAtomicCmpXchgHandle(&pChunk->aRefs[i].hClass, pPriorClass, NIL_RTLOCKVALCLASS, fDone); 962 if (fDone) 963 { 964 pChunk->aRefs[i].fAutodidacticism = fAutodidacticism; 965 rc = VINF_SUCCESS; 966 break; 967 } 968 } 969 if (fDone) 970 break; 971 972 /* If no more chunks, allocate a new one and insert the class before linking it. */ 973 if (!pChunk->pNext) 974 { 975 PRTLOCKVALCLASSREFCHUNK pNew = (PRTLOCKVALCLASSREFCHUNK)RTMemAlloc(sizeof(*pNew)); 976 if (!pNew) 977 { 978 rc = VERR_NO_MEMORY; 979 break; 980 } 981 pNew->pNext = NULL; 982 for (uint32_t i = 0; i < RT_ELEMENTS(pNew->aRefs); i++) 983 { 984 pNew->aRefs[i].hClass = NIL_RTLOCKVALCLASS; 985 pNew->aRefs[i].cLookups = 0; 986 pNew->aRefs[i].fAutodidacticism = false; 987 pNew->aRefs[i].afReserved[0] = false; 988 pNew->aRefs[i].afReserved[1] = false; 989 pNew->aRefs[i].afReserved[2] = false; 990 } 991 992 pNew->aRefs[0].hClass = pPriorClass; 993 pNew->aRefs[0].fAutodidacticism = fAutodidacticism; 994 995 ASMAtomicWritePtr((void * volatile *)&pChunk->pNext, pNew); 996 rc = VINF_SUCCESS; 997 break; 998 } 999 } /* chunk loop */ 1000 } 1001 else 1002 rc = VINF_SUCCESS; 1003 } 1004 else 1005 rc = VERR_SEM_LV_WRONG_ORDER; 1006 1007 if (RT_SUCCESS(rcLock)) 1008 RTCritSectLeave(&g_LockValClassTeachCS); 1009 return rc; 1010 } 1011 1012 1013 RTDECL(int) RTLockValidatorClassAddPriorClass(RTLOCKVALCLASS hClass, RTLOCKVALCLASS hPriorClass) 1014 { 1015 RTLOCKVALCLASSINT *pClass = hClass; 1016 AssertPtrReturn(pClass, VERR_INVALID_HANDLE); 1017 AssertReturn(pClass->u32Magic == RTLOCKVALCLASS_MAGIC, VERR_INVALID_HANDLE); 1018 1019 RTLOCKVALCLASSINT *pPriorClass = hPriorClass; 1020 AssertPtrReturn(pPriorClass, VERR_INVALID_HANDLE); 1021 AssertReturn(pPriorClass->u32Magic == RTLOCKVALCLASS_MAGIC, VERR_INVALID_HANDLE); 1022 1023 return rtLockValidatorClassAddPriorClass(pClass, pPriorClass, false /*fAutodidacticism*/); 418 1024 } 419 1025 … … 457 1063 return true; 458 1064 } 459 460 461 1065 462 1066 … … 960 1564 961 1565 962 963 964 RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVALIDATORCLASS hClass, 1566 RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, 965 1567 uint32_t uSubClass, const char *pszName, void *hLock) 966 1568 { … … 973 1575 pRec->afReserved[1] = 0; 974 1576 pRec->afReserved[2] = 0; 975 rtLockValidator InitSrcPos(&pRec->SrcPos);1577 rtLockValidatorSrcPosInit(&pRec->SrcPos); 976 1578 pRec->hThread = NIL_RTTHREAD; 977 1579 pRec->pDown = NULL; 978 pRec->hClass = hClass;1580 pRec->hClass = rtLockValidatorClassValidateAndRetain(hClass); 979 1581 pRec->uSubClass = uSubClass; 980 1582 pRec->cRecursion = 0; … … 983 1585 pRec->pSibling = NULL; 984 1586 985 /* Lazily initialize the crossroads semaphore. */ 986 static uint32_t volatile s_fInitializing = false; 987 if (RT_UNLIKELY( g_hLockValidatorXRoads == NIL_RTSEMXROADS 988 && ASMAtomicCmpXchgU32(&s_fInitializing, true, false))) 989 { 990 RTSEMXROADS hXRoads; 991 int rc = RTSemXRoadsCreate(&hXRoads); 992 if (RT_SUCCESS(rc)) 993 ASMAtomicWriteHandle(&g_hLockValidatorXRoads, hXRoads); 994 ASMAtomicWriteU32(&s_fInitializing, false); 995 } 996 } 997 998 999 RTDECL(int) RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALIDATORCLASS hClass, 1587 /* Lazy initialization. */ 1588 if (RT_UNLIKELY(g_hLockValidatorXRoads == NIL_RTSEMXROADS)) 1589 rtLockValidatorLazyInit(); 1590 } 1591 1592 1593 RTDECL(int) RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, 1000 1594 uint32_t uSubClass, const char *pszName, void *pvLock) 1001 1595 { … … 1019 1613 ASMAtomicWriteU32(&pRec->Core.u32Magic, RTLOCKVALRECEXCL_MAGIC_DEAD); 1020 1614 ASMAtomicWriteHandle(&pRec->hThread, NIL_RTTHREAD); 1021 ASMAtomicWriteHandle(&pRec->hClass, NIL_RTLOCKVAL IDATORCLASS);1615 ASMAtomicWriteHandle(&pRec->hClass, NIL_RTLOCKVALCLASS); 1022 1616 if (pRec->pSibling) 1023 1617 rtLockValidatorUnlinkAllSiblings(&pRec->Core); … … 1065 1659 * Update the record. 1066 1660 */ 1067 rtLockValidator CopySrcPos(&pRec->SrcPos, pSrcPos);1661 rtLockValidatorSrcPosCopy(&pRec->SrcPos, pSrcPos); 1068 1662 ASMAtomicUoWriteU32(&pRec->cRecursion, 1); 1069 1663 ASMAtomicWriteHandle(&pRec->hThread, hThreadSelf); … … 1232 1826 */ 1233 1827 rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pRec, pRecU); 1234 rtLockValidator CopySrcPos(&pThreadSelf->LockValidator.SrcPos, pSrcPos);1828 rtLockValidatorSrcPosCopy(&pThreadSelf->LockValidator.SrcPos, pSrcPos); 1235 1829 ASMAtomicWriteBool(&pThreadSelf->LockValidator.fInValidator, true); 1236 1830 pThreadSelf->LockValidator.enmRecState = enmSleepState; … … 1284 1878 1285 1879 1286 RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVAL IDATORCLASS hClass, uint32_t uSubClass,1880 RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, 1287 1881 const char *pszName, void *hLock, bool fSignaller) 1288 1882 { … … 1292 1886 pRec->Core.u32Magic = RTLOCKVALRECSHRD_MAGIC; 1293 1887 pRec->uSubClass = uSubClass; 1294 pRec->hClass = hClass;1888 pRec->hClass = rtLockValidatorClassValidateAndRetain(hClass); 1295 1889 pRec->hLock = hLock; 1296 1890 pRec->pszName = pszName; … … 1331 1925 1332 1926 ASMAtomicWriteU32(&pRec->Core.u32Magic, RTLOCKVALRECSHRD_MAGIC_DEAD); 1333 ASMAtomicUoWriteHandle(&pRec->hClass, NIL_RTLOCKVAL IDATORCLASS);1927 ASMAtomicUoWriteHandle(&pRec->hClass, NIL_RTLOCKVALCLASS); 1334 1928 if (pRec->papOwners) 1335 1929 { … … 1437 2031 */ 1438 2032 rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pRec, pRecU); 1439 rtLockValidator CopySrcPos(&pThreadSelf->LockValidator.SrcPos, pSrcPos);2033 rtLockValidatorSrcPosCopy(&pThreadSelf->LockValidator.SrcPos, pSrcPos); 1440 2034 ASMAtomicWriteBool(&pThreadSelf->LockValidator.fInValidator, true); 1441 2035 pThreadSelf->LockValidator.enmRecState = enmSleepState; … … 1536 2130 pEntry->SrcPos = *pSrcPos; 1537 2131 else 1538 rtLockValidator InitSrcPos(&pEntry->SrcPos);2132 rtLockValidatorSrcPosInit(&pEntry->SrcPos); 1539 2133 return pEntry; 1540 2134 } … … 1880 2474 * Check the release order. 1881 2475 */ 1882 if (pRec->hClass != NIL_RTLOCKVAL IDATORCLASS)2476 if (pRec->hClass != NIL_RTLOCKVALCLASS) 1883 2477 { 1884 2478 /** @todo order validation */ -
trunk/src/VBox/Runtime/generic/critsect-generic.cpp
r25638 r25682 69 69 pCritSect->cLockers = -1; 70 70 pCritSect->NativeThreadOwner = NIL_RTNATIVETHREAD; 71 int rc = RTLockValidatorRecExclCreate(&pCritSect->pValidatorRec, NIL_RTLOCKVAL IDATORCLASS, 0, "RTCritSect", pCritSect);71 int rc = RTLockValidatorRecExclCreate(&pCritSect->pValidatorRec, NIL_RTLOCKVALCLASS, 0, "RTCritSect", pCritSect); 72 72 if (RT_SUCCESS(rc)) 73 73 { -
trunk/src/VBox/Runtime/generic/semrw-generic.cpp
r25638 r25682 135 135 pThis->u32Magic = RTSEMRW_MAGIC; 136 136 #ifdef RTSEMRW_STRICT 137 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis);138 RTLockValidatorRecSharedInit(&pThis->ValidatorRead, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/);137 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemRW", pThis); 138 RTLockValidatorRecSharedInit(&pThis->ValidatorRead, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/); 139 139 RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core); 140 140 #endif -
trunk/src/VBox/Runtime/generic/semrw-lockless-generic.cpp
r25670 r25682 134 134 pThis->fNeedReset = false; 135 135 #ifdef RTSEMRW_STRICT 136 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis);137 RTLockValidatorRecSharedInit(&pThis->ValidatorRead, NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/);136 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemRW", pThis); 137 RTLockValidatorRecSharedInit(&pThis->ValidatorRead, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/); 138 138 RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core); 139 139 #endif -
trunk/src/VBox/Runtime/include/internal/magics.h
r25611 r25682 67 67 /** The magic value for RTLOCALIPCSERVER::u32Magic. (Katsuhiro Otomo) */ 68 68 #define RTLOCALIPCSESSION_MAGIC UINT32_C(0x19530414) 69 /** The magic value for RTLOCKVALCLASSINT::u32Magic. (Thomas Mann) */ 70 #define RTLOCKVALCLASS_MAGIC UINT32_C(0x18750605) 71 /** The magic value for RTLOCKVALCLASSINT::u32Magic after destruction. */ 72 #define RTLOCKVALCLASS_MAGIC_DEAD UINT32_C(0x19550812) 69 73 /** The magic value for RTLOCKVALRECEXCL::u32Magic. (Vladimir Vladimirovich Nabokov) */ 70 74 #define RTLOCKVALRECEXCL_MAGIC UINT32_C(0x18990422) -
trunk/src/VBox/Runtime/r3/linux/semevent-linux.cpp
r25651 r25682 130 130 #ifdef RTSEMEVENT_STRICT 131 131 RTLockValidatorRecSharedInit(&pThis->Signallers, 132 NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,132 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, 133 133 "RTSemEvent", pThis, true /*fSignaller*/); 134 134 pThis->fEverHadSignallers = false; -
trunk/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp
r25649 r25682 131 131 #ifdef RTSEMEVENTMULTI_STRICT 132 132 RTLockValidatorRecSharedInit(&pThis->Signallers, 133 NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,133 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, 134 134 "RTSemEventMulti", pThis, true /*fSignaller*/); 135 135 pThis->fEverHadSignallers = false; -
trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
r25652 r25682 120 120 pThis->cNesting = 0; 121 121 #ifdef RTSEMMUTEX_STRICT 122 RTLockValidatorRecExclInit(&pThis->ValidatorRec, NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemMutex", pThis);122 RTLockValidatorRecExclInit(&pThis->ValidatorRec, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemMutex", pThis); 123 123 #endif 124 124 -
trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp
r25661 r25682 133 133 #ifdef RTSEMEVENT_STRICT 134 134 RTLockValidatorRecSharedInit(&pThis->Signallers, 135 NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,135 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, 136 136 "RTSemEvent", pThis, true /*fSignaller*/); 137 137 pThis->fEverHadSignallers = false; -
trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp
r25661 r25682 123 123 #ifdef RTSEMEVENTMULTI_STRICT 124 124 RTLockValidatorRecSharedInit(&pThis->Signallers, 125 NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,125 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, 126 126 "RTSemEventMulti", pThis, true /*fSignaller*/); 127 127 pThis->fEverHadSignallers = false; -
trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
r25638 r25682 102 102 pThis->u32Magic = RTSEMMUTEX_MAGIC; 103 103 #ifdef RTSEMMUTEX_STRICT 104 RTLockValidatorRecExclInit(&pThis->ValidatorRec, NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemMutex", pThis);104 RTLockValidatorRecExclInit(&pThis->ValidatorRec, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemMutex", pThis); 105 105 #endif 106 106 -
trunk/src/VBox/Runtime/r3/posix/semrw-posix.cpp
r25638 r25682 126 126 pThis->Writer = (pthread_t)-1; 127 127 #ifdef RTSEMRW_STRICT 128 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis);129 RTLockValidatorRecSharedInit(&pThis->ValidatorRead, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/);128 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemRW", pThis); 129 RTLockValidatorRecSharedInit(&pThis->ValidatorRead, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/); 130 130 RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core); 131 131 #endif -
trunk/src/VBox/Runtime/r3/win/semevent-win.cpp
r25659 r25682 88 88 #ifdef RTSEMEVENT_STRICT 89 89 RTLockValidatorRecSharedInit(&pThis->Signallers, 90 NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,90 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, 91 91 "RTSemEvent", pThis, true /*fSignaller*/); 92 92 pThis->fEverHadSignallers = false; -
trunk/src/VBox/Runtime/r3/win/semeventmulti-win.cpp
r25659 r25682 91 91 #ifdef RTSEMEVENT_STRICT 92 92 RTLockValidatorRecSharedInit(&pThis->Signallers, 93 NIL_RTLOCKVAL IDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,93 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, 94 94 "RTSemEvent", pThis, true /*fSignaller*/); 95 95 pThis->fEverHadSignallers = false; -
trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp
r25658 r25682 93 93 pThis->cRecursions = 0; 94 94 #ifdef RTSEMMUTEX_STRICT 95 RTLockValidatorRecExclInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemMutex", pThis);95 RTLockValidatorRecExclInit(&pThis->ValidatorRec, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemMutex", pThis); 96 96 #endif 97 97 *pMutexSem = pThis; -
trunk/src/VBox/VMM/PDMCritSect.cpp
r25607 r25682 127 127 if (RT_SUCCESS(rc)) 128 128 { 129 rc = RTLockValidatorRecExclCreate(&pCritSect->Core.pValidatorRec, NIL_RTLOCKVAL IDATORCLASS, 0, pszName, pCritSect);129 rc = RTLockValidatorRecExclCreate(&pCritSect->Core.pValidatorRec, NIL_RTLOCKVALCLASS, 0, pszName, pCritSect); 130 130 if (RT_SUCCESS(rc)) 131 131 {
Note:
See TracChangeset
for help on using the changeset viewer.