Changeset 25382 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Dec 15, 2009 12:30:34 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56006
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp
r25381 r25382 37 37 38 38 #include <iprt/semaphore.h> 39 #include "internal/iprt.h" 40 41 #include <iprt/assert.h> 42 #include <iprt/asm.h> 43 #include <iprt/err.h> 44 #include <iprt/lockvalidator.h> 45 #include <iprt/mem.h> 39 46 #include <iprt/thread.h> 40 #include <iprt/assert.h> 41 #include <iprt/err.h> 47 #include "internal/magics.h" 42 48 #include "internal/strict.h" 43 49 … … 46 52 * Defined Constants And Macros * 47 53 *******************************************************************************/ 48 /** Converts semaphore to win32 handle. */ 49 #define SEM2HND(Sem) ((HANDLE)(uintptr_t)Sem) 54 /** Posix internal representation of a Mutex semaphore. */ 55 struct RTSEMMUTEXINTERNAL 56 { 57 /** Magic value (RTSEMMUTEX_MAGIC). */ 58 uint32_t u32Magic; 59 /** The mutex handle. */ 60 HANDLE hMtx; 61 #ifdef RTSEMMUTEX_STRICT 62 /** Lock validator record associated with this mutex. */ 63 RTLOCKVALIDATORREC ValidatorRec; 64 #endif 65 }; 50 66 51 67 … … 57 73 RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem) 58 74 { 75 int rc; 76 59 77 /* 60 78 * Create the semaphore. 61 79 */ 62 HANDLE h mtx = CreateMutex(NULL, FALSE, NULL);63 if (h mtx)80 HANDLE hMtx = CreateMutex(NULL, FALSE, NULL); 81 if (hMtx) 64 82 { 65 *pMutexSem = (RTSEMMUTEX)(void *)hmtx; 83 RTSEMMUTEXINTERNAL *pThis = (RTSEMMUTEXINTERNAL *)RTMemAlloc(sizeof(*pThis)); 84 if (pThis) 85 { 86 pThis->u32Magic = RTSEMMUTEX_MAGIC; 87 pThis->hMtx = hMtx; 88 #ifdef RTSEMMUTEX_STRICT 89 RTLockValidatorInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis); 90 #endif 91 *pMutexSem = pThis; 92 return VINF_SUCCESS; 93 } 94 95 rc = VERR_NO_MEMORY; 96 } 97 else 98 rc = RTErrConvertFromWin32(GetLastError()); 99 return rc; 100 } 101 102 103 RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem) 104 { 105 /* 106 * Validate. 107 */ 108 RTSEMMUTEXINTERNAL *pThis = MutexSem; 109 if (pThis == NIL_RTSEMMUTEX) 66 110 return VINF_SUCCESS; 111 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 112 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 113 114 /* 115 * Close semaphore handle. 116 */ 117 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE); 118 HANDLE hMtx = pThis->hMtx; 119 ASMAtomicWritePtr((void * volatile *)&pThis->hMtx, (void *)INVALID_HANDLE_VALUE); 120 121 int rc = VINF_SUCCESS; 122 if (!CloseHandle(hMtx)) 123 { 124 rc = RTErrConvertFromWin32(GetLastError()); 125 AssertMsgFailed(("%p rc=%d lasterr=%d\n", pThis->hMtx, rc, GetLastError())); 67 126 } 68 127 69 return RTErrConvertFromWin32(GetLastError()); 70 } 71 72 73 RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem) 74 { 75 /* 76 * Close semaphore handle. 77 */ 78 if (CloseHandle(SEM2HND(MutexSem))) 79 return VINF_SUCCESS; 80 AssertMsgFailed(("Destroy MutexSem %p failed, lasterr=%d\n", MutexSem, GetLastError())); 81 return RTErrConvertFromWin32(GetLastError()); 82 } 83 84 85 RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies) 86 { 128 #ifdef RTSEMMUTEX_STRICT 129 RTLockValidatorDelete(&pThis->ValidatorRec); 130 #endif 131 RTMemFree(pThis); 132 return rc; 133 } 134 135 136 /** 137 * Internal worker for RTSemMutexRequestNoResume and it's debug companion. 138 * 139 * @returns Same as RTSEmMutexRequestNoResume 140 * @param MutexSem The mutex handle. 141 * @param cMillies The number of milliseconds to wait. 142 * @param TSEMMUTEX_STRICT_POS_DECL The source position of the caller. 143 */ 144 DECL_FORCE_INLINE(int) rtSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies, RTSEMMUTEX_STRICT_POS_DECL) 145 { 146 /* 147 * Validate. 148 */ 149 RTSEMMUTEXINTERNAL *pThis = MutexSem; 150 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 151 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 152 153 #ifdef RTSEMMUTEX_STRICT 154 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 155 RTLockValidatorCheckOrder(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS); 156 #else 157 RTTHREAD hThreadSelf = RTThreadSelf(); 158 #endif 159 87 160 /* 88 161 * Lock mutex semaphore. 89 162 */ 90 int rc = WaitForSingleObjectEx(SEM2HND(MutexSem), cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, TRUE); 163 if (cMillies > 0) 164 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec)); 165 int rc = WaitForSingleObjectEx(pThis->hMtx, 166 cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, 167 TRUE /*bAlertable*/); 168 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX); 91 169 switch (rc) 92 170 { 93 171 case WAIT_OBJECT_0: 94 { 95 #ifdef RTSEMMUTEX_STRICT 96 RTTHREAD Thread = RTThreadSelf(); 97 if (Thread != NIL_RTTHREAD) 98 RTThreadWriteLockInc(Thread); 172 #ifdef RTSEMMUTEX_STRICT 173 RTThreadWriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS)); 99 174 #endif 100 175 return VINF_SUCCESS; 101 }102 176 103 177 case WAIT_TIMEOUT: return VERR_TIMEOUT; … … 118 192 119 193 120 RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 121 { 194 RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies) 195 { 196 #ifndef RTSEMMUTEX_STRICT 197 return rtSemMutexRequestNoResume(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS); 198 #else 199 return RTSemMutexRequestNoResumeDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS); 200 #endif 201 } 202 203 204 RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL) 205 { 206 #ifdef RTSEMMUTEX_STRICT 207 return rtSemMutexRequestNoResume(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS); 208 #else 122 209 return RTSemMutexRequestNoResume(MutexSem, cMillies); 123 } 124 125 126 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem) 127 { 210 #endif 211 } 212 213 214 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem) 215 { 216 /* 217 * Validate. 218 */ 219 RTSEMMUTEXINTERNAL *pThis = MutexSem; 220 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 221 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 222 128 223 /* 129 224 * Unlock mutex semaphore. 130 225 */ 131 226 #ifdef RTSEMMUTEX_STRICT 132 RTTHREAD Thread = RTThreadSelf(); 133 if (Thread != NIL_RTTHREAD) 134 RTThreadWriteLockDec(Thread); 135 #endif 136 if (ReleaseMutex(SEM2HND(MutexSem))) 227 if ( pThis->ValidatorRec.hThread != NIL_RTTHREAD 228 && pThis->ValidatorRec.hThread == RTThreadSelf()) 229 RTThreadWriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec)); 230 else 231 AssertMsgFailed(("%p hThread=%RTthrd\n", pThis, pThis->ValidatorRec.hThread)); 232 #endif 233 if (ReleaseMutex(pThis->hMtx)) 137 234 return VINF_SUCCESS; 138 139 #ifdef RTSEMMUTEX_STRICT 140 if (Thread != NIL_RTTHREAD) 141 RTThreadWriteLockInc(Thread); 142 #endif 143 AssertMsgFailed(("Release MutexSem %p failed, lasterr=%d\n", MutexSem, GetLastError())); 144 return RTErrConvertFromWin32(GetLastError()); 145 } 146 235 int rc = RTErrConvertFromWin32(GetLastError()); 236 AssertMsgFailed(("%p/%p, rc=%Rrc lasterr=%d\n", pThis, pThis->hMtx, rc, GetLastError())); 237 return rc; 238 } 239 -
trunk/src/VBox/Runtime/testcase/Makefile.kmk
r25059 r25382 92 92 tstSems \ 93 93 tstSemEvent \ 94 tstSemMutex \ 94 95 tstSemPingPong \ 95 96 tstRTStrCache \ … … 124 125 tstInlineAsmPIC \ 125 126 tstInlineAsmPIC3 \ 126 tstSemMutex \127 127 tstSemRW 128 128 PROGRAMS.l4 += \
Note:
See TracChangeset
for help on using the changeset viewer.