Changeset 28503 in vbox for trunk/src/VBox/Runtime/r0drv/darwin/semfastmutex-r0drv-darwin.cpp
- Timestamp:
- Apr 20, 2010 7:19:05 AM (15 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/darwin/semfastmutex-r0drv-darwin.cpp
r28501 r28503 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - Semaphores, Ring-0 Driver, Darwin.3 * IPRT - Fast Mutex Semaphores, Ring-0 Driver, Darwin. 4 4 */ 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 … … 51 51 *******************************************************************************/ 52 52 /** 53 * Darwin event semaphore.54 */55 typedef struct RTSEMEVENTINTERNAL56 {57 /** Magic value (RTSEMEVENT_MAGIC). */58 uint32_t volatile u32Magic;59 /** The number of waiting threads. */60 uint32_t volatile cWaiters;61 /** Set if the event object is signaled. */62 uint8_t volatile fSignaled;63 /** The number of threads in the process of waking up. */64 uint32_t volatile cWaking;65 /** The spinlock protecting us. */66 lck_spin_t *pSpinlock;67 } RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;68 69 70 /**71 * Darwin multiple release event semaphore.72 */73 typedef struct RTSEMEVENTMULTIINTERNAL74 {75 /** Magic value (RTSEMEVENTMULTI_MAGIC). */76 uint32_t volatile u32Magic;77 /** The number of waiting threads. */78 uint32_t volatile cWaiters;79 /** Set if the event object is signaled. */80 uint8_t volatile fSignaled;81 /** The number of threads in the process of waking up. */82 uint32_t volatile cWaking;83 /** The spinlock protecting us. */84 lck_spin_t *pSpinlock;85 } RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;86 87 88 #if 0 /** @todo */89 /**90 * Darwin mutex semaphore.91 */92 typedef struct RTSEMMUTEXINTERNAL93 {94 /** Magic value (RTSEMMUTEX_MAGIC). */95 uint32_t volatile u32Magic;96 /** The mutex. */97 lck_mtx_t *pMtx;98 } RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;99 100 #endif101 102 103 /**104 53 * Wrapper for the darwin semaphore structure. 105 54 */ … … 111 60 lck_mtx_t *pMtx; 112 61 } RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL; 113 114 115 116 RTDECL(int) RTSemEventCreate(PRTSEMEVENT phEventSem)117 {118 return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);119 }120 121 122 RTDECL(int) RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...)123 {124 AssertCompile(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));125 AssertReturn(!(fFlags & ~RTSEMEVENT_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);126 AssertPtrReturn(phEventSem, VERR_INVALID_POINTER);127 RT_ASSERT_PREEMPTIBLE();128 129 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pThis));130 if (pThis)131 {132 pThis->u32Magic = RTSEMEVENT_MAGIC;133 pThis->cWaiters = 0;134 pThis->cWaking = 0;135 pThis->fSignaled = 0;136 Assert(g_pDarwinLockGroup);137 pThis->pSpinlock = lck_spin_alloc_init(g_pDarwinLockGroup, LCK_ATTR_NULL);138 if (pThis->pSpinlock)139 {140 *phEventSem = pThis;141 return VINF_SUCCESS;142 }143 144 pThis->u32Magic = 0;145 RTMemFree(pThis);146 }147 return VERR_NO_MEMORY;148 }149 150 151 RTDECL(int) RTSemEventDestroy(RTSEMEVENT hEventSem)152 {153 PRTSEMEVENTINTERNAL pThis = hEventSem;154 if (pThis == NIL_RTSEMEVENT)155 return VINF_SUCCESS;156 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);157 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);158 RT_ASSERT_INTS_ON();159 160 lck_spin_lock(pThis->pSpinlock);161 ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */162 if (pThis->cWaiters > 0)163 {164 /* abort waiting thread, last man cleans up. */165 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);166 thread_wakeup_prim((event_t)pThis, FALSE /* all threads */, THREAD_RESTART);167 lck_spin_unlock(pThis->pSpinlock);168 }169 else if (pThis->cWaking)170 /* the last waking thread is gonna do the cleanup */171 lck_spin_unlock(pThis->pSpinlock);172 else173 {174 lck_spin_unlock(pThis->pSpinlock);175 lck_spin_destroy(pThis->pSpinlock, g_pDarwinLockGroup);176 RTMemFree(pThis);177 }178 179 return VINF_SUCCESS;180 }181 182 183 RTDECL(int) RTSemEventSignal(RTSEMEVENT hEventSem)184 {185 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;186 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);187 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC,188 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),189 VERR_INVALID_HANDLE);190 RT_ASSERT_PREEMPT_CPUID_VAR();191 RT_ASSERT_INTS_ON();192 193 /** @todo should probably disable interrupts here... update194 * semspinmutex-r0drv-generic.c when done. */195 lck_spin_lock(pThis->pSpinlock);196 197 if (pThis->cWaiters > 0)198 {199 ASMAtomicDecU32(&pThis->cWaiters);200 ASMAtomicIncU32(&pThis->cWaking);201 thread_wakeup_prim((event_t)pThis, TRUE /* one thread */, THREAD_AWAKENED);202 /** @todo this isn't safe. a scheduling interrupt on the other cpu while we're in here203 * could cause the thread to be timed out before we manage to wake it up and the event204 * ends up in the wrong state. ditto for posix signals.205 * Update: check the return code; it will return KERN_NOT_WAITING if no one is around. */206 }207 else208 ASMAtomicXchgU8(&pThis->fSignaled, true);209 210 lck_spin_unlock(pThis->pSpinlock);211 212 RT_ASSERT_PREEMPT_CPUID();213 return VINF_SUCCESS;214 }215 216 217 static int rtSemEventWait(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies, wait_interrupt_t fInterruptible)218 {219 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;220 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);221 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);222 if (cMillies)223 RT_ASSERT_PREEMPTIBLE();224 225 lck_spin_lock(pThis->pSpinlock);226 227 int rc;228 if (pThis->fSignaled)229 {230 Assert(!pThis->cWaiters);231 ASMAtomicXchgU8(&pThis->fSignaled, false);232 rc = VINF_SUCCESS;233 }234 else if (!cMillies)235 rc = VERR_TIMEOUT;236 else237 {238 ASMAtomicIncU32(&pThis->cWaiters);239 240 wait_result_t rcWait;241 if (cMillies == RT_INDEFINITE_WAIT)242 rcWait = lck_spin_sleep(pThis->pSpinlock, LCK_SLEEP_DEFAULT, (event_t)pThis, fInterruptible);243 else244 {245 uint64_t u64AbsTime;246 nanoseconds_to_absolutetime(cMillies * UINT64_C(1000000), &u64AbsTime);247 u64AbsTime += mach_absolute_time();248 249 rcWait = lck_spin_sleep_deadline(pThis->pSpinlock, LCK_SLEEP_DEFAULT,250 (event_t)pThis, fInterruptible, u64AbsTime);251 }252 switch (rcWait)253 {254 case THREAD_AWAKENED:255 Assert(pThis->cWaking > 0);256 if ( !ASMAtomicDecU32(&pThis->cWaking)257 && pThis->u32Magic != RTSEMEVENT_MAGIC)258 {259 /* the event was destroyed after we woke up, as the last thread do the cleanup. */260 lck_spin_unlock(pThis->pSpinlock);261 Assert(g_pDarwinLockGroup);262 lck_spin_destroy(pThis->pSpinlock, g_pDarwinLockGroup);263 RTMemFree(pThis);264 return VINF_SUCCESS;265 }266 rc = VINF_SUCCESS;267 break;268 269 case THREAD_TIMED_OUT:270 Assert(cMillies != RT_INDEFINITE_WAIT);271 ASMAtomicDecU32(&pThis->cWaiters);272 rc = VERR_TIMEOUT;273 break;274 275 case THREAD_INTERRUPTED:276 Assert(fInterruptible);277 ASMAtomicDecU32(&pThis->cWaiters);278 rc = VERR_INTERRUPTED;279 break;280 281 case THREAD_RESTART:282 /* Last one out does the cleanup. */283 if (!ASMAtomicDecU32(&pThis->cWaking))284 {285 lck_spin_unlock(pThis->pSpinlock);286 Assert(g_pDarwinLockGroup);287 lck_spin_destroy(pThis->pSpinlock, g_pDarwinLockGroup);288 RTMemFree(pThis);289 return VERR_SEM_DESTROYED;290 }291 292 rc = VERR_SEM_DESTROYED;293 break;294 295 default:296 AssertMsgFailed(("rcWait=%d\n", rcWait));297 rc = VERR_GENERAL_FAILURE;298 break;299 }300 }301 302 lck_spin_unlock(pThis->pSpinlock);303 return rc;304 }305 306 307 RTDECL(int) RTSemEventWait(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies)308 {309 return rtSemEventWait(hEventSem, cMillies, THREAD_UNINT);310 }311 312 313 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies)314 {315 return rtSemEventWait(hEventSem, cMillies, THREAD_ABORTSAFE);316 }317 318 319 320 RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)321 {322 return RTSemEventMultiCreateEx(phEventMultiSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);323 }324 325 326 RTDECL(int) RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,327 const char *pszNameFmt, ...)328 {329 AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);330 AssertCompile(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *));331 AssertPtrReturn(phEventMultiSem, VERR_INVALID_POINTER);332 RT_ASSERT_PREEMPTIBLE();333 334 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));335 if (pThis)336 {337 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;338 pThis->cWaiters = 0;339 pThis->cWaking = 0;340 pThis->fSignaled = 0;341 Assert(g_pDarwinLockGroup);342 pThis->pSpinlock = lck_spin_alloc_init(g_pDarwinLockGroup, LCK_ATTR_NULL);343 if (pThis->pSpinlock)344 {345 *phEventMultiSem = pThis;346 return VINF_SUCCESS;347 }348 349 pThis->u32Magic = 0;350 RTMemFree(pThis);351 }352 return VERR_NO_MEMORY;353 }354 355 356 RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)357 {358 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;359 if (pThis == NIL_RTSEMEVENTMULTI)360 return VINF_SUCCESS;361 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);362 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);363 RT_ASSERT_INTS_ON();364 365 lck_spin_lock(pThis->pSpinlock);366 ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */367 if (pThis->cWaiters > 0)368 {369 /* abort waiting thread, last man cleans up. */370 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);371 thread_wakeup_prim((event_t)pThis, FALSE /* all threads */, THREAD_RESTART);372 lck_spin_unlock(pThis->pSpinlock);373 }374 else if (pThis->cWaking)375 /* the last waking thread is gonna do the cleanup */376 lck_spin_unlock(pThis->pSpinlock);377 else378 {379 lck_spin_unlock(pThis->pSpinlock);380 lck_spin_destroy(pThis->pSpinlock, g_pDarwinLockGroup);381 RTMemFree(pThis);382 }383 384 return VINF_SUCCESS;385 }386 387 388 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)389 {390 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;391 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);392 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);393 RT_ASSERT_PREEMPT_CPUID_VAR();394 RT_ASSERT_INTS_ON();395 396 lck_spin_lock(pThis->pSpinlock);397 398 ASMAtomicXchgU8(&pThis->fSignaled, true);399 if (pThis->cWaiters > 0)400 {401 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);402 ASMAtomicXchgU32(&pThis->cWaiters, 0);403 thread_wakeup_prim((event_t)pThis, FALSE /* all threads */, THREAD_AWAKENED);404 }405 406 lck_spin_unlock(pThis->pSpinlock);407 408 RT_ASSERT_PREEMPT_CPUID();409 return VINF_SUCCESS;410 }411 412 413 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem)414 {415 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;416 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);417 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);418 RT_ASSERT_PREEMPT_CPUID_VAR();419 RT_ASSERT_INTS_ON();420 421 lck_spin_lock(pThis->pSpinlock);422 ASMAtomicXchgU8(&pThis->fSignaled, false);423 lck_spin_unlock(pThis->pSpinlock);424 425 RT_ASSERT_PREEMPT_CPUID();426 return VINF_SUCCESS;427 }428 429 430 static int rtSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies, wait_interrupt_t fInterruptible)431 {432 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;433 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);434 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);435 if (cMillies)436 RT_ASSERT_PREEMPTIBLE();437 438 lck_spin_lock(pThis->pSpinlock);439 440 int rc;441 if (pThis->fSignaled)442 rc = VINF_SUCCESS;443 else if (!cMillies)444 rc = VERR_TIMEOUT;445 else446 {447 ASMAtomicIncU32(&pThis->cWaiters);448 449 wait_result_t rcWait;450 if (cMillies == RT_INDEFINITE_WAIT)451 rcWait = lck_spin_sleep(pThis->pSpinlock, LCK_SLEEP_DEFAULT, (event_t)pThis, fInterruptible);452 else453 {454 uint64_t u64AbsTime;455 nanoseconds_to_absolutetime(cMillies * UINT64_C(1000000), &u64AbsTime);456 u64AbsTime += mach_absolute_time();457 458 rcWait = lck_spin_sleep_deadline(pThis->pSpinlock, LCK_SLEEP_DEFAULT,459 (event_t)pThis, fInterruptible, u64AbsTime);460 }461 switch (rcWait)462 {463 case THREAD_AWAKENED:464 Assert(pThis->cWaking > 0);465 if ( !ASMAtomicDecU32(&pThis->cWaking)466 && pThis->u32Magic != RTSEMEVENTMULTI_MAGIC)467 {468 /* the event was destroyed after we woke up, as the last thread do the cleanup. */469 lck_spin_unlock(pThis->pSpinlock);470 Assert(g_pDarwinLockGroup);471 lck_spin_destroy(pThis->pSpinlock, g_pDarwinLockGroup);472 RTMemFree(pThis);473 return VINF_SUCCESS;474 }475 rc = VINF_SUCCESS;476 break;477 478 case THREAD_TIMED_OUT:479 Assert(cMillies != RT_INDEFINITE_WAIT);480 ASMAtomicDecU32(&pThis->cWaiters);481 rc = VERR_TIMEOUT;482 break;483 484 case THREAD_INTERRUPTED:485 Assert(fInterruptible);486 ASMAtomicDecU32(&pThis->cWaiters);487 rc = VERR_INTERRUPTED;488 break;489 490 case THREAD_RESTART:491 /* Last one out does the cleanup. */492 if (!ASMAtomicDecU32(&pThis->cWaking))493 {494 lck_spin_unlock(pThis->pSpinlock);495 Assert(g_pDarwinLockGroup);496 lck_spin_destroy(pThis->pSpinlock, g_pDarwinLockGroup);497 RTMemFree(pThis);498 return VERR_SEM_DESTROYED;499 }500 501 rc = VERR_SEM_DESTROYED;502 break;503 504 default:505 AssertMsgFailed(("rcWait=%d\n", rcWait));506 rc = VERR_GENERAL_FAILURE;507 break;508 }509 }510 511 lck_spin_unlock(pThis->pSpinlock);512 return rc;513 }514 515 516 RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)517 {518 return rtSemEventMultiWait(hEventMultiSem, cMillies, THREAD_UNINT);519 }520 521 522 RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)523 {524 return rtSemEventMultiWait(hEventMultiSem, cMillies, THREAD_ABORTSAFE);525 }526 527 528 529 530 531 #if 0 /* need proper timeout lock function! */532 RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phFastMtx)533 {534 RT_ASSERT_PREEMPTIBLE();535 AssertCompile(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));536 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis));537 if (pThis)538 {539 pThis->u32Magic = RTSEMMUTEX_MAGIC;540 Assert(g_pDarwinLockGroup);541 pThis->pMtx = lck_mtx_alloc_init(g_pDarwinLockGroup, LCK_ATTR_NULL);542 if (pThis->pMtx)543 {544 *phFastMtx = pThis;545 return VINF_SUCCESS;546 }547 RTMemFree(pThis);548 }549 return VERR_NO_MEMORY;550 }551 552 553 RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX hMutexSem)554 {555 /*556 * Validate input.557 */558 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;559 if (!pThis)560 return VERR_INVALID_PARAMETER;561 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);562 AssertMsg(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);563 RT_ASSERT_INTS_ON();564 565 /*566 * Invalidate it and signal the object just in case.567 */568 ASMAtomicIncU32(&pThis->u32Magic);569 570 Assert(g_pDarwinLockGroup);571 lck_mtx_free(pThis->pMtx, g_pDarwinLockGroup);572 pThis->pMtx = NULL;573 574 RTMemFree(pThis);575 return VINF_SUCCESS;576 }577 578 579 RTDECL(int) RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)580 {581 /*582 * Validate input.583 */584 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;585 if (!pThis)586 return VERR_INVALID_PARAMETER;587 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);588 AssertMsg(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);589 if (cMillies)590 RT_ASSERT_PREEMPTIBLE();591 592 /*593 * Get the mutex.594 */595 wait_result_t rc = lck_mtx_lock_deadlink596 #if 1597 #else598 NTSTATUS rcNt;599 if (cMillies == RT_INDEFINITE_WAIT)600 rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, TRUE, NULL);601 else602 {603 LARGE_INTEGER Timeout;604 Timeout.QuadPart = -(int64_t)cMillies * 10000;605 rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, TRUE, &Timeout);606 }607 switch (rcNt)608 {609 case STATUS_SUCCESS:610 if (pThis->u32Magic == RTSEMMUTEX_MAGIC)611 return VINF_SUCCESS;612 return VERR_SEM_DESTROYED;613 case STATUS_ALERTED:614 return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */615 case STATUS_USER_APC:616 return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */617 case STATUS_TIMEOUT:618 return VERR_TIMEOUT;619 default:620 AssertMsgFailed(("pThis->u32Magic=%RX32 pThis=%p: wait returned %lx!\n",621 pThis->u32Magic, pThis, (long)rcNt));622 return VERR_INTERNAL_ERROR;623 }624 #endif625 return VINF_SUCCESS;626 }627 628 629 RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem)630 {631 /*632 * Validate input.633 */634 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;635 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);636 AssertMsg(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);637 RT_ASSERT_PREEMPTIBLE();638 639 /*640 * Release the mutex.641 */642 #ifdef RT_USE_FAST_MUTEX643 ExReleaseFastMutex(&pThis->Mutex);644 #else645 KeReleaseMutex(&pThis->Mutex, FALSE);646 #endif647 return VINF_SUCCESS;648 }649 650 #endif /* later */651 652 62 653 63
Note:
See TracChangeset
for help on using the changeset viewer.