- Timestamp:
- Dec 14, 2009 7:20:27 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 55992
- Location:
- trunk/src/VBox
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
r25369 r25373 133 133 134 134 135 RTDECL( void) RTLockValidatorSetOwner(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL)135 RTDECL(RTTHREAD) RTLockValidatorSetOwner(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL) 136 136 { 137 AssertReturn Void(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC);137 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, NIL_RTTHREAD); 138 138 Assert(pRec->hThread == NIL_RTTHREAD); 139 139 … … 147 147 148 148 if (hThread == NIL_RTTHREAD) 149 { 149 #ifdef IN_RING3 150 hThread = RTThreadSelfAutoAdopt(); 151 #else 150 152 hThread = RTThreadSelf(); 151 #ifdef IN_RING3152 if (RT_UNLIKELY(hThread == NIL_RTTHREAD))153 RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &hThread);154 153 #endif 155 }156 154 ASMAtomicWriteHandle(&pRec->hThread, hThread); 157 155 … … 160 158 */ 161 159 /** @todo push it onto the per-thread lock stack. */ 160 161 return hThread; 162 162 } 163 163 164 164 165 RTDECL( void) RTLockValidatorUnsetOwner(PRTLOCKVALIDATORREC pRec)165 RTDECL(RTTHREAD) RTLockValidatorUnsetOwner(PRTLOCKVALIDATORREC pRec) 166 166 { 167 AssertReturnVoid(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC); 168 Assert(pRec->hThread != NIL_RTTHREAD); 167 AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, NIL_RTTHREAD); 168 RTTHREAD hThread = pRec->hThread; 169 AssertReturn(hThread != NIL_RTTHREAD, hThread); 169 170 170 171 /* … … 177 178 */ 178 179 ASMAtomicWriteHandle(&pRec->hThread, NIL_RTTHREAD); 180 181 return hThread; 179 182 } 180 183 -
trunk/src/VBox/Runtime/common/misc/thread.cpp
r25368 r25373 332 332 } 333 333 RT_EXPORT_SYMBOL(RTThreadAdopt); 334 335 336 /** 337 * Get the thread handle of the current thread, automatically adopting alien 338 * threads. 339 * 340 * @returns Thread handle. 341 */ 342 RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void) 343 { 344 RTTHREAD hSelf = RTThreadSelf(); 345 if (RT_UNLIKELY(hSelf == NIL_RTTHREAD)) 346 RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &hSelf); 347 return hSelf; 348 } 349 RT_EXPORT_SYMBOL(RTThreadSelfAutoAdopt); 334 350 335 351 … … 1237 1253 { 1238 1254 PRTTHREADINT pThread = rtThreadGet(Thread); 1239 Assert (pThread);1255 AssertReturnVoid(pThread); 1240 1256 ASMAtomicIncS32(&pThread->cWriteLocks); 1241 1257 rtThreadRelease(pThread); … … 1252 1268 { 1253 1269 PRTTHREADINT pThread = rtThreadGet(Thread); 1254 Assert (pThread);1270 AssertReturnVoid(pThread); 1255 1271 ASMAtomicDecS32(&pThread->cWriteLocks); 1256 1272 rtThreadRelease(pThread); … … 1543 1559 1544 1560 { 1561 Assert(RTTHREAD_IS_SLEEPING(enmState)); 1562 1563 /* 1564 * Fend off wild life. 1565 */ 1545 1566 PRTTHREADINT pThread = hThread; 1546 Assert(RTTHREAD_IS_SLEEPING(enmState)); 1547 if (pThread && rtThreadGetState(pThread) == RTTHREADSTATE_RUNNING) 1548 { 1567 if (!pThread) 1568 return; 1569 if (rtThreadGetState(pThread) != RTTHREADSTATE_RUNNING) 1570 return; 1571 1572 if (!pValidatorRec) 1573 /* 1574 * If no validator record, just update the thread state. 1575 */ 1576 rtThreadSetState(pThread, enmState); 1577 else 1578 { 1579 /* 1580 * Record the location and everything before changing the state and 1581 * performing deadlock detection. 1582 */ 1549 1583 /** @todo This has to be serialized! The deadlock detection isn't 100% safe!!! */ 1550 1584 pThread->Block.pRec = pValidatorRec; -
trunk/src/VBox/Runtime/generic/critsect-generic.cpp
r25368 r25373 244 244 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf); 245 245 #ifdef RTCRITSECT_STRICT 246 RT LockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS);246 RTThreadWriteLockInc(RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS)); 247 247 #endif 248 248 … … 283 283 RTNATIVETHREAD NativeThreadSelf = RTThreadNativeSelf(); 284 284 #ifdef RTCRITSECT_STRICT 285 RTTHREAD ThreadSelf = RTThreadSelf(); 286 if (ThreadSelf == NIL_RTTHREAD) 287 RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &ThreadSelf); 288 RTLockValidatorCheckOrder(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS); 285 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 286 RTLockValidatorCheckOrder(pCritSect->pValidatorRec, hThreadSelf, uId, RT_SRC_POS_ARGS); 289 287 #endif 290 288 … … 315 313 } 316 314 315 /* 316 * Wait for the current owner to release it. 317 */ 318 #ifndef RTCRITSECT_STRICT 319 RTTHREAD hThreadSelf = RTThreadSelf(); 320 #endif 317 321 for (;;) 318 322 { 319 #ifdef RTCRITSECT_STRICT 320 RTThreadBlocking(ThreadSelf, RTTHREADSTATE_CRITSECT, pCritSect->pValidatorRec, uId, RT_SRC_POS_ARGS); 321 #endif 323 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT, RTCRITSECT_STRICT_BLOCK_ARGS(pCritSect->pValidatorRec)); 322 324 int rc = RTSemEventWait(pCritSect->EventSem, RT_INDEFINITE_WAIT); 323 #ifdef RTCRITSECT_STRICT 324 RTThreadUnblocked(ThreadSelf, RTTHREADSTATE_CRITSECT); 325 #endif 325 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_CRITSECT); 326 326 if (pCritSect->u32Magic != RTCRITSECT_MAGIC) 327 327 return VERR_SEM_DESTROYED; … … 339 339 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf); 340 340 #ifdef RTCRITSECT_STRICT 341 RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS); 342 RTThreadWriteLockInc(ThreadSelf); 341 RTThreadWriteLockInc(RTLockValidatorSetOwner(pCritSect->pValidatorRec, hThreadSelf, uId, RT_SRC_POS_ARGS)); 343 342 #endif 344 343 … … 393 392 */ 394 393 #ifdef RTCRITSECT_STRICT 395 RT LockValidatorUnsetOwner(pCritSect->pValidatorRec);394 RTThreadWriteLockInc(RTLockValidatorUnsetOwner(pCritSect->pValidatorRec)); 396 395 #endif 397 396 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NIL_RTNATIVETHREAD); -
trunk/src/VBox/Runtime/generic/semnoint-generic.cpp
r21337 r25373 126 126 RT_EXPORT_SYMBOL(RTSemMutexRequest); 127 127 128 129 RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX Mutex, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 130 { 131 int rc; 132 if (cMillies == RT_INDEFINITE_WAIT) 133 { 134 do rc = RTSemMutexRequestNoResumeDebug(Mutex, cMillies, uId, RT_SRC_POS_ARGS); 135 while (rc == VERR_INTERRUPTED); 136 } 137 else 138 { 139 const uint64_t u64Start = RTTimeMilliTS(); 140 rc = RTSemMutexRequestNoResumeDebug(Mutex, cMillies, uId, RT_SRC_POS_ARGS); 141 if (rc == VERR_INTERRUPTED) 142 { 143 do 144 { 145 uint64_t u64Elapsed = RTTimeMilliTS() - u64Start; 146 if (u64Elapsed >= cMillies) 147 return VERR_TIMEOUT; 148 rc = RTSemMutexRequestNoResumeDebug(Mutex, cMillies - (unsigned)u64Elapsed, uId, RT_SRC_POS_ARGS); 149 } while (rc == VERR_INTERRUPTED); 150 } 151 } 152 return rc; 153 } 154 RT_EXPORT_SYMBOL(RTSemMutexRequestDebug); 155 -
trunk/src/VBox/Runtime/include/internal/strict.h
r8651 r25373 42 42 #endif 43 43 44 #ifdef RTCRITSECT_STRICT 45 # define RTCRITSECT_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 46 # define RTCRITSECT_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 47 # define RTCRITSECT_STRICT_BLOCK_ARGS(pRec) pRec, uId, RT_SRC_POS_ARGS 48 #else 49 # define RTCRITSECT_STRICT_POS_DECL int iDummy 50 # define RTCRITSECT_STRICT_POS_ARGS 0 51 # define RTCRITSECT_STRICT_BLOCK_ARGS(pRec) NULL, 0, NULL, 0, NULL 52 #endif 53 54 44 55 /** @def RTSEMMUTEX_STRICT 45 56 * Enables strictness checks and lock accounting of the RTSemMutex API. … … 48 59 # define RTSEMMUTEX_STRICT 49 60 #endif 61 62 #ifdef RTSEMMUTEX_STRICT 63 # define RTSEMMUTEX_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 64 # define RTSEMMUTEX_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 65 # define RTSEMMUTEX_STRICT_BLOCK_ARGS(pRec) pRec, uId, RT_SRC_POS_ARGS 66 #else 67 # define RTSEMMUTEX_STRICT_POS_DECL int iDummy 68 # define RTSEMMUTEX_STRICT_POS_ARGS 0 69 # define RTSEMMUTEX_STRICT_BLOCK_ARGS(pRec) NULL, 0, NULL, 0, NULL 70 #endif 71 50 72 51 73 /** @def RTSEMRW_STRICT … … 56 78 #endif 57 79 80 #ifdef RTSEMRW_STRICT 81 # define RTSEMRW_STRICT_POS_DECL RTHCUINTPTR uId, RT_SRC_POS_DECL 82 # define RTSEMRW_STRICT_POS_ARGS uId, RT_SRC_POS_ARGS 83 # define RTSEMRW_STRICT_BLOCK_ARGS(pRec) pRec, uId, RT_SRC_POS_ARGS 84 #else 85 # define RTSEMRW_STRICT_POS_DECL int iDummy 86 # define RTSEMRW_STRICT_POS_ARGS 0 87 # define RTSEMRW_STRICT_BLOCK_ARGS(pRec) NULL, 0, NULL, 0, NULL 88 #endif 89 90 58 91 59 92 /** @} */ -
trunk/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
r8245 r25373 160 160 161 161 162 RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 163 { 164 return RTSemMutexRequest(MutexSem, cMillies); 165 } 166 167 /** @todo implement the NoResume versions */ 168 162 169 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem) 163 170 { -
trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
r22959 r25373 33 33 *******************************************************************************/ 34 34 #include <iprt/semaphore.h> 35 #include "internal/iprt.h" 36 37 #include <iprt/alloc.h> 38 #include <iprt/asm.h> 35 39 #include <iprt/assert.h> 36 #include <iprt/alloc.h> 40 #include <iprt/err.h> 41 #include <iprt/lockvalidator.h> 37 42 #include <iprt/thread.h> 38 #include <iprt/asm.h>39 #include <iprt/err.h>40 43 #include <iprt/time.h> 41 44 #include "internal/magics.h" … … 74 77 /** The owner of the mutex. */ 75 78 pthread_t volatile Owner; 76 /** Magic value. */ 77 intptr_t volatile iMagic; 79 /** Magic value (RTSEMMUTEX_MAGIC). */ 80 uint32_t volatile u32Magic; 81 #ifdef RTSEMMUTEX_STRICT 82 /** Lock validator record associated with this mutex. */ 83 RTLOCKVALIDATORREC ValidatorRec; 84 #endif 78 85 }; 79 86 … … 103 110 if (pThis) 104 111 { 105 pThis-> iMagic= RTSEMMUTEX_MAGIC;112 pThis->u32Magic = RTSEMMUTEX_MAGIC; 106 113 pThis->iState = 0; 107 114 pThis->Owner = (pthread_t)~0; 108 115 pThis->cNesting = 0; 116 #ifdef RTSEMMUTEX_STRICT 117 RTLockValidatorInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis); 118 #endif 109 119 110 120 *pMutexSem = pThis; … … 122 132 */ 123 133 if (MutexSem == NIL_RTSEMMUTEX) 124 return V ERR_INVALID_HANDLE;134 return VINF_SUCCESS; 125 135 struct RTSEMMUTEXINTERNAL *pThis = MutexSem; 126 136 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 127 AssertMsgReturn(pThis-> iMagic == RTSEMMUTEX_MAGIC,128 ("MutexSem=%p iMagic=%#x\n", pThis, pThis->iMagic),137 AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, 138 ("MutexSem=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 129 139 VERR_INVALID_HANDLE); 130 140 … … 132 142 * Invalidate the semaphore and wake up anyone waiting on it. 133 143 */ 134 ASMAtomic XchgSize(&pThis->iMagic, RTSEMMUTEX_MAGIC + 1);144 ASMAtomicWriteU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD); 135 145 if (ASMAtomicXchgS32(&pThis->iState, 0) > 0) 136 146 { … … 140 150 pThis->Owner = (pthread_t)~0; 141 151 pThis->cNesting = 0; 152 #ifdef RTSEMMUTEX_STRICT 153 RTLockValidatorDelete(&pThis->ValidatorRec); 154 #endif 142 155 143 156 /* … … 149 162 150 163 151 static int rtsemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, bool fAutoResume)164 DECL_FORCE_INLINE(int) rtSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, bool fAutoResume, RTSEMMUTEX_STRICT_POS_DECL) 152 165 { 153 166 /* … … 155 168 */ 156 169 struct RTSEMMUTEXINTERNAL *pThis = MutexSem; 157 AssertReturn(VALID_PTR(pThis) && pThis->iMagic == RTSEMMUTEX_MAGIC, 158 VERR_INVALID_HANDLE); 170 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 171 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 172 173 #ifdef RTSEMMUTEX_STRICT 174 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 175 RTLockValidatorCheckOrder(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS); 176 #endif 159 177 160 178 /* … … 165 183 && pThis->cNesting > 0) 166 184 { 167 pThis->cNesting++;185 ASMAtomicIncU32(&pThis->cNesting); 168 186 return VINF_SUCCESS; 169 187 } 188 #ifndef RTSEMMUTEX_STRICT 189 RTTHREAD hThreadSelf = RTThreadSelf(); 190 #endif 170 191 171 192 /* … … 202 223 * Go to sleep. 203 224 */ 225 if (pTimeout && ( pTimeout->tv_sec || pTimeout->tv_nsec )) 226 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec)); 204 227 long rc = sys_futex(&pThis->iState, FUTEX_WAIT, 2, pTimeout, NULL, 0); 205 if (RT_UNLIKELY(pThis->iMagic != RTSEMMUTEX_MAGIC)) 228 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 229 if (RT_UNLIKELY(pThis->u32Magic != RTSEMMUTEX_MAGIC)) 206 230 return VERR_SEM_DESTROYED; 207 231 … … 258 282 */ 259 283 pThis->Owner = Self; 260 ASMAtomicXchgU32(&pThis->cNesting, 1); 261 #ifdef RTSEMMUTEX_STRICT 262 RTTHREAD Thread = RTThreadSelf(); 263 if (Thread != NIL_RTTHREAD) 264 RTThreadWriteLockInc(Thread); 284 ASMAtomicWriteU32(&pThis->cNesting, 1); 285 #ifdef RTSEMMUTEX_STRICT 286 RTThreadWriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS)); 265 287 #endif 266 288 return VINF_SUCCESS; … … 268 290 269 291 270 RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies) 271 { 272 int rc = rtsemMutexRequest(MutexSem, cMillies, true); 292 RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies) 293 { 294 #ifndef RTSEMMUTEX_STRICT 295 int rc = rtSemMutexRequest(MutexSem, cMillies, true, RTSEMMUTEX_STRICT_POS_ARGS); 273 296 Assert(rc != VERR_INTERRUPTED); 274 297 return rc; 275 } 276 277 278 RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies) 279 { 280 return rtsemMutexRequest(MutexSem, cMillies, false); 281 } 282 283 284 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem) 298 #else 299 return RTSemMutexRequestDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS); 300 #endif 301 } 302 303 304 RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 305 { 306 #ifdef RTSEMMUTEX_STRICT 307 int rc = rtSemMutexRequest(MutexSem, cMillies, true, RTSEMMUTEX_STRICT_POS_ARGS); 308 Assert(rc != VERR_INTERRUPTED); 309 return rc; 310 #else 311 return RTSemMutexRequest(MutexSem, cMillies); 312 #endif 313 } 314 315 316 RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies) 317 { 318 #ifndef RTSEMMUTEX_STRICT 319 return rtSemMutexRequest(MutexSem, cMillies, false, RTSEMMUTEX_STRICT_POS_ARGS); 320 #else 321 return RTSemMutexRequestNoResumeDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS); 322 #endif 323 } 324 325 326 RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 327 { 328 #ifdef RTSEMMUTEX_STRICT 329 return rtSemMutexRequest(MutexSem, cMillies, false, RTSEMMUTEX_STRICT_POS_ARGS); 330 #else 331 return RTSemMutexRequest(MutexSem, cMillies); 332 #endif 333 } 334 335 336 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem) 285 337 { 286 338 /* … … 288 340 */ 289 341 struct RTSEMMUTEXINTERNAL *pThis = MutexSem; 290 Assert Return(VALID_PTR(pThis) && pThis->iMagic == RTSEMMUTEX_MAGIC,291 342 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 343 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 292 344 293 345 /* … … 308 360 if (pThis->cNesting > 1) 309 361 { 310 pThis->cNesting--;362 ASMAtomicDecU32(&pThis->cNesting); 311 363 return VINF_SUCCESS; 312 364 } … … 316 368 */ 317 369 #ifdef RTSEMMUTEX_STRICT 318 RTTHREAD Thread = RTThreadSelf(); 319 if (Thread != NIL_RTTHREAD) 320 RTThreadWriteLockDec(Thread); 370 RTThreadWriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec)); 321 371 #endif 322 372 pThis->Owner = (pthread_t)~0; 323 ASMAtomic XchgU32(&pThis->cNesting, 0);373 ASMAtomicWriteU32(&pThis->cNesting, 0); 324 374 325 375 /* -
trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
r8651 r25373 33 33 *******************************************************************************/ 34 34 #include <iprt/semaphore.h> 35 #include "internal/iprt.h" 36 37 #include <iprt/alloc.h> 38 #include <iprt/asm.h> 35 39 #include <iprt/assert.h> 36 #include <iprt/alloc.h> 40 #include <iprt/err.h> 41 #include <iprt/lockvalidator.h> 37 42 #include <iprt/thread.h> 38 #include <iprt/asm.h> 39 #include <iprt/err.h> 43 #include "internal/magics.h" 40 44 #include "internal/strict.h" 41 45 … … 58 62 /** Nesting count. */ 59 63 volatile uint32_t cNesting; 64 /** Magic value (RTSEMMUTEX_MAGIC). */ 65 uint32_t u32Magic; 66 #ifdef RTSEMMUTEX_STRICT 67 /** Lock validator record associated with this mutex. */ 68 RTLOCKVALIDATORREC ValidatorRec; 69 #endif 60 70 }; 61 71 62 72 63 73 64 /**65 * Validate a Mutex semaphore handle passed to one of the interface.66 *67 * @returns true if valid.68 * @returns false if invalid.69 * @param pIntMutexSem Pointer to the mutex semaphore to validate.70 */71 DECLINLINE(bool) rtsemMutexValid(struct RTSEMMUTEXINTERNAL *pIntMutexSem)72 {73 if ((uintptr_t)pIntMutexSem < 0x10000)74 return false;75 76 if (pIntMutexSem->cNesting == (uint32_t)~0)77 return false;78 79 return true;80 }81 82 83 74 RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem) 84 75 { … … 88 79 * Allocate semaphore handle. 89 80 */ 90 struct RTSEMMUTEXINTERNAL *p IntMutexSem= (struct RTSEMMUTEXINTERNAL *)RTMemAlloc(sizeof(struct RTSEMMUTEXINTERNAL));91 if (p IntMutexSem)81 struct RTSEMMUTEXINTERNAL *pThis = (struct RTSEMMUTEXINTERNAL *)RTMemAlloc(sizeof(struct RTSEMMUTEXINTERNAL)); 82 if (pThis) 92 83 { 93 84 /* … … 98 89 if (!rc) 99 90 { 100 rc = pthread_mutex_init(&p IntMutexSem->Mutex, &MutexAttr);91 rc = pthread_mutex_init(&pThis->Mutex, &MutexAttr); 101 92 if (!rc) 102 93 { 103 94 pthread_mutexattr_destroy(&MutexAttr); 104 95 105 pIntMutexSem->Owner = (pthread_t)-1; 106 pIntMutexSem->cNesting = 0; 107 108 *pMutexSem = pIntMutexSem; 96 pThis->Owner = (pthread_t)-1; 97 pThis->cNesting = 0; 98 pThis->u32Magic = RTSEMMUTEX_MAGIC; 99 #ifdef RTSEMMUTEX_STRICT 100 RTLockValidatorInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis); 101 #endif 102 103 *pMutexSem = pThis; 109 104 return VINF_SUCCESS; 110 105 } 111 106 pthread_mutexattr_destroy(&MutexAttr); 112 107 } 113 RTMemFree(p IntMutexSem);108 RTMemFree(pThis); 114 109 } 115 110 else … … 125 120 * Validate input. 126 121 */ 127 if ( !rtsemMutexValid(MutexSem))128 {129 AssertMsgFailed(("Invalid handle %p!\n", MutexSem));130 return VERR_INVALID_HANDLE;131 }122 if (MutexSem == NIL_RTSEMMUTEX) 123 return VINF_SUCCESS; 124 struct RTSEMMUTEXINTERNAL *pThis = MutexSem; 125 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 126 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 132 127 133 128 /* 134 129 * Try destroy it. 135 130 */ 136 struct RTSEMMUTEXINTERNAL *pIntMutexSem = MutexSem; 137 int rc = pthread_mutex_destroy(&pIntMutexSem->Mutex); 131 int rc = pthread_mutex_destroy(&pThis->Mutex); 138 132 if (rc) 139 133 { … … 145 139 * Free the memory and be gone. 146 140 */ 147 pIntMutexSem->Owner = (pthread_t)-1; 148 pIntMutexSem->cNesting = ~0; 149 RTMemTmpFree(pIntMutexSem); 141 ASMAtomicWriteU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD); 142 pThis->Owner = (pthread_t)-1; 143 pThis->cNesting = UINT32_MAX; 144 #ifdef RTSEMMUTEX_STRICT 145 RTLockValidatorDelete(&pThis->ValidatorRec); 146 #endif 147 RTMemTmpFree(pThis); 150 148 151 149 return VINF_SUCCESS; … … 153 151 154 152 155 RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)153 DECL_FORCE_INLINE(int) rtSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, RTSEMMUTEX_STRICT_POS_DECL) 156 154 { 157 155 /* 158 156 * Validate input. 159 157 */ 160 if (!rtsemMutexValid(MutexSem)) 161 { 162 AssertMsgFailed(("Invalid handle %p!\n", MutexSem)); 163 return VERR_INVALID_HANDLE; 164 } 158 struct RTSEMMUTEXINTERNAL *pThis = MutexSem; 159 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 160 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 161 162 #ifdef RTSEMMUTEX_STRICT 163 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 164 RTLockValidatorCheckOrder(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS); 165 #endif 165 166 166 167 /* 167 168 * Check if nested request. 168 169 */ 169 pthread_t Self = pthread_self(); 170 struct RTSEMMUTEXINTERNAL *pIntMutexSem = MutexSem; 171 if ( pIntMutexSem->Owner == Self 172 && pIntMutexSem->cNesting > 0) 173 { 174 pIntMutexSem->cNesting++; 170 pthread_t Self = pthread_self(); 171 if ( pThis->Owner == Self 172 && pThis->cNesting > 0) 173 { 174 ASMAtomicIncU32(&pThis->cNesting); 175 175 return VINF_SUCCESS; 176 176 } 177 #ifndef RTSEMMUTEX_STRICT 178 RTTHREAD hThreadSelf = RTThreadSelf(); 179 #endif 177 180 178 181 /* … … 182 185 { 183 186 /* take mutex */ 184 int rc = pthread_mutex_lock(&pIntMutexSem->Mutex); 187 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec)); 188 int rc = pthread_mutex_lock(&pThis->Mutex); 189 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 185 190 if (rc) 186 191 { … … 209 214 ts.tv_sec++; 210 215 } 216 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec)); 211 217 } 212 218 213 219 /* take mutex */ 214 int rc = pthread_mutex_timedlock(&pIntMutexSem->Mutex, &ts); 220 int rc = pthread_mutex_timedlock(&pThis->Mutex, &ts); 221 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 215 222 if (rc) 216 223 { … … 224 231 * Set the owner and nesting. 225 232 */ 226 pIntMutexSem->Owner = Self; 227 ASMAtomicXchgU32(&pIntMutexSem->cNesting, 1); 228 #ifdef RTSEMMUTEX_STRICT 229 RTTHREAD Thread = RTThreadSelf(); 230 if (Thread != NIL_RTTHREAD) 231 RTThreadWriteLockInc(Thread); 233 pThis->Owner = Self; 234 ASMAtomicWriteU32(&pThis->cNesting, 1); 235 #ifdef RTSEMMUTEX_STRICT 236 RTThreadWriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS)); 232 237 #endif 233 238 … … 236 241 237 242 238 RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies) 243 RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies) 244 { 245 #ifndef RTSEMMUTEX_STRICT 246 return rtSemMutexRequest(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS); 247 #else 248 return RTSemMutexRequestDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS); 249 #endif 250 } 251 252 253 RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 254 { 255 #ifdef RTSEMMUTEX_STRICT 256 return rtSemMutexRequest(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS); 257 #else 258 return RTSemMutexRequest(MutexSem, cMillies); 259 #endif 260 } 261 262 263 RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies) 239 264 { 240 265 /* EINTR isn't returned by the wait functions we're using. */ 266 #ifndef RTSEMMUTEX_STRICT 241 267 return RTSemMutexRequest(MutexSem, cMillies); 268 #else 269 return RTSemMutexRequestDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS); 270 #endif 271 } 272 273 274 RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 275 { 276 /* EINTR isn't returned by the wait functions we're using. */ 277 #ifdef RTSEMMUTEX_STRICT 278 return RTSemMutexRequestDebug(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS); 279 #else 280 return RTSemMutexRequest(MutexSem, cMillies); 281 #endif 242 282 } 243 283 … … 248 288 * Validate input. 249 289 */ 250 if (!rtsemMutexValid(MutexSem)) 251 { 252 AssertMsgFailed(("Invalid handle %p!\n", MutexSem)); 253 return VERR_INVALID_HANDLE; 254 } 290 struct RTSEMMUTEXINTERNAL *pThis = MutexSem; 291 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 292 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 255 293 256 294 /* 257 295 * Check if nested. 258 296 */ 259 pthread_t Self = pthread_self(); 260 struct RTSEMMUTEXINTERNAL *pIntMutexSem = MutexSem; 261 if ( pIntMutexSem->Owner != Self 262 || pIntMutexSem->cNesting == (uint32_t)~0) 297 pthread_t Self = pthread_self(); 298 if (RT_UNLIKELY( pThis->Owner != Self 299 || pThis->cNesting == 0)) 263 300 { 264 301 AssertMsgFailed(("Not owner of mutex %p!! Self=%08x Owner=%08x cNesting=%d\n", 265 p IntMutexSem, Self, pIntMutexSem->Owner, pIntMutexSem->cNesting));302 pThis, Self, pThis->Owner, pThis->cNesting)); 266 303 return VERR_NOT_OWNER; 267 304 } … … 270 307 * If nested we'll just pop a nesting. 271 308 */ 272 if (p IntMutexSem->cNesting > 1)273 { 274 pIntMutexSem->cNesting--;309 if (pThis->cNesting > 1) 310 { 311 ASMAtomicDecU32(&pThis->cNesting); 275 312 return VINF_SUCCESS; 276 313 } … … 280 317 */ 281 318 #ifdef RTSEMMUTEX_STRICT 282 RTTHREAD Thread = RTThreadSelf(); 283 if (Thread != NIL_RTTHREAD) 284 RTThreadWriteLockDec(Thread); 285 #endif 286 pIntMutexSem->Owner = (pthread_t)-1; 287 ASMAtomicXchgU32(&pIntMutexSem->cNesting, 0); 319 RTThreadWriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec)); 320 #endif 321 pThis->Owner = (pthread_t)-1; 322 ASMAtomicXchgU32(&pThis->cNesting, 0); 288 323 289 324 /* 290 325 * Unlock mutex semaphore. 291 326 */ 292 int rc = pthread_mutex_unlock(&p IntMutexSem->Mutex);293 if ( rc)327 int rc = pthread_mutex_unlock(&pThis->Mutex); 328 if (RT_UNLIKELY(rc)) 294 329 { 295 330 AssertMsgFailed(("Failed to unlock mutex sem %p, rc=%d.\n", MutexSem, rc)); NOREF(rc); -
trunk/src/VBox/Runtime/r3/win/sems-win.cpp
r10839 r25373 265 265 } 266 266 267 268 RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 269 { 270 return RTSemMutexRequestNoResume(MutexSem, cMillies); 271 } 272 273 267 274 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem) 268 275 { -
trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
r25368 r25373 104 104 105 105 # if defined(PDMCRITSECT_STRICT) && defined(IN_RING3) 106 RTLockValidatorSetOwner(pCritSect->s.Core.pValidatorRec, NIL_RTTHREAD, PDMCRITSECT_STRICT_ARGS_PASS_ON); 107 RTThreadWriteLockInc(pCritSect->s.Core.pValidatorRec->hThread); 106 RTThreadWriteLockInc(RTLockValidatorSetOwner(pCritSect->s.Core.pValidatorRec, NIL_RTTHREAD, PDMCRITSECT_STRICT_ARGS_PASS_ON)); 108 107 # endif 109 108 … … 136 135 SUPSEMEVENT hEvent = (SUPSEMEVENT)pCritSect->s.Core.EventSem; 137 136 # ifdef PDMCRITSECT_STRICT 138 RTTHREAD hSelf = RTThreadSelf(); 139 if (hSelf == NIL_RTTHREAD) 140 RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &hSelf); 137 RTTHREAD hSelf = RTThreadSelfAutoAdopt(); 141 138 RTLockValidatorCheckOrder(pCritSect->s.Core.pValidatorRec, hSelf, 0, NULL, 0, NULL); 142 139 # endif … … 380 377 #else 381 378 /* No need for a second code instance. */ 382 return PDMCritSectTryEnter Debug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);379 return PDMCritSectTryEnter(pCritSect); 383 380 #endif 384 381 } … … 403 400 && pCritSect->s.Core.pValidatorRec 404 401 && pCritSect->s.Core.pValidatorRec->hThread != NIL_RTTHREAD) 405 { 406 RTThreadWriteLockDec(pCritSect->s.Core.pValidatorRec->hThread); 407 RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec); 408 } 402 RTThreadWriteLockDec(RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec)); 409 403 return rc; 410 404 } … … 452 446 # if defined(PDMCRITSECT_STRICT) 453 447 if (pCritSect->s.Core.pValidatorRec->hThread != NIL_RTTHREAD) 454 { 455 RTThreadWriteLockDec(pCritSect->s.Core.pValidatorRec->hThread); 456 RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec); 457 } 448 RTThreadWriteLockDec(RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec)); 458 449 # endif 459 450 # endif
Note:
See TracChangeset
for help on using the changeset viewer.