Changeset 25714 in vbox
- Timestamp:
- Jan 11, 2010 12:40:15 PM (15 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r25666 r25714 1296 1296 r0drv/linux/semeventmulti-r0drv-linux.c \ 1297 1297 r0drv/linux/semfastmutex-r0drv-linux.c \ 1298 r0drv/linux/semmutex-r0drv-linux.c \ 1298 1299 r0drv/linux/spinlock-r0drv-linux.c \ 1299 1300 r0drv/linux/thread-r0drv-linux.c \ -
trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
r25378 r25714 63 63 64 64 65 /* Undefine debug mappings. */ 66 #undef RTSemMutexRequest 67 #undef RTSemMutexRequestNoResume 68 69 70 RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem) 71 { 72 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pMutexInt)); 73 if (pMutexInt) 74 { 75 pMutexInt->u32Magic = RTSEMMUTEX_MAGIC; 76 init_waitqueue_head(&pMutexInt->Head); 77 *pMutexSem = pMutexInt; 65 66 RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMutexSem) 67 { 68 return RTSemMutexCreateEx(phMutexSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL); 69 } 70 71 72 RTDECL(int) RTSemMutexCreateEx(PRTSEMMUTEX phMutexSem, uint32_t fFlags, 73 RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...) 74 { 75 PRTSEMMUTEXINTERNAL pThis; 76 77 AssertReturn(!(fFlags & ~RTSEMMUTEX_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER); 78 79 pThis = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis)); 80 if (pThis) 81 { 82 pThis->u32Magic = RTSEMMUTEX_MAGIC; 83 pThis->cRecursion = 0; 84 pThis->pOwner = NULL; 85 init_waitqueue_head(&pThis->Head); 86 87 *phMutexSem = pThis; 78 88 AssertReleaseMsgFailed(("This mutex implementation is buggy, fix it!\n")); 79 89 return VINF_SUCCESS; … … 89 99 * Validate input. 90 100 */ 91 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem; 92 if (!pMutexInt) 93 return VERR_INVALID_PARAMETER; 94 if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC) 95 { 96 AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt->u32Magic, pMutexInt)); 97 return VERR_INVALID_PARAMETER; 98 } 101 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem; 102 if (pThis == NIL_RTSEMMUTEX) 103 return VINF_SUCCESS; 104 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 105 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 99 106 100 107 /* 101 108 * Invalidate it and signal the object just in case. 102 109 */ 103 ASMAtomicIncU32(&pMutexInt->u32Magic); 104 ASMAtomicXchgU32(&pMutexInt->cRecursion, 0); 105 Assert(!waitqueue_active(&pMutexInt->Head)); 106 wake_up_all(&pMutexInt->Head); 107 RTMemFree(pMutexInt); 110 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE); 111 ASMAtomicWriteU32(&pThis->cRecursion, 0); 112 Assert(!waitqueue_active(&pThis->Head)); 113 wake_up_all(&pThis->Head); 114 115 RTMemFree(pThis); 108 116 return VINF_SUCCESS; 109 117 } … … 111 119 112 120 121 #undef RTSemMutexRequest 113 122 RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies) 114 123 { 124 int rc = VINF_SUCCESS; 125 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem; 126 115 127 /* 116 128 * Validate input. 117 129 */ 118 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem; 119 if (!pMutexInt) 120 return VERR_INVALID_PARAMETER; 121 if ( !pMutexInt 122 || pMutexInt->u32Magic != RTSEMMUTEX_MAGIC) 123 { 124 AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt)); 125 return VERR_INVALID_PARAMETER; 126 } 130 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 131 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 127 132 128 133 /* 129 134 * Check for recursive request. 130 135 */ 131 if (p MutexInt->pOwner == current)132 { 133 Assert(p MutexInt->cRecursion < 1000);134 ASMAtomicIncU32(&p MutexInt->cRecursion);136 if (pThis->pOwner == current) 137 { 138 Assert(pThis->cRecursion < 1000); 139 ASMAtomicIncU32(&pThis->cRecursion); 135 140 return VINF_SUCCESS; 136 141 } … … 139 144 * Try aquire it. 140 145 */ 141 if (ASMAtomicCmpXchgU32(&pMutexInt->cRecursion, 1, 0)) 142 { 143 ASMAtomicXchgPtr(&pMutexInt->pOwner, current); 144 return VINF_SUCCESS; 145 } 146 if (ASMAtomicCmpXchgU32(&pThis->cRecursion, 1, 0)) 147 ASMAtomicWritePtr(&pThis->pOwner, current); 146 148 else 147 149 { … … 150 152 */ 151 153 DEFINE_WAIT(Wait); 152 int rc = VINF_SUCCESS;153 154 long lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies); 154 155 for (;;) 155 156 { 156 157 /* make everything thru schedule() atomic scheduling wise. */ 157 prepare_to_wait(&p MutexInt->Head, &Wait, TASK_INTERRUPTIBLE);158 prepare_to_wait(&pThis->Head, &Wait, TASK_INTERRUPTIBLE); 158 159 159 160 /* check the condition. */ 160 if (ASMAtomicCmpXchgU32(&p MutexInt->cRecursion, 1, 0))161 { 162 ASMAtomic XchgPtr(&pMutexInt->pOwner, current);161 if (ASMAtomicCmpXchgU32(&pThis->cRecursion, 1, 0)) 162 { 163 ASMAtomicWritePtr(&pThis->pOwner, current); 163 164 break; 164 165 } … … 177 178 178 179 /* Check if someone destroyed the semaphore while we was waiting. */ 179 if (p MutexInt->u32Magic != RTSEMMUTEX_MAGIC)180 if (pThis->u32Magic != RTSEMMUTEX_MAGIC) 180 181 { 181 182 rc = VERR_SEM_DESTROYED; … … 190 191 } 191 192 } 192 finish_wait(&pMutexInt->Head, &Wait); 193 return rc; 194 } 193 finish_wait(&pThis->Head, &Wait); 194 } 195 return rc; 196 } 197 RT_EXPORT_SYMBOL(RTSemMutexRequest); 198 199 200 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem) 201 { 202 /* 203 * Validate input. 204 */ 205 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem; 206 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 207 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 208 209 AssertReturn(pThis->pOwner == current, VERR_NOT_OWNER); 210 211 /* 212 * Release the mutex. 213 */ 214 if (pThis->cRecursion == 1) 215 { 216 ASMAtomicWritePtr(&pThis->pOwner, NULL); 217 ASMAtomicWriteU32(&pThis->cRecursion, 0); 218 wake_up(&pThis->Head); 219 } 220 else 221 ASMAtomicDecU32(&pThis->cRecursion); 222 195 223 return VINF_SUCCESS; 196 224 } 197 RT_EXPORT_SYMBOL(RTSemMutexRequest);198 199 200 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)201 {202 /*203 * Validate input.204 */205 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;206 if (!pMutexInt)207 return VERR_INVALID_PARAMETER;208 if ( !pMutexInt209 || pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)210 {211 AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));212 return VERR_INVALID_PARAMETER;213 }214 if (pMutexInt->pOwner != current)215 {216 AssertMsgFailed(("Not owner, pOwner=%p current=%p\n", (void *)pMutexInt->pOwner, (void *)current));217 return VERR_NOT_OWNER;218 }219 220 /*221 * Release the mutex.222 */223 if (pMutexInt->cRecursion == 1)224 {225 ASMAtomicXchgPtr(&pMutexInt->pOwner, NULL);226 ASMAtomicXchgU32(&pMutexInt->cRecursion, 0);227 }228 else229 ASMAtomicDecU32(&pMutexInt->cRecursion);230 231 return VINF_SUCCESS;232 }233 225 RT_EXPORT_SYMBOL(RTSemMutexRelease); 234 226 -
trunk/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
r25433 r25714 5 5 6 6 /* 7 * Copyright (C) 2006-20 07Sun Microsystems, Inc.7 * Copyright (C) 2006-2010 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 64 64 65 65 66 /* Undefine debug mappings. */ 67 #undef RTSemMutexRequest 68 #undef RTSemMutexRequestNoResume 69 70 71 RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem) 72 { 73 Assert(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *)); 74 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pMutexInt)); 75 if (pMutexInt) 76 { 77 pMutexInt->u32Magic = RTSEMMUTEX_MAGIC; 78 #ifdef RT_USE_FAST_MUTEX 79 ExInitializeFastMutex(&pMutexInt->Mutex); 66 67 RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMutexSem) 68 { 69 return RTSemMutexCreateEx(phMutexSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL); 70 } 71 72 73 RTDECL(int) RTSemMutexCreateEx(PRTSEMMUTEX phMutexSem, uint32_t fFlags, 74 RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...) 75 { 76 AssertReturn(!(fFlags & ~RTSEMMUTEX_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER); 77 78 AssertCompile(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *)); 79 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis)); 80 if (!pThis) 81 return VERR_NO_MEMORY; 82 83 pThis->u32Magic = RTSEMMUTEX_MAGIC; 84 #ifdef RT_USE_FAST_MUTEX 85 ExInitializeFastMutex(&pThis->Mutex); 80 86 #else 81 KeInitializeMutex(&pMutexInt->Mutex, 0);87 KeInitializeMutex(&pThis->Mutex, 0); 82 88 #endif 83 *pMutexSem = pMutexInt; 89 90 *phMutexSem = pThis; 91 return VINF_SUCCESS; 92 } 93 94 95 RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem) 96 { 97 /* 98 * Validate input. 99 */ 100 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem; 101 if (pThis == NIL_RTSEMMUTEX) 84 102 return VINF_SUCCESS; 85 } 86 return VERR_NO_MEMORY; 87 } 88 89 90 RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem) 91 { 92 /* 93 * Validate input. 94 */ 95 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem; 96 if (!pMutexInt) 97 return VERR_INVALID_PARAMETER; 98 AssertReturn(pMutexInt->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 103 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 104 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 99 105 100 106 /* 101 107 * Invalidate it and signal the object just in case. 102 108 */ 103 AssertReturn(ASMAtomicCmpXchgU32(&p MutexInt->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);104 RTMemFree(p MutexInt);109 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE); 110 RTMemFree(pThis); 105 111 return VINF_SUCCESS; 106 112 } … … 122 128 * Validate input. 123 129 */ 124 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem; 125 if (!pMutexInt) 126 return VERR_INVALID_PARAMETER; 127 AssertReturn(pMutexInt->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 130 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem; 131 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 132 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 128 133 129 134 /* … … 132 137 #ifdef RT_USE_FAST_MUTEX 133 138 AssertMsg(cMillies == RT_INDEFINITE_WAIT, ("timeouts are not supported when using fast mutexes!\n")); 134 ExAcquireFastMutex(&p MutexInt->Mutex);139 ExAcquireFastMutex(&pThis->Mutex); 135 140 #else /* !RT_USE_FAST_MUTEX */ 136 141 NTSTATUS rcNt; 137 142 if (cMillies == RT_INDEFINITE_WAIT) 138 rcNt = KeWaitForSingleObject(&p MutexInt->Mutex, Executive, KernelMode, fInterruptible, NULL);143 rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, fInterruptible, NULL); 139 144 else 140 145 { 141 146 LARGE_INTEGER Timeout; 142 147 Timeout.QuadPart = -(int64_t)cMillies * 10000; 143 rcNt = KeWaitForSingleObject(&p MutexInt->Mutex, Executive, KernelMode, fInterruptible, &Timeout);148 rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, fInterruptible, &Timeout); 144 149 } 145 150 switch (rcNt) 146 151 { 147 152 case STATUS_SUCCESS: 148 if (p MutexInt->u32Magic == RTSEMMUTEX_MAGIC)153 if (pThis->u32Magic == RTSEMMUTEX_MAGIC) 149 154 return VINF_SUCCESS; 150 155 return VERR_SEM_DESTROYED; … … 159 164 160 165 default: 161 AssertMsgFailed(("p MutexInt->u32Magic=%RX32 pMutexInt=%p: wait returned %lx!\n",162 p MutexInt->u32Magic, pMutexInt, (long)rcNt));166 AssertMsgFailed(("pThis->u32Magic=%RX32 pThis=%p: wait returned %lx!\n", 167 pThis->u32Magic, pThis, (long)rcNt)); 163 168 return VERR_INTERNAL_ERROR; 164 169 } … … 168 173 169 174 175 #undef RTSemMutexRequest 170 176 RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies) 171 177 { … … 180 186 181 187 188 #undef RTSemMutexRequestNoResume 182 189 RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies) 183 190 { … … 197 204 * Validate input. 198 205 */ 199 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem; 200 if (!pMutexInt) 201 return VERR_INVALID_PARAMETER; 202 AssertReturn(pMutexInt->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 206 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem; 207 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 208 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); 203 209 204 210 /* … … 206 212 */ 207 213 #ifdef RT_USE_FAST_MUTEX 208 ExReleaseFastMutex(&p MutexInt->Mutex);214 ExReleaseFastMutex(&pThis->Mutex); 209 215 #else 210 KeReleaseMutex(&p MutexInt->Mutex, FALSE /*Wait*/);216 KeReleaseMutex(&pThis->Mutex, FALSE /*Wait*/); 211 217 #endif 212 218 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.