Changeset 25467 in vbox
- Timestamp:
- Dec 17, 2009 3:16:55 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/err.h
r25360 r25467 843 843 /** Don't spin for the semaphore, but it is safe to try grab it. */ 844 844 #define VINF_SEM_BAD_CONTEXT (367) 845 /** Wrong locking order detected. */ 846 #define VERR_SEM_LV_WRONG_ORDER (-368) 847 /** Wrong release order detected. */ 848 #define VERR_SEM_LV_WRONG_RELEASE_ORDER (-369) 849 /** Attempt to recursively enter a non-recurisve lock. */ 850 #define VERR_SEM_LV_NESTED (-370) 851 /** Invalid parameters passed to the lock validator. */ 852 #define VERR_SEM_LV_INVALID_PARAMETER (-371) 853 /** The lock validator detected a deadlock. */ 854 #define VERR_SEM_LV_DEADLOCK (-372) 845 855 /** @} */ 846 856 -
trunk/include/iprt/lockvalidator.h
r25409 r25467 150 150 * 151 151 * @retval VINF_SUCCESS on success. 152 * @retval VERR_DEADLOCK if the order is wrong, after having whined and 153 * asserted. 152 * @retval VERR_SEM_LV_WRONG_ORDER if the order is wrong. Will have done all 153 * necessary whining and breakpointing before returning. 154 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid. 154 155 * 155 156 * @param pRec The validator record. … … 170 171 * Change the thread state to blocking and do deadlock detection. 171 172 * 173 * @retval VINF_SUCCESS 174 * @retval VERR_SEM_LV_DEADLOCK if blocking would deadlock. Gone thru the 175 * motions. 176 * @retval VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is 177 * already the owner. Gone thru the motions. 178 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid. 179 * 172 180 * @param pRec The validator record we're blocing on. 173 181 * @param hThread The current thread. Shall not be NIL_RTTHREAD! … … 178 186 * @param RT_SRC_POS_DECL Where we are blocking. 179 187 */ 180 RTDECL( void) RTLockValidatorCheckBlocking(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread,181 182 188 RTDECL(int) RTLockValidatorCheckBlocking(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, 189 RTTHREADSTATE enmState, bool fRecursiveOk, 190 RTHCUINTPTR uId, RT_SRC_POS_DECL); 183 191 184 192 /** 185 193 * Check the exit order. 186 194 * 187 * This is called by routines implementing lock acquisition.195 * This is called by routines implementing releasing the lock. 188 196 * 189 197 * @retval VINF_SUCCESS on success. 190 * @retval VERR_DEADLOCK if the order is wrong, after having whined and 191 * asserted. 198 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong. Will have 199 * done all necessary whining and breakpointing before returning. 200 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid. 201 * 202 * @param pRec The validator record. 203 */ 204 RTDECL(int) RTLockValidatorCheckReleaseOrder(PRTLOCKVALIDATORREC pRec); 205 206 /** 207 * Checks and records a lock recursion. 208 * 209 * @retval VINF_SUCCESS on success. 210 * @retval VERR_SEM_LV_NESTED if the semaphore class forbids recursion. Gone 211 * thru the motions. 212 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid. 213 * 214 * @param pRec The validator record. 215 * @param uId Some kind of locking location ID. Typically a 216 * return address up the stack. Optional (0). 217 * @param pszFile The file where the lock is being acquired from. 218 * Optional. 219 * @param iLine The line number in that file. Optional (0). 220 * @param pszFunction The functionn where the lock is being acquired 221 * from. Optional. 222 */ 223 RTDECL(int) RTLockValidatorRecordRecursion(PRTLOCKVALIDATORREC pRec, RTHCUINTPTR uId, RT_SRC_POS_DECL); 224 225 /** 226 * Records a lock unwind (releasing one recursion). 227 * 228 * This should be coupled with called to RTLockValidatorRecordRecursion. 229 * 230 * @param pRec The validator record. 231 */ 232 RTDECL(void) RTLockValidatorRecordUnwind(PRTLOCKVALIDATORREC pRec); 233 234 /** 235 * Record the specified thread as lock owner and increment the write lock count. 236 * 237 * This function is typically called after acquiring the lock. 238 * 239 * @returns hThread resolved. Can return NIL_RTHREAD iff we fail to adopt the 240 * alien thread or if pRec is invalid. 192 241 * 193 242 * @param pRec The validator record. … … 203 252 * from. Optional. 204 253 */ 205 RTDECL(int) RTLockValidatorCheckReleaseOrder(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread);206 207 208 /**209 * Record the specified thread as lock owner.210 *211 * This is typically called after acquiring the lock.212 *213 * @returns hThread resolved. Can return NIL_RTHREAD iff we fail to adopt the214 * alien thread or if pRec is invalid.215 *216 * @param pRec The validator record.217 * @param hThread The handle of the calling thread. If not known,218 * pass NIL_RTTHREAD and this method will figure it219 * out.220 * @param uId Some kind of locking location ID. Typically a221 * return address up the stack. Optional (0).222 * @param pszFile The file where the lock is being acquired from.223 * Optional.224 * @param iLine The line number in that file. Optional (0).225 * @param pszFunction The functionn where the lock is being acquired226 * from. Optional.227 */228 254 RTDECL(RTTHREAD) RTLockValidatorSetOwner(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL); 229 255 230 256 231 257 /** 232 * Clear the lock ownership .258 * Clear the lock ownership and decrement the write lock count. 233 259 * 234 260 * This is typically called before release the lock. -
trunk/include/iprt/semaphore.h
r25426 r25467 247 247 * @param MutexSem The mutex semaphore to request ownership over. 248 248 * @param cMillies The number of milliseconds to wait. 249 * @param uId250 249 * @param uId Some kind of locking location ID. Typically a 251 250 * return address up the stack. Optional (0). … … 262 261 * 263 262 * @returns iprt status code. 264 * Will not return VERR_INTERRUPTED.265 263 * @param MutexSem The mutex semaphore to request ownership over. 266 264 * @param cMillies The number of milliseconds to wait. 267 * @param uId268 265 * @param uId Some kind of locking location ID. Typically a 269 266 * return address up the stack. Optional (0). … … 530 527 */ 531 528 RTDECL(int) RTSemRWRequestWriteNoResume(RTSEMRW RWSem, unsigned cMillies); 529 530 /** 531 * Debug version of RTSemRWRequestWrite that tracks the location. 532 * 533 * @returns IPRT status code, see RTSemRWRequestWrite. 534 * @param RWSem The Read/Write semaphore to request write access 535 * to. 536 * @param cMillies The number of milliseconds to wait. 537 * @param uId Some kind of locking location ID. Typically a 538 * return address up the stack. Optional (0). 539 * @param pszFile The file where the lock is being acquired from. 540 * Optional. 541 * @param iLine The line number in that file. Optional (0). 542 * @param pszFunction The functionn where the lock is being acquired 543 * from. Optional. 544 */ 545 RTDECL(int) RTSemRWRequestWriteDebug(RTSEMRW MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL); 546 547 /** 548 * Debug version of RTSemRWRequestWriteNoResume that tracks the location. 549 * 550 * @returns IPRT status code, see RTSemRWRequestWriteNoResume. 551 * @param RWSem The Read/Write semaphore to request write access 552 * to. 553 * @param cMillies The number of milliseconds to wait. 554 * @param uId Some kind of locking location ID. Typically a 555 * return address up the stack. Optional (0). 556 * @param pszFile The file where the lock is being acquired from. 557 * Optional. 558 * @param iLine The line number in that file. Optional (0). 559 * @param pszFunction The functionn where the lock is being acquired 560 * from. Optional. 561 */ 562 RTDECL(int) RTSemRWRequestWriteNoResumeDebug(RTSEMRW RWSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL); 532 563 533 564 /** -
trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
r25436 r25467 181 181 RTDECL(int) RTLockValidatorCheckOrder(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL) 182 182 { 183 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, VERR_ INVALID_MAGIC);183 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 184 184 185 185 /* … … 196 196 197 197 198 RTDECL(int) RTLockValidatorCheckReleaseOrder(PRTLOCKVALIDATORREC pRec) 199 { 200 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 201 AssertReturn(pRec->hThread != NIL_RTTHREAD, VERR_SEM_LV_INVALID_PARAMETER); 202 203 return VINF_SUCCESS; 204 } 205 206 207 RTDECL(int) RTLockValidatorRecordRecursion(PRTLOCKVALIDATORREC pRec, RTHCUINTPTR uId, RT_SRC_POS_DECL) 208 { 209 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 210 AssertReturn(pRec->hThread != NIL_RTTHREAD, VERR_SEM_LV_INVALID_PARAMETER); 211 212 Assert(pRec->cRecursion < _1M); 213 pRec->cRecursion++; 214 215 return VINF_SUCCESS; 216 } 217 218 219 RTDECL(void) RTLockValidatorRecordUnwind(PRTLOCKVALIDATORREC pRec) 220 { 221 AssertReturnVoid(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC); 222 AssertReturnVoid(pRec->hThread != NIL_RTTHREAD); 223 AssertReturnVoid(pRec->cRecursion > 0); 224 225 pRec->cRecursion--; 226 } 227 228 198 229 RTDECL(RTTHREAD) RTLockValidatorSetOwner(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL) 199 230 { … … 201 232 202 233 if (hThread == NIL_RTTHREAD) 234 { 203 235 hThread = RTThreadSelfAutoAdopt(); 236 AssertReturn(hThread != NIL_RTTHREAD, hThread); 237 } 238 239 ASMAtomicIncS32(&hThread->LockValidator.cWriteLocks); 240 204 241 if (pRec->hThread == hThread) 205 242 pRec->cRecursion++; … … 232 269 { 233 270 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, NIL_RTTHREAD); 234 RTTHREAD hThread = pRec->hThread; 235 AssertReturn(hThread != NIL_RTTHREAD, hThread); 236 AssertReturn(pRec->hThread == hThread, hThread); 271 RTTHREADINT *pThread = pRec->hThread; 272 AssertReturn(pThread != NIL_RTTHREAD, pThread); 273 274 ASMAtomicDecS32(&pThread->LockValidator.cWriteLocks); 237 275 238 276 if (ASMAtomicDecU32(&pRec->cRecursion) == 0) … … 249 287 } 250 288 251 return hThread;289 return pThread; 252 290 } 253 291 … … 421 459 422 460 423 /** 424 * Change the thread state to blocking and do deadlock detection. 425 * 426 * @param pRec The validator record we're blocing on. 427 * @param hThread The current thread. Shall not be NIL_RTTHREAD! 428 * @param enmState The sleep state. 429 * @param pvBlock Pointer to a RTLOCKVALIDATORREC structure. 430 * @param fRecursiveOk Whether it's ok to recurse. 431 * @param uId Where we are blocking. 432 * @param RT_SRC_POS_DECL Where we are blocking. 433 */ 434 RTDECL(void) RTLockValidatorCheckBlocking(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, 435 RTTHREADSTATE enmState, bool fRecursiveOk, 436 RTHCUINTPTR uId, RT_SRC_POS_DECL) 461 RTDECL(int) RTLockValidatorCheckBlocking(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, 462 RTTHREADSTATE enmState, bool fRecursiveOk, 463 RTHCUINTPTR uId, RT_SRC_POS_DECL) 437 464 { 438 465 /* 439 466 * Fend off wild life. 440 467 */ 441 AssertReturn Void(RTTHREAD_IS_SLEEPING(enmState));442 AssertPtrReturn Void(pRec);443 AssertReturn Void(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC);468 AssertReturn(RTTHREAD_IS_SLEEPING(enmState), VERR_SEM_LV_INVALID_PARAMETER); 469 AssertPtrReturn(pRec, VERR_SEM_LV_INVALID_PARAMETER); 470 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 444 471 PRTTHREADINT pThread = hThread; 445 AssertPtrReturn Void(pThread);446 AssertReturn Void(pThread->u32Magic == RTTHREADINT_MAGIC);472 AssertPtrReturn(pThread, VERR_SEM_LV_INVALID_PARAMETER); 473 AssertReturn(pThread->u32Magic == RTTHREADINT_MAGIC, VERR_SEM_LV_INVALID_PARAMETER); 447 474 RTTHREADSTATE enmThreadState = rtThreadGetState(pThread); 448 AssertReturnVoid( enmThreadState == RTTHREADSTATE_RUNNING 449 || enmThreadState == RTTHREADSTATE_TERMINATED /* rtThreadRemove uses locks too */); 475 AssertReturn( enmThreadState == RTTHREADSTATE_RUNNING 476 || enmThreadState == RTTHREADSTATE_TERMINATED /* rtThreadRemove uses locks too */ 477 || enmThreadState == RTTHREADSTATE_INITIALIZING /* rtThreadInsert uses locks too */ 478 , VERR_SEM_LV_INVALID_PARAMETER); 450 479 451 480 /* … … 468 497 * isn't any other place to check for this. semmutex-win.cpp for instance. 469 498 */ 470 if ( !fRecursiveOk 471 || pRec->hThread != pThread) 472 { 473 /* 474 * Do deadlock detection. 475 * 476 * Since we're missing proper serialization, we don't declare it a 477 * deadlock until we've got three runs with the same list length. 478 * While this isn't perfect, it should avoid out the most obvious 479 * races on SMP boxes. 480 */ 481 rtLockValidatorSerializeDetectionEnter(); 482 483 PRTTHREADINT pCur; 484 unsigned cPrevLength = ~0U; 485 unsigned cEqualRuns = 0; 486 unsigned iParanoia = 256; 487 do 499 if (pRec->hThread == pThread) 500 { 501 if (fRecursiveOk) 502 return VINF_SUCCESS; 503 AssertMsgFailed(("%p (%s)\n", pRec->hLock, pRec->pszName)); 504 return VERR_SEM_LV_NESTED; 505 } 506 507 /* 508 * Do deadlock detection. 509 * 510 * Since we're missing proper serialization, we don't declare it a 511 * deadlock until we've got three runs with the same list length. 512 * While this isn't perfect, it should avoid out the most obvious 513 * races on SMP boxes. 514 */ 515 rtLockValidatorSerializeDetectionEnter(); 516 517 PRTTHREADINT pCur; 518 unsigned cPrevLength = ~0U; 519 unsigned cEqualRuns = 0; 520 unsigned iParanoia = 256; 521 do 522 { 523 unsigned cLength = 0; 524 pCur = pThread; 525 for (;;) 488 526 { 489 unsigned cLength = 0; 490 pCur = pThread; 527 /* 528 * Get the next thread. 529 */ 530 PRTTHREADINT pNext = NULL; 491 531 for (;;) 492 532 { 493 /* 494 * Get the next thread. 495 */ 496 PRTTHREADINT pNext = NULL; 497 for (;;) 533 RTTHREADSTATE enmCurState = rtThreadGetState(pCur); 534 switch (enmCurState) 498 535 { 499 RTTHREADSTATE enmCurState = rtThreadGetState(pCur); 500 switch (enmCurState) 536 case RTTHREADSTATE_CRITSECT: 537 case RTTHREADSTATE_EVENT: 538 case RTTHREADSTATE_EVENT_MULTI: 539 case RTTHREADSTATE_FAST_MUTEX: 540 case RTTHREADSTATE_MUTEX: 541 case RTTHREADSTATE_RW_READ: 542 case RTTHREADSTATE_RW_WRITE: 543 case RTTHREADSTATE_SPIN_MUTEX: 501 544 { 502 case RTTHREADSTATE_CRITSECT: 503 case RTTHREADSTATE_EVENT: 504 case RTTHREADSTATE_EVENT_MULTI: 505 case RTTHREADSTATE_FAST_MUTEX: 506 case RTTHREADSTATE_MUTEX: 507 case RTTHREADSTATE_RW_READ: 508 case RTTHREADSTATE_RW_WRITE: 509 case RTTHREADSTATE_SPIN_MUTEX: 510 { 511 PRTLOCKVALIDATORREC pCurRec = pCur->LockValidator.pRec; 512 if ( rtThreadGetState(pCur) != enmCurState 513 || !VALID_PTR(pCurRec) 514 || pCurRec->u32Magic != RTLOCKVALIDATORREC_MAGIC) 515 continue; 516 pNext = pCurRec->hThread; 517 if ( rtThreadGetState(pCur) != enmCurState 518 || pCurRec->u32Magic != RTLOCKVALIDATORREC_MAGIC 519 || pCurRec->hThread != pNext) 520 continue; 521 break; 522 } 523 524 default: 525 pNext = NULL; 526 break; 545 PRTLOCKVALIDATORREC pCurRec = pCur->LockValidator.pRec; 546 if ( rtThreadGetState(pCur) != enmCurState 547 || !VALID_PTR(pCurRec) 548 || pCurRec->u32Magic != RTLOCKVALIDATORREC_MAGIC) 549 continue; 550 pNext = pCurRec->hThread; 551 if ( rtThreadGetState(pCur) != enmCurState 552 || pCurRec->u32Magic != RTLOCKVALIDATORREC_MAGIC 553 || pCurRec->hThread != pNext) 554 continue; 555 break; 527 556 } 528 break; 557 558 default: 559 pNext = NULL; 560 break; 529 561 } 530 531 /* 532 * If we arrive at the end of the list we're good. 533 */ 534 pCur = pNext; 535 if (!pCur) 536 { 537 rtLockValidatorSerializeDetectionLeave(); 538 return; 539 } 540 541 /* 542 * If we've got back to the blocking thread id we've 543 * got a deadlock. 544 */ 545 if (pCur == pThread) 546 break; 547 548 /* 549 * If we've got a chain of more than 256 items, there is some 550 * kind of cycle in the list, which means that there is already 551 * a deadlock somewhere. 552 */ 553 if (cLength >= 256) 554 break; 555 556 cLength++; 562 break; 557 563 } 558 564 559 /* compare with previous list run. */ 560 if (cLength != cPrevLength) 565 /* 566 * If we arrive at the end of the list we're good. 567 */ 568 pCur = pNext; 569 if (!pCur) 561 570 { 562 cPrevLength = cLength;563 cEqualRuns = 0;571 rtLockValidatorSerializeDetectionLeave(); 572 return VINF_SUCCESS; 564 573 } 565 else 566 cEqualRuns++; 567 } while (cEqualRuns < 3 && --iParanoia > 0); 568 569 /* 570 * Ok, if we ever get here, it's most likely a genuine deadlock. 571 */ 572 rtLockValidatorComplainAboutDeadlock(pRec, pThread, enmState, pCur, uId, RT_SRC_POS_ARGS); 573 574 rtLockValidatorSerializeDetectionLeave(); 575 } 574 575 /* 576 * If we've got back to the blocking thread id we've 577 * got a deadlock. 578 */ 579 if (pCur == pThread) 580 break; 581 582 /* 583 * If we've got a chain of more than 256 items, there is some 584 * kind of cycle in the list, which means that there is already 585 * a deadlock somewhere. 586 */ 587 if (cLength >= 256) 588 break; 589 590 cLength++; 591 } 592 593 /* compare with previous list run. */ 594 if (cLength != cPrevLength) 595 { 596 cPrevLength = cLength; 597 cEqualRuns = 0; 598 } 599 else 600 cEqualRuns++; 601 } while (cEqualRuns < 3 && --iParanoia > 0); 602 603 /* 604 * Ok, if we ever get here, it's most likely a genuine deadlock. 605 */ 606 rtLockValidatorComplainAboutDeadlock(pRec, pThread, enmState, pCur, uId, RT_SRC_POS_ARGS); 607 608 rtLockValidatorSerializeDetectionLeave(); 609 610 return VERR_SEM_LV_DEADLOCK; 576 611 } 577 612 RT_EXPORT_SYMBOL(RTThreadBlocking); -
trunk/src/VBox/Runtime/generic/critsect-generic.cpp
r25409 r25467 244 244 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf); 245 245 #ifdef RTCRITSECT_STRICT 246 RTLockValidator WriteLockInc(RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS));246 RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS); 247 247 #endif 248 248 … … 321 321 for (;;) 322 322 { 323 RTCRITSECT_STRICT_BLOCK(hThreadSelf, pCritSect->pValidatorRec, !(pCritSect->fFlags & RTCRITSECT_FLAGS_NO_NESTING)); 323 #ifdef RTCRITSECT_STRICT 324 int rc9 = RTLockValidatorCheckBlocking(pCritSect->pValidatorRec, hThreadSelf, RTTHREADSTATE_CRITSECT, 325 !(pCritSect->fFlags & RTCRITSECT_FLAGS_NO_NESTING), 326 uId, RT_SRC_POS_ARGS); 327 if (RT_FAILURE(rc9)) 328 { 329 ASMAtomicDecS32(&pCritSect->cLockers); 330 return rc9; 331 } 332 #else 333 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT); 334 #endif 335 324 336 int rc = RTSemEventWait(pCritSect->EventSem, RT_INDEFINITE_WAIT); 325 RTCRITSECT_STRICT_UNBLOCK(hThreadSelf); 337 338 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_CRITSECT); 326 339 if (pCritSect->u32Magic != RTCRITSECT_MAGIC) 327 340 return VERR_SEM_DESTROYED; … … 339 352 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf); 340 353 #ifdef RTCRITSECT_STRICT 341 RTLockValidator WriteLockInc(RTLockValidatorSetOwner(pCritSect->pValidatorRec, hThreadSelf, uId, RT_SRC_POS_ARGS));354 RTLockValidatorSetOwner(pCritSect->pValidatorRec, hThreadSelf, uId, RT_SRC_POS_ARGS); 342 355 #endif 343 356 … … 392 405 */ 393 406 #ifdef RTCRITSECT_STRICT 394 RTLockValidator WriteLockInc(RTLockValidatorUnsetOwner(pCritSect->pValidatorRec));407 RTLockValidatorUnsetOwner(pCritSect->pValidatorRec); 395 408 #endif 396 409 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NIL_RTNATIVETHREAD); -
trunk/src/VBox/Runtime/include/internal/strict.h
r25406 r25467 45 45 # define RTCRITSECT_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 46 46 # define RTCRITSECT_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 47 # define RTCRITSECT_STRICT_BLOCK(hThread, pRec, fRecursive) \48 RTLockValidatorCheckBlocking(pRec, (hThread), RTTHREADSTATE_CRITSECT, fRecursive, uId, RT_SRC_POS_ARGS)49 47 #else 50 48 # define RTCRITSECT_STRICT_POS_DECL int iDummy 51 49 # define RTCRITSECT_STRICT_POS_ARGS 0 52 # define RTCRITSECT_STRICT_BLOCK(hThread, pRec, fRecursive) \53 RTThreadBlocking((hThread), RTTHREADSTATE_CRITSECT)54 50 #endif 55 #define RTCRITSECT_STRICT_UNBLOCK(hThread) RTThreadUnblocked((hThread), RTTHREADSTATE_CRITSECT)56 51 57 52 … … 66 61 # define RTSEMMUTEX_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 67 62 # define RTSEMMUTEX_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 68 # define RTSEMMUTEX_STRICT_BLOCK(hThread, pRec) RTLockValidatorCheckBlocking(pRec, (hThread), RTTHREADSTATE_MUTEX, true, uId, RT_SRC_POS_ARGS)69 63 #else 70 64 # define RTSEMMUTEX_STRICT_POS_DECL int iDummy 71 65 # define RTSEMMUTEX_STRICT_POS_ARGS 0 72 # define RTSEMMUTEX_STRICT_BLOCK(hThread, pRec) RTThreadBlocking((hThread), RTTHREADSTATE_MUTEX)73 66 #endif 74 #define RTSEMMUTEX_STRICT_UNBLOCK(hThread) RTThreadUnblocked((hThread), RTTHREADSTATE_MUTEX)75 67 76 68 … … 83 75 84 76 #ifdef RTSEMRW_STRICT 85 # define RTSEMRW_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 86 # define RTSEMRW_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 87 # define RTSEMRW_STRICT_BLOCK_ARGS(pRec) pRec, uId, RT_SRC_POS_ARGS 77 # define RTSEMRW_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 78 # define RTSEMRW_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 88 79 #else 89 # define RTSEMRW_STRICT_POS_DECL int iDummy 90 # define RTSEMRW_STRICT_POS_ARGS 0 91 # define RTSEMRW_STRICT_BLOCK_ARGS(pRec) NULL, 0, NULL, 0, NULL 80 # define RTSEMRW_STRICT_POS_DECL int iDummy 81 # define RTSEMRW_STRICT_POS_ARGS 0 92 82 #endif 93 83 -
trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
r25409 r25467 229 229 */ 230 230 if (pTimeout && ( pTimeout->tv_sec || pTimeout->tv_nsec )) 231 RTSEMMUTEX_STRICT_BLOCK(hThreadSelf, &pThis->ValidatorRec); 231 { 232 #ifdef RTSEMMUTEX_STRICT 233 int rc9 = RTLockValidatorCheckBlocking(&pThis->ValidatorRec, hThreadSelf, 234 RTTHREADSTATE_MUTEX, true, uId, RT_SRC_POS_ARGS); 235 if (RT_FAILURE(rc9)) 236 return rc9; 237 #else 238 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX); 239 #endif 240 } 241 232 242 long rc = sys_futex(&pThis->iState, FUTEX_WAIT, 2, pTimeout, NULL, 0); 233 RTSEMMUTEX_STRICT_UNBLOCK(hThreadSelf); 243 244 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 234 245 if (RT_UNLIKELY(pThis->u32Magic != RTSEMMUTEX_MAGIC)) 235 246 return VERR_SEM_DESTROYED; … … 289 300 ASMAtomicWriteU32(&pThis->cNesting, 1); 290 301 #ifdef RTSEMMUTEX_STRICT 291 RTLockValidator WriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS));302 RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS); 292 303 #endif 293 304 return VINF_SUCCESS; … … 373 384 */ 374 385 #ifdef RTSEMMUTEX_STRICT 375 RTLockValidator WriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec));386 RTLockValidatorUnsetOwner(&pThis->ValidatorRec); 376 387 #endif 377 388 pThis->Owner = (pthread_t)~0; -
trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
r25409 r25467 186 186 * Lock it. 187 187 */ 188 if (cMillies != 0) 189 { 190 #ifdef RTSEMMUTEX_STRICT 191 int rc9 = RTLockValidatorCheckBlocking(&pThis->ValidatorRec, hThreadSelf, 192 RTTHREADSTATE_MUTEX, true, uId, RT_SRC_POS_ARGS); 193 if (RT_FAILURE(rc9)) 194 return rc9; 195 #else 196 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX); 197 #endif 198 } 199 188 200 if (cMillies == RT_INDEFINITE_WAIT) 189 201 { 190 202 /* take mutex */ 191 RTSEMMUTEX_STRICT_BLOCK(hThreadSelf, &pThis->ValidatorRec);192 203 int rc = pthread_mutex_lock(&pThis->Mutex); 193 RT SEMMUTEX_STRICT_UNBLOCK(hThreadSelf);204 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 194 205 if (rc) 195 206 { … … 218 229 ts.tv_sec++; 219 230 } 220 RTSEMMUTEX_STRICT_BLOCK(hThreadSelf, &pThis->ValidatorRec);221 231 } 222 232 223 233 /* take mutex */ 224 234 int rc = pthread_mutex_timedlock(&pThis->Mutex, &ts); 225 RT SEMMUTEX_STRICT_UNBLOCK(hThreadSelf);235 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 226 236 if (rc) 227 237 { … … 238 248 ASMAtomicWriteU32(&pThis->cNesting, 1); 239 249 #ifdef RTSEMMUTEX_STRICT 240 RTLockValidator WriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS));250 RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS); 241 251 #endif 242 252 … … 321 331 */ 322 332 #ifdef RTSEMMUTEX_STRICT 323 RTLockValidator WriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec));333 RTLockValidatorUnsetOwner(&pThis->ValidatorRec); 324 334 #endif 325 335 pThis->Owner = (pthread_t)-1; -
trunk/src/VBox/Runtime/r3/posix/semrw-posix.cpp
r25409 r25467 83 83 /** pthread rwlock. */ 84 84 pthread_rwlock_t RWLock; 85 #ifdef RTSEMRW_STRICT 86 /** The validator record for the writer. */ 87 RTLOCKVALIDATORREC ValidatorRec; 88 #endif 85 89 }; 86 90 … … 111 115 pThis->cWriterReads = 0; 112 116 pThis->Writer = (pthread_t)-1; 117 #ifdef RTSEMRW_STRICT 118 RTLockValidatorInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis); 119 #endif 113 120 *pRWSem = pThis; 114 121 return VINF_SUCCESS; … … 131 138 * Validate input, nil handle is fine. 132 139 */ 133 if (RWSem == NIL_RTSEMRW) 140 struct RTSEMRWINTERNAL *pThis = RWSem; 141 if (pThis == NIL_RTSEMRW) 134 142 return VINF_SUCCESS; 135 struct RTSEMRWINTERNAL *pThis = RWSem;136 143 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 137 144 AssertMsgReturn(pThis->u32Magic == RTSEMRW_MAGIC, … … 145 152 * Try destroy it. 146 153 */ 154 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTSEMRW_MAGIC, RTSEMRW_MAGIC), VERR_INVALID_HANDLE); 147 155 int rc = pthread_rwlock_destroy(&pThis->RWLock); 148 156 if (!rc) 149 157 { 150 pThis->u32Magic++; 158 #ifdef RTSEMRW_STRICT 159 RTLockValidatorInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis); 160 #endif 151 161 RTMemFree(pThis); 152 162 rc = VINF_SUCCESS; … … 154 164 else 155 165 { 166 ASMAtomicWriteU32(&pThis->u32Magic, RTSEMRW_MAGIC); 156 167 AssertMsgFailed(("Failed to destroy read-write sem %p, rc=%d.\n", RWSem, rc)); 157 168 rc = RTErrConvertFromErrno(rc); … … 304 315 305 316 306 RTDECL(int) RTSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies)317 DECL_FORCE_INLINE(int) rtSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies, RTSEMRW_STRICT_POS_DECL) 307 318 { 308 319 /* … … 314 325 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 315 326 VERR_INVALID_HANDLE); 327 #ifdef RTSEMRW_STRICT 328 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 329 RTLockValidatorCheckOrder(&pThis->ValidatorRec, hThreadSelf, RTSEMRW_STRICT_POS_ARGS); 330 #endif 316 331 317 332 /* … … 323 338 if (Writer == Self) 324 339 { 340 #ifdef RTSEMRW_STRICT 341 int rc9 = RTLockValidatorRecordRecursion(&pThis->ValidatorRec, RTSEMRW_STRICT_POS_ARGS); 342 if (RT_FAILURE(rc9)) 343 return rc9; 344 #endif 325 345 Assert(pThis->cWrites < INT32_MAX); 326 346 pThis->cWrites++; 327 347 return VINF_SUCCESS; 328 348 } 349 #ifndef RTSEMRW_STRICT 350 RTTHREAD hThreadSelf = RTThreadSelf(); 351 #endif 329 352 330 353 /* 331 354 * Try lock it. 332 355 */ 356 if (cMillies) 357 { 358 #ifdef RTSEMRW_STRICT 359 int rc9 = RTLockValidatorCheckBlocking(&pThis->ValidatorRec, hThreadSelf, RTTHREADSTATE_RW_WRITE, true, uId, RT_SRC_POS_ARGS); 360 if (RT_FAILURE(rc9)) 361 return rc9; 362 #else 363 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE); 364 #endif 365 } 366 333 367 if (cMillies == RT_INDEFINITE_WAIT) 334 368 { 335 369 /* take rwlock */ 336 370 int rc = pthread_rwlock_wrlock(&pThis->RWLock); 371 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE); 337 372 if (rc) 338 373 { … … 365 400 /* take rwlock */ 366 401 int rc = pthread_rwlock_timedwrlock(&pThis->RWLock, &ts); 402 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE); 367 403 if (rc) 368 404 { … … 376 412 pThis->cWrites = 1; 377 413 #ifdef RTSEMRW_STRICT 378 RTTHREAD ThreadSelf = RTThreadSelf(); 379 if (ThreadSelf != NIL_RTTHREAD) 380 RTLockValidatorWriteLockInc(ThreadSelf); 414 RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMRW_STRICT_POS_ARGS); 381 415 #endif 382 416 return VINF_SUCCESS; … … 384 418 385 419 420 RTDECL(int) RTSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies) 421 { 422 #ifndef RTSEMRW_STRICT 423 return rtSemRWRequestWrite(RWSem, cMillies, RTSEMRW_STRICT_POS_ARGS); 424 #else 425 return RTSemRWRequestWriteDebug(RWSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS); 426 #endif 427 } 428 429 430 RTDECL(int) RTSemRWRequestWriteDebug(RTSEMRW RWSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 431 { 432 #ifdef RTSEMRW_STRICT 433 return rtSemRWRequestWrite(RWSem, cMillies, RTSEMRW_STRICT_POS_ARGS); 434 #else 435 return RTSemRWRequestWrite(RWSem, cMillies); 436 #endif 437 } 438 439 386 440 RTDECL(int) RTSemRWRequestWriteNoResume(RTSEMRW RWSem, unsigned cMillies) 387 441 { 388 442 /* EINTR isn't returned by the wait functions we're using. */ 443 #ifndef RTSEMRW_STRICT 389 444 return RTSemRWRequestWrite(RWSem, cMillies); 445 #else 446 return RTSemRWRequestWriteDebug(RWSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS); 447 #endif 448 } 449 450 451 RTDECL(int) RTSemRWRequestWriteNoResumeDebug(RTSEMRW RWSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 452 { 453 /* EINTR isn't returned by the wait functions we're using. */ 454 #ifdef RTSEMRW_STRICT 455 return RTSemRWRequestWriteDebug(RWSem, cMillies, RTSEMRW_STRICT_POS_ARGS); 456 #else 457 return RTSemRWRequestWrite(RWSem, cMillies); 458 #endif 390 459 } 391 460 … … 409 478 ATOMIC_GET_PTHREAD_T(&pThis->Writer, &Writer); 410 479 AssertMsgReturn(Writer == Self, ("pThis=%p\n", pThis), VERR_NOT_OWNER); 480 AssertReturn(pThis->cWriterReads == 0 || pThis->cWrites > 1, VERR_WRONG_ORDER); 481 411 482 pThis->cWrites--; 412 483 if (pThis->cWrites) 484 { 485 #ifdef RTSEMRW_STRICT 486 RTLockValidatorRecordUnwind(&pThis->ValidatorRec); 487 #endif 413 488 return VINF_SUCCESS; 414 AssertReturn(!pThis->cWriterReads, VERR_WRONG_ORDER);489 } 415 490 416 491 /* 417 492 * Try unlock it. 418 493 */ 494 #ifdef RTSEMRW_STRICT 495 RTLockValidatorCheckReleaseOrder(&pThis->ValidatorRec); 496 RTLockValidatorUnsetOwner(&pThis->ValidatorRec); 497 #endif 498 419 499 ATOMIC_SET_PTHREAD_T(&pThis->Writer, (pthread_t)-1); 420 500 int rc = pthread_rwlock_unlock(&pThis->RWLock); … … 425 505 } 426 506 427 #ifdef RTSEMRW_STRICT428 RTTHREAD ThreadSelf = RTThreadSelf();429 if (ThreadSelf != NIL_RTTHREAD)430 RTLockValidatorWriteLockDec(ThreadSelf);431 #endif432 507 return VINF_SUCCESS; 433 508 } -
trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp
r25409 r25467 162 162 */ 163 163 if (cMillies > 0) 164 RTSEMMUTEX_STRICT_BLOCK(hThreadSelf, &pThis->ValidatorRec); 164 { 165 #ifdef RTSEMMUTEX_STRICT 166 int rc9 = RTLockValidatorCheckBlocking(&pThis->ValidatorRec, hThreadSelf, 167 RTTHREADSTATE_MUTEX, true, uId, RT_SRC_POS_ARGS); 168 if (RT_FAILURE(rc9)) 169 return rc9; 170 #else 171 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX); 172 #endif 173 } 165 174 int rc = WaitForSingleObjectEx(pThis->hMtx, 166 175 cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, 167 176 TRUE /*bAlertable*/); 168 RT SEMMUTEX_STRICT_UNBLOCK(hThreadSelf);177 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 169 178 switch (rc) 170 179 { 171 180 case WAIT_OBJECT_0: 172 181 #ifdef RTSEMMUTEX_STRICT 173 RTLockValidator WriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS));182 RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS); 174 183 #endif 175 184 return VINF_SUCCESS; … … 227 236 if ( pThis->ValidatorRec.hThread != NIL_RTTHREAD 228 237 && pThis->ValidatorRec.hThread == RTThreadSelf()) 229 RTLockValidator WriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec));238 RTLockValidatorUnsetOwner(&pThis->ValidatorRec); 230 239 else 231 240 AssertMsgFailed(("%p hThread=%RTthrd\n", pThis, pThis->ValidatorRec.hThread)); -
trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
r25409 r25467 55 55 # define PDMCRITSECT_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 56 56 # define PDMCRITSECT_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 57 # define PDMCRITSECT_STRICT_BLOCK(hThread, pRec, fRecursive) \ 58 RTLockValidatorCheckBlocking(pRec, (hThread), RTTHREADSTATE_CRITSECT, fRecursive, uId, RT_SRC_POS_ARGS) 57 # define PDMCRITSECT_STRICT_BLOCK_RET(hThread, pRec, fRecursive) \ 58 do { \ 59 int rc9 = RTLockValidatorCheckBlocking(pRec, (hThread), RTTHREADSTATE_CRITSECT, fRecursive, uId, RT_SRC_POS_ARGS); \ 60 if (RT_FAILURE(rc9)) \ 61 return rc9; \ 62 } while (0) 59 63 #else 60 64 # define PDMCRITSECT_STRICT_POS_DECL int iDummy 61 65 # define PDMCRITSECT_STRICT_POS_ARGS 0 62 # define PDMCRITSECT_STRICT_BLOCK (hThread, pRec, fRecursive) \66 # define PDMCRITSECT_STRICT_BLOCK_RET(hThread, pRec, fRecursive) \ 63 67 RTThreadBlocking((hThread), RTTHREADSTATE_CRITSECT) 64 68 #endif … … 109 113 110 114 # ifdef PDMCRITSECT_STRICT 111 RTLockValidator WriteLockInc(RTLockValidatorSetOwner(pCritSect->s.Core.pValidatorRec, NIL_RTTHREAD, PDMCRITSECT_STRICT_POS_ARGS));115 RTLockValidatorSetOwner(pCritSect->s.Core.pValidatorRec, NIL_RTTHREAD, PDMCRITSECT_STRICT_POS_ARGS); 112 116 # endif 113 117 … … 141 145 # ifdef PDMCRITSECT_STRICT 142 146 RTTHREAD hSelf = RTThreadSelfAutoAdopt(); 143 RTLockValidatorCheckOrder(pCritSect->s.Core.pValidatorRec, hSelf, 0, NULL, 0, NULL); 147 int rc2 = RTLockValidatorCheckOrder(pCritSect->s.Core.pValidatorRec, hSelf, 0, NULL, 0, NULL); 148 if (RT_FAILURE(rc2)) 149 return rc2; 144 150 # else 145 151 RTTHREAD hSelf = RTThreadSelf(); … … 147 153 for (;;) 148 154 { 149 PDMCRITSECT_STRICT_BLOCK (hSelf, pCritSect->s.Core.pValidatorRec, !(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NO_NESTING));155 PDMCRITSECT_STRICT_BLOCK_RET(hSelf, pCritSect->s.Core.pValidatorRec, !(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NO_NESTING)); 150 156 int rc = SUPSemEventWaitNoResume(pSession, hEvent, RT_INDEFINITE_WAIT); 151 157 PDMCRITSECT_STRICT_UNBLOCK(hSelf); … … 403 409 && pCritSect->s.Core.pValidatorRec 404 410 && pCritSect->s.Core.pValidatorRec->hThread != NIL_RTTHREAD) 405 RTLockValidator WriteLockDec(RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec));411 RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec); 406 412 return rc; 407 413 } … … 449 455 # if defined(PDMCRITSECT_STRICT) 450 456 if (pCritSect->s.Core.pValidatorRec->hThread != NIL_RTTHREAD) 451 RTLockValidator WriteLockDec(RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec));457 RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec); 452 458 # endif 453 459 Assert(!pCritSect->s.Core.pValidatorRec || pCritSect->s.Core.pValidatorRec->hThread == NIL_RTTHREAD);
Note:
See TracChangeset
for help on using the changeset viewer.