Changeset 28533 in vbox for trunk/src/VBox/Runtime/r0drv
- Timestamp:
- Apr 20, 2010 5:38:34 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 60339
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c
r28532 r28533 59 59 /** The number of recursions. */ 60 60 uint32_t cRecursions; 61 /** Whether we are being woken up by a release. */ 62 uint8_t volatile fSignaled; 63 /** The number of waiting threads. */ 61 /** The number of threads waiting for the mutex. */ 64 62 uint32_t volatile cWaiters; 65 /** The number of threads in the process of waking up. */66 uint32_t volatile c Waking;63 /** The number of threads referencing us. */ 64 uint32_t volatile cRefs; 67 65 /** The owner thread, NIL_RTNATIVETHREAD if none. */ 68 66 RTNATIVETHREAD hOwnerThread; … … 88 86 pThis->u32Magic = RTSEMMUTEX_MAGIC; 89 87 pThis->cRecursions = 0; 90 pThis->fSignaled = false;91 88 pThis->cWaiters = 0; 92 pThis->c Waking = 0;93 pThis->hOwnerThread 89 pThis->cRefs = 1; 90 pThis->hOwnerThread = NIL_RTNATIVETHREAD; 94 91 mutex_init(&pThis->Mtx, "IPRT Mutex", MUTEX_DRIVER, (void *)ipltospl(DISP_LEVEL)); 95 92 cv_init(&pThis->Cnd, "IPRT CVM", CV_DRIVER, NULL); … … 113 110 mutex_enter(&pThis->Mtx); 114 111 112 ASMAtomicDecU32(&pThis->cRefs); 113 115 114 /* 116 115 * Invalidate the magic to indicate the mutex is being destroyed. … … 122 121 * Wake up all waiters, last waiter thread cleans up. 123 122 */ 124 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);125 123 cv_broadcast(&pThis->Cnd); 126 124 mutex_exit(&pThis->Mtx); 127 125 } 128 else if (pThis->cWaking) 129 { 130 /* 131 * We're not the last waiting thread to be woken up. Just relinquish & bail. 132 */ 133 mutex_exit(&pThis->Mtx); 134 } 135 else 126 else if (pThis->cRefs == 0) 136 127 { 137 128 /* … … 142 133 mutex_destroy(&pThis->Mtx); 143 134 RTMemFree(pThis); 135 } 136 else 137 { 138 /* 139 * We're not the last waiting thread to be woken up. Just relinquish & bail. 140 */ 141 mutex_exit(&pThis->Mtx); 144 142 } 145 143 … … 166 164 167 165 /* 168 * Now we wait (sleep; although might spin and then sleep) .166 * Now we wait (sleep; although might spin and then sleep) & reference the mutex. 169 167 */ 170 168 ASMAtomicIncU32(&pThis->cWaiters); 169 ASMAtomicIncU32(&pThis->cRefs); 171 170 172 171 if (cMillies != RT_INDEFINITE_WAIT) … … 191 190 } 192 191 192 ASMAtomicDecU32(&pThis->cWaiters); 193 193 if (rc > 0) 194 194 { 195 195 if (pThis->u32Magic == RTSEMMUTEX_MAGIC) 196 196 { 197 if (pThis-> fSignaled)197 if (pThis->hOwnerThread == NIL_RTNATIVETHREAD) 198 198 { 199 199 /* 200 200 * Woken up by a release from another thread. 201 201 */ 202 ASMAtomicDecU32(&pThis->cWaking); 203 ASMAtomicXchgU8(&pThis->fSignaled, false); 204 pThis->cRecursions++; 202 Assert(pThis->cRecursions == 0); 203 pThis->cRecursions = 1; 205 204 pThis->hOwnerThread = RTThreadNativeSelf(); 206 205 rc = VINF_SUCCESS; … … 212 211 */ 213 212 rc= VERR_INTERRUPTED; 214 ASMAtomicDecU32(&pThis->cWaiters);215 213 } 216 214 } … … 222 220 */ 223 221 rc = VERR_SEM_DESTROYED; 224 if (!ASMAtomicDecU32(&pThis->c Waking))222 if (!ASMAtomicDecU32(&pThis->cRefs)) 225 223 { 226 224 mutex_exit(&pThis->Mtx); … … 238 236 */ 239 237 rc = VERR_TIMEOUT; 240 ASMAtomicDecU32(&pThis->cWaiters);241 238 } 242 239 else … … 246 243 */ 247 244 rc = VERR_INTERRUPTED; 248 ASMAtomicDecU32(&pThis->cWaiters);249 245 } 250 246 … … 266 262 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 267 263 AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 264 Assert(pThis->cRefs >= 1); 268 265 269 266 /* … … 280 277 /* 281 278 * Not a recursion, make sure we don't sneak in when another thread 282 * is being woken up (fSignaled).279 * is being woken up. 283 280 */ 284 281 else if ( pThis->hOwnerThread == NIL_RTNATIVETHREAD 285 && pThis->cWaiters == 0 286 && pThis->fSignaled == false) 282 && pThis->cWaiters == 0) 287 283 { 288 284 pThis->cRecursions = 1; … … 358 354 */ 359 355 if (pThis->cWaiters > 0) 360 {361 ASMAtomicXchgU8(&pThis->fSignaled, true);362 ASMAtomicDecU32(&pThis->cWaiters);363 ASMAtomicIncU32(&pThis->cWaking);364 356 cv_signal(&pThis->Cnd); 365 }366 357 } 367 358 rc = VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.