Changeset 25368 in vbox for trunk/src/VBox/Runtime/generic
- Timestamp:
- Dec 14, 2009 4:31:40 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/generic/critsect-generic.cpp
r23718 r25368 5 5 6 6 /* 7 * Copyright (C) 2006-200 7Sun Microsystems, Inc.7 * Copyright (C) 2006-2009 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 45 45 46 46 47 /* in strict mode we're redefining this, so undefine itnow for the implementation. */47 /* In strict mode we're redefining these, so undefine them now for the implementation. */ 48 48 #undef RTCritSectEnter 49 49 #undef RTCritSectTryEnter … … 51 51 52 52 53 /**54 * Initialize a critical section.55 */56 53 RTDECL(int) RTCritSectInit(PRTCRITSECT pCritSect) 57 54 { … … 61 58 62 59 63 /**64 * Initialize a critical section.65 *66 * @returns iprt status code.67 * @param pCritSect Pointer to the critical section structure.68 * @param fFlags Flags, any combination of the RTCRITSECT_FLAGS \#defines.69 */70 60 RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags) 71 61 { … … 78 68 pCritSect->cLockers = -1; 79 69 pCritSect->NativeThreadOwner = NIL_RTNATIVETHREAD; 80 pCritSect->Strict.ThreadOwner = NIL_RTTHREAD; 81 pCritSect->Strict.pszEnterFile = NULL; 82 pCritSect->Strict.u32EnterLine = 0; 83 pCritSect->Strict.uEnterId = 0; 84 int rc = RTSemEventCreate(&pCritSect->EventSem); 70 int rc = RTLockValidatorCreate(&pCritSect->pValidatorRec, NIL_RTLOCKVALIDATORCLASS, 0, NULL, pCritSect); 85 71 if (RT_SUCCESS(rc)) 86 return VINF_SUCCESS; 72 { 73 rc = RTSemEventCreate(&pCritSect->EventSem); 74 if (RT_SUCCESS(rc)) 75 return VINF_SUCCESS; 76 RTLockValidatorDestroy(&pCritSect->pValidatorRec); 77 } 87 78 88 79 AssertRC(rc); … … 94 85 95 86 96 /** 97 * Enter multiple critical sections. 98 * 99 * This function will enter ALL the specified critical sections before returning. 100 * 101 * @returns VINF_SUCCESS on success. 102 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 103 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. 104 * @param cCritSects Number of critical sections in the array. 105 * @param papCritSects Array of critical section pointers. 106 * 107 * @remark Please note that this function will not necessarily come out favourable in a 108 * fight with other threads which are using the normal RTCritSectEnter() function. 109 * Therefore, avoid having to enter multiple critical sections! 110 */ 111 RTDECL(int) RTCritSectEnterMultiple(unsigned cCritSects, PRTCRITSECT *papCritSects) 112 #ifdef RTCRITSECT_STRICT 113 { 114 return RTCritSectEnterMultipleDebug(cCritSects, papCritSects, __FILE__, __LINE__, 0); 115 } 116 RTDECL(int) RTCritSectEnterMultipleDebug(unsigned cCritSects, PRTCRITSECT *papCritSects, const char *pszFile, unsigned uLine, RTUINTPTR uId) 117 #endif /* RTCRITSECT_STRICT */ 87 #ifdef RTCRITSECT_STRICT 88 RTDECL(int) RTCritSectEnterMultipleDebug(size_t cCritSects, PRTCRITSECT *papCritSects, RTUINTPTR uId, RT_SRC_POS_DECL) 89 #else 90 RTDECL(int) RTCritSectEnterMultiple(size_t cCritSects, PRTCRITSECT *papCritSects) 91 #endif 118 92 { 119 93 Assert(cCritSects > 0); 120 Assert (VALID_PTR(papCritSects));94 AssertPtr(papCritSects); 121 95 122 96 /* … … 124 98 */ 125 99 int rc = VERR_INVALID_PARAMETER; 126 unsignedi;100 size_t i; 127 101 for (i = 0; i < cCritSects; i++) 128 102 { 129 103 #ifdef RTCRITSECT_STRICT 130 rc = RTCritSectTryEnterDebug(papCritSects[i], pszFile, uLine, uId);104 rc = RTCritSectTryEnterDebug(papCritSects[i], uId, RT_SRC_POS_ARGS); 131 105 #else 132 106 rc = RTCritSectTryEnter(papCritSects[i]); … … 146 120 * We've failed, release any locks we might have gotten. ('i' is the lock that failed btw.) 147 121 */ 148 unsignedj = i;122 size_t j = i; 149 123 while (j-- > 0) 150 124 { … … 166 140 */ 167 141 #ifdef RTCRITSECT_STRICT 168 rc = RTCritSectEnterDebug(papCritSects[i], pszFile, uLine, uId);142 rc = RTCritSectEnterDebug(papCritSects[i], uId, RT_SRC_POS_ARGS); 169 143 #else 170 144 rc = RTCritSectEnter(papCritSects[i]); … … 181 155 { 182 156 #ifdef RTCRITSECT_STRICT 183 rc = RTCritSectTryEnterDebug(papCritSects[j], pszFile, uLine, uId);157 rc = RTCritSectTryEnterDebug(papCritSects[j], uId, RT_SRC_POS_ARGS); 184 158 #else 185 159 rc = RTCritSectTryEnter(papCritSects[j]); … … 203 177 } 204 178 } 179 #ifdef RTCRITSECT_STRICT 180 RT_EXPORT_SYMBOL(RTCritSectEnterMultipleDebug); 181 #else 205 182 RT_EXPORT_SYMBOL(RTCritSectEnterMultiple); 206 207 208 /** 209 * Try enter a critical section. 210 * 211 * @returns VINF_SUCCESS on success. 212 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 213 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. 214 * @param pCritSect The critical section. 215 */ 183 #endif 184 185 186 #ifdef RTCRITSECT_STRICT 187 RTDECL(int) RTCritSectEnterMultiple(size_t cCritSects, PRTCRITSECT *papCritSects) 188 { 189 return RTCritSectEnterMultipleDebug(cCritSects, papCritSects, 0, RT_SRC_POS); 190 } 191 RT_EXPORT_SYMBOL(RTCritSectEnterMultiple); 192 193 194 #else /* !RTCRITSECT_STRICT */ 195 RTDECL(int) RTCritSectEnterMultipleDebug(size_t cCritSects, PRTCRITSECT *papCritSects, RTUINTPTR uId, RT_SRC_POS_DECL) 196 { 197 return RTCritSectEnterMultiple(cCritSects, papCritSects); 198 } 199 RT_EXPORT_SYMBOL(RTCritSectEnterMultipleDebug); 200 #endif /* !RTCRITSECT_STRICT */ 201 202 203 #ifdef RTCRITSECT_STRICT 204 RTDECL(int) RTCritSectTryEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL) 205 #else 216 206 RTDECL(int) RTCritSectTryEnter(PRTCRITSECT pCritSect) 217 #ifdef RTCRITSECT_STRICT 218 { 219 return RTCritSectTryEnterDebug(pCritSect, __FILE__, __LINE__, 0); 220 } 221 RTDECL(int) RTCritSectTryEnterDebug(PRTCRITSECT pCritSect, const char *pszFile, unsigned uLine, RTUINTPTR uId) 222 #endif /* RTCRITSECT_STRICT */ 207 #endif 223 208 { 224 209 Assert(pCritSect); … … 259 244 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf); 260 245 #ifdef RTCRITSECT_STRICT 261 pCritSect->Strict.pszEnterFile = pszFile; 262 pCritSect->Strict.u32EnterLine = uLine; 263 pCritSect->Strict.uEnterId = uId; 264 ASMAtomicWriteHandle(&pCritSect->Strict.ThreadOwner, ThreadSelf); 246 RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS); 265 247 #endif 266 248 267 249 return VINF_SUCCESS; 268 250 } 251 #ifdef RTCRITSECT_STRICT 252 RT_EXPORT_SYMBOL(RTCritSectTryEnterDebug); 253 #else 269 254 RT_EXPORT_SYMBOL(RTCritSectTryEnter); 270 271 272 /** 273 * Enter a critical section. 274 * 275 * @returns VINF_SUCCESS on success. 276 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 277 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. 278 * @param pCritSect The critical section. 279 */ 255 #endif 256 257 258 #ifdef RTCRITSECT_STRICT 259 RTDECL(int) RTCritSectTryEnter(PRTCRITSECT pCritSect) 260 { 261 return RTCritSectTryEnterDebug(pCritSect, 0, RT_SRC_POS); 262 } 263 RT_EXPORT_SYMBOL(RTCritSectTryEnter); 264 265 266 #else /* !RTCRITSECT_STRICT */ 267 RTDECL(int) RTCritSectTryEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL) 268 { 269 return RTCritSectTryEnter(pCritSect); 270 } 271 RT_EXPORT_SYMBOL(RTCritSectTryEnterDebug); 272 #endif /* !RTCRITSECT_STRICT */ 273 274 275 #ifdef RTCRITSECT_STRICT 276 RTDECL(int) RTCritSectEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL) 277 #else 280 278 RTDECL(int) RTCritSectEnter(PRTCRITSECT pCritSect) 281 #ifdef RTCRITSECT_STRICT 282 { 283 return RTCritSectEnterDebug(pCritSect, __FILE__, __LINE__, 0); 284 } 285 RTDECL(int) RTCritSectEnterDebug(PRTCRITSECT pCritSect, const char *pszFile, unsigned uLine, RTUINTPTR uId) 286 #endif /* RTCRITSECT_STRICT */ 279 #endif 287 280 { 288 281 Assert(pCritSect); … … 293 286 if (ThreadSelf == NIL_RTTHREAD) 294 287 RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &ThreadSelf); 288 RTLockValidatorCheckOrder(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS); 295 289 #endif 296 290 … … 324 318 { 325 319 #ifdef RTCRITSECT_STRICT 326 RTThreadBlocking(ThreadSelf, RTTHREADSTATE_CRITSECT, (uintptr_t)pCritSect, pszFile, uLine, uId);320 RTThreadBlocking(ThreadSelf, RTTHREADSTATE_CRITSECT, pCritSect->pValidatorRec, uId, RT_SRC_POS_ARGS); 327 321 #endif 328 322 int rc = RTSemEventWait(pCritSect->EventSem, RT_INDEFINITE_WAIT); … … 345 339 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf); 346 340 #ifdef RTCRITSECT_STRICT 347 pCritSect->Strict.pszEnterFile = pszFile; 348 pCritSect->Strict.u32EnterLine = uLine; 349 pCritSect->Strict.uEnterId = uId; 350 ASMAtomicWriteHandle(&pCritSect->Strict.ThreadOwner, ThreadSelf); 341 RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS); 351 342 RTThreadWriteLockInc(ThreadSelf); 352 343 #endif … … 354 345 return VINF_SUCCESS; 355 346 } 347 #ifdef RTCRITSECT_STRICT 348 RT_EXPORT_SYMBOL(RTCritSectEnterDebug); 349 #else 356 350 RT_EXPORT_SYMBOL(RTCritSectEnter); 357 358 359 /** 360 * Leave a critical section. 361 * 362 * @returns VINF_SUCCESS. 363 * @param pCritSect The critical section. 364 */ 351 #endif 352 353 354 #ifdef RTCRITSECT_STRICT 355 RTDECL(int) RTCritSectEnter(PRTCRITSECT pCritSect) 356 { 357 return RTCritSectEnterDebug(pCritSect, 0, RT_SRC_POS); 358 } 359 RT_EXPORT_SYMBOL(RTCritSectEnter); 360 361 362 #else /* !RTCRITSECT_STRICT */ 363 RTDECL(int) RTCritSectEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL) 364 { 365 return RTCritSectEnter(pCritSect); 366 } 367 RT_EXPORT_SYMBOL(RTCritSectEnterDebug); 368 #endif /* !RTCRITSECT_STRICT */ 369 370 365 371 RTDECL(int) RTCritSectLeave(PRTCRITSECT pCritSect) 366 372 { … … 387 393 */ 388 394 #ifdef RTCRITSECT_STRICT 389 if (pCritSect->Strict.ThreadOwner != NIL_RTTHREAD) /* May happen for PDMCritSects when entering GC/R0. */ 390 RTThreadWriteLockDec(pCritSect->Strict.ThreadOwner); 391 ASMAtomicWriteHandle(&pCritSect->Strict.ThreadOwner, NIL_RTTHREAD); 395 RTLockValidatorUnsetOwner(pCritSect->pValidatorRec); 392 396 #endif 393 397 ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NIL_RTNATIVETHREAD); … … 403 407 404 408 405 /** 406 * Leave multiple critical sections. 407 * 408 * @returns VINF_SUCCESS. 409 * @param cCritSects Number of critical sections in the array. 410 * @param papCritSects Array of critical section pointers. 411 */ 412 RTDECL(int) RTCritSectLeaveMultiple(unsigned cCritSects, PRTCRITSECT *papCritSects) 409 RTDECL(int) RTCritSectLeaveMultiple(size_t cCritSects, PRTCRITSECT *papCritSects) 413 410 { 414 411 int rc = VINF_SUCCESS; 415 for ( unsignedi = 0; i < cCritSects; i++)412 for (size_t i = 0; i < cCritSects; i++) 416 413 { 417 414 int rc2 = RTCritSectLeave(papCritSects[i]); … … 424 421 425 422 426 #ifndef RTCRITSECT_STRICT427 RTDECL(int) RTCritSectEnterDebug(PRTCRITSECT pCritSect, const char *pszFile, unsigned uLine, RTUINTPTR uId)428 {429 return RTCritSectEnter(pCritSect);430 }431 432 RTDECL(int) RTCritSectTryEnterDebug(PRTCRITSECT pCritSect, const char *pszFile, unsigned uLine, RTUINTPTR uId)433 {434 return RTCritSectTryEnter(pCritSect);435 }436 437 RTDECL(int) RTCritSectEnterMultipleDebug(unsigned cCritSects, PRTCRITSECT *papCritSects, const char *pszFile, unsigned uLine, RTUINTPTR uId)438 {439 return RTCritSectEnterMultiple(cCritSects, papCritSects);440 }441 #endif /* RT_STRICT */442 RT_EXPORT_SYMBOL(RTCritSectEnterDebug);443 RT_EXPORT_SYMBOL(RTCritSectTryEnterDebug);444 RT_EXPORT_SYMBOL(RTCritSectEnterMultipleDebug);445 446 447 /**448 * Deletes a critical section.449 *450 * @returns VINF_SUCCESS.451 * @param pCritSect The critical section.452 */453 423 RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect) 454 424 { … … 472 442 RTSEMEVENT EventSem = pCritSect->EventSem; 473 443 pCritSect->EventSem = NIL_RTSEMEVENT; 444 474 445 while (pCritSect->cLockers-- >= 0) 475 446 RTSemEventSignal(EventSem); … … 478 449 AssertRC(rc); 479 450 451 RTLockValidatorDestroy(&pCritSect->pValidatorRec); 452 480 453 return rc; 481 454 }
Note:
See TracChangeset
for help on using the changeset viewer.