Changeset 25373 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Dec 14, 2009 7:20:27 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 55992
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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);
Note:
See TracChangeset
for help on using the changeset viewer.