Changeset 201 in vbox for trunk/src/VBox/Runtime/r0drv
- Timestamp:
- Jan 20, 2007 4:09:16 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/darwin/semaphore-r0drv-darwin.cpp
r199 r201 36 36 * Structures and Typedefs * 37 37 *******************************************************************************/ 38 #if 0 /** @todo */39 38 /** 40 39 * Darwin event semaphore. … … 44 43 /** Magic value (RTSEMEVENT_MAGIC). */ 45 44 uint32_t volatile u32Magic; 46 /** The NT Event object. */ 47 KEVENT Event; 45 /** The number of waiting threads. */ 46 uint32_t volatile cWaiters; 47 /** Set if the event object is signaled. */ 48 uint8_t volatile fSignaled; 49 /** The number of threads in the process of waking up. */ 50 uint32_t volatile cWaking; 51 /** The spinlock protecting us. */ 52 lck_spin_t *pSpinlock; 48 53 } RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL; 49 54 50 55 /** Magic for the Darwin event semaphore structure. (Neil Gaiman) */ 51 56 #define RTSEMEVENT_MAGIC 0x19601110 52 #endif53 57 54 58 #if 0 /** @todo */ … … 84 88 85 89 86 #if 0/** @todo */87 90 RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem) 88 91 { 89 92 Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *)); 93 AssertPtrReturn(VALID_PTR(pEventSem), VERR_INVALID_POINTER); 94 90 95 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt)); 91 96 if (pEventInt) 92 97 { 93 98 pEventInt->u32Magic = RTSEMEVENT_MAGIC; 94 wait_queue_init 95 KeInitializeEvent(&pEventInt->Event, SynchronizationEvent, FALSE); 96 *pEventSem = pEventInt; 97 return VINF_SUCCESS; 99 pEventInt->cWaiters = 0; 100 pEventInt->cWaking = 0; 101 pEventInt->fSignaled = 0; 102 Assert(g_pDarwinLockGroup); 103 pEventInt->pSpinlock = lck_spin_alloc_init(g_pDarwinLockGroup, LCK_ATTR_NULL); 104 if (pEventInt->pSpinlock) 105 { 106 *pEventSem = pEventInt; 107 return VINF_SUCCESS; 108 } 109 110 pEventInt->u32Magic = 0; 111 RTMemFree(pEventInt); 98 112 } 99 113 return VERR_NO_MEMORY; … … 103 117 RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem) 104 118 { 105 /* 106 * Validate input. 107 */ 119 if (EventSem == NIL_RTSEMEVENT) /* don't bitch */ 120 return VERR_INVALID_HANDLE; 108 121 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 109 if (!pEventInt) 110 return VERR_INVALID_PARAMETER; 111 if (pEventInt->u32Magic != RTSEMEVENT_MAGIC) 112 { 113 AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt->u32Magic, pEventInt)); 114 return VERR_INVALID_PARAMETER; 115 } 116 117 /* 118 * Invalidate it and signal the object just in case. 119 */ 120 ASMAtomicIncU32(&pEventInt->u32Magic); 121 KeSetEvent(&pEventInt->Event, 0xfff, FALSE); 122 RTMemFree(pEventInt); 122 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 123 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 124 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 125 VERR_INVALID_HANDLE); 126 127 lck_spin_lock(pEventInt->pSpinlock); 128 ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */ 129 if (pEventInt->cWaiters > 0) 130 { 131 /* abort waiting thread, last man cleans up. */ 132 ASMAtomicXchgU32(&pEventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters); 133 thread_wakeup_prim((event_t)pEventInt, FALSE /* all threads */, THREAD_RESTART); 134 lck_spin_unlock(pEventInt->pSpinlock); 135 } 136 else if (pEventInt->cWaking) 137 /* the last waking thread is gonna do the cleanup */ 138 lck_spin_unlock(pEventInt->pSpinlock); 139 else 140 { 141 lck_spin_unlock(pEventInt->pSpinlock); 142 lck_spin_destroy(pEventInt->pSpinlock, g_pDarwinLockGroup); 143 RTMemFree(pEventInt); 144 } 145 123 146 return VINF_SUCCESS; 124 147 } … … 127 150 RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem) 128 151 { 129 /*130 * Validate input.131 */132 152 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 133 if (!pEventInt) 134 return VERR_INVALID_PARAMETER; 135 if ( !pEventInt 136 || pEventInt->u32Magic != RTSEMEVENT_MAGIC) 137 { 138 AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt)); 139 return VERR_INVALID_PARAMETER; 140 } 141 142 /* 143 * Signal the event object. 144 */ 145 KeSetEvent(&pEventInt->Event, 1, FALSE); 146 return VINF_SUCCESS; 153 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 154 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 155 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 156 VERR_INVALID_HANDLE); 157 158 lck_spin_lock(pEventInt->pSpinlock); 159 160 if (pEventInt->cWaiters > 0) 161 { 162 ASMAtomicDecU32(&pEventInt->cWaiters); 163 ASMAtomicIncU32(&pEventInt->cWaking); 164 thread_wakeup_prim((event_t)pEventInt, TRUE /* one thread */, THREAD_AWAKENED); 165 } 166 else 167 ASMAtomicXchgU8(&pEventInt->fSignaled, true); 168 169 lck_spin_unlock(pEventInt->pSpinlock); 170 return VINF_SUCCESS; 171 } 172 173 174 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, wait_interrupt_t fInterruptible) 175 { 176 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 177 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 178 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 179 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 180 VERR_INVALID_HANDLE); 181 182 lck_spin_lock(pEventInt->pSpinlock); 183 184 int rc; 185 if (pEventInt->fSignaled) 186 { 187 Assert(!pEventInt->cWaiters); 188 ASMAtomicXchgU8(&pEventInt->fSignaled, false); 189 rc = 0; 190 } 191 else 192 { 193 ASMAtomicIncU32(&pEventInt->cWaiters); 194 195 wait_result_t rcWait; 196 if (cMillies == RT_INDEFINITE_WAIT) 197 rcWait = lck_spin_sleep(pEventInt->pSpinlock, LCK_SLEEP_DEFAULT, (event_t)pEventInt, fInterruptible); 198 else 199 { 200 uint64_t u64AbsTime; 201 nanoseconds_to_absolutetime(cMillies * UINT64_C(1000000), &u64AbsTime); 202 u64AbsTime += mach_absolute_time(); 203 204 rcWait = lck_spin_sleep_deadline(pEventInt->pSpinlock, LCK_SLEEP_DEFAULT, 205 (event_t)pEventInt, fInterruptible, u64AbsTime); 206 } 207 switch (rcWait) 208 { 209 case THREAD_AWAKENED: 210 Assert(pEventInt->cWaking > 0); 211 if ( !ASMAtomicDecU32(&pEventInt->cWaking) 212 && pEventInt->u32Magic != RTSEMEVENT_MAGIC) 213 { 214 /* the event was destroyed after we woke up, as the last thread do the cleanup. */ 215 lck_spin_unlock(pEventInt->pSpinlock); 216 Assert(g_pDarwinLockGroup); 217 lck_spin_destroy(pEventInt->pSpinlock, g_pDarwinLockGroup); 218 RTMemFree(pEventInt); 219 return VINF_SUCCESS; 220 } 221 rc = VINF_SUCCESS; 222 break; 223 224 case THREAD_TIMED_OUT: 225 Assert(cMillies != RT_INDEFINITE_WAIT); 226 ASMAtomicDecU32(&pEventInt->cWaiters); 227 rc = VERR_TIMEOUT; 228 break; 229 230 case THREAD_INTERRUPTED: 231 Assert(fInterruptible); 232 ASMAtomicDecU32(&pEventInt->cWaiters); 233 rc = VERR_INTERRUPTED; 234 break; 235 236 case THREAD_RESTART: 237 /* Last one out does the cleanup. */ 238 if (!ASMAtomicDecU32(&pEventInt->cWaking)) 239 { 240 lck_spin_unlock(pEventInt->pSpinlock); 241 Assert(g_pDarwinLockGroup); 242 lck_spin_destroy(pEventInt->pSpinlock, g_pDarwinLockGroup); 243 RTMemFree(pEventInt); 244 return VERR_SEM_DESTROYED; 245 } 246 247 rc = VERR_SEM_DESTROYED; 248 break; 249 250 default: 251 AssertMsgFailed(("rcWait=%d\n", rcWait)); 252 rc = VERR_GENERAL_FAILURE; 253 break; 254 } 255 } 256 257 lck_spin_unlock(pEventInt->pSpinlock); 258 return rc; 147 259 } 148 260 … … 150 262 RTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies) 151 263 { 152 /* 153 * Validate input. 154 */ 155 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 156 if (!pEventInt) 157 return VERR_INVALID_PARAMETER; 158 if ( !pEventInt 159 || pEventInt->u32Magic != RTSEMEVENT_MAGIC) 160 { 161 AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt)); 162 return VERR_INVALID_PARAMETER; 163 } 164 165 /* 166 * Wait for it. 167 */ 168 NTSTATUS rcNt; 169 if (cMillies == RT_INDEFINITE_WAIT) 170 rcNt = KeWaitForSingleObject(&pEventInt->Event, Executive, KernelMode, TRUE, NULL); 171 else 172 { 173 LARGE_INTEGER Timeout; 174 Timeout.QuadPart = -(int64_t)cMillies * 10000; 175 rcNt = KeWaitForSingleObject(&pEventInt->Event, Executive, KernelMode, TRUE, &Timeout); 176 } 177 switch (rcNt) 178 { 179 case STATUS_SUCCESS: 180 if (pEventInt->u32Magic == RTSEMEVENT_MAGIC) 181 return VINF_SUCCESS; 182 return VERR_SEM_DESTROYED; 183 case STATUS_ALERTED: 184 return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */ 185 case STATUS_USER_APC: 186 return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */ 187 case STATUS_TIMEOUT: 188 return VERR_TIMEOUT; 189 default: 190 AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p: wait returned %lx!\n", 191 pEventInt->u32Magic, pEventInt, (long)rcNt)); 192 return VERR_INTERNAL_ERROR; 193 } 194 } 195 #endif /* todo */ 264 return rtSemEventWait(EventSem, cMillies, FALSE /* not interruptable */); 265 } 266 267 268 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies) 269 { 270 return rtSemEventWait(EventSem, cMillies, TRUE /* interruptable */); 271 } 272 196 273 197 274 … … 354 431 return VERR_INVALID_PARAMETER; 355 432 PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem; 356 AssertPtrReturn( VALID_PTR(pFastInt), VERR_INVALID_POINTER);433 AssertPtrReturn(pFastInt, VERR_INVALID_PARAMETER); 357 434 AssertMsgReturn(pFastInt->u32Magic == RTSEMFASTMUTEX_MAGIC, 358 435 ("pFastInt->u32Magic=%RX32 pFastInt=%p\n", pFastInt->u32Magic, pFastInt), … … 372 449 { 373 450 PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem; 374 AssertMsgReturn(VALID_PTR(pFastInt) && pFastInt->u32Magic == RTSEMFASTMUTEX_MAGIC, 375 ("pFastInt->u32Magic=%RX32 pFastInt=%p\n", VALID_PTR(pFastInt) ? pFastInt->u32Magic : 0, pFastInt), 451 AssertPtrReturn(pFastInt, VERR_INVALID_PARAMETER); 452 AssertMsgReturn(pFastInt->u32Magic == RTSEMFASTMUTEX_MAGIC, 453 ("pFastInt->u32Magic=%RX32 pFastInt=%p\n", pFastInt->u32Magic, pFastInt), 376 454 VERR_INVALID_PARAMETER); 377 455 lck_mtx_lock(pFastInt->pMtx); … … 383 461 { 384 462 PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem; 385 AssertMsgReturn(VALID_PTR(pFastInt) && pFastInt->u32Magic == RTSEMFASTMUTEX_MAGIC, 386 ("pFastInt->u32Magic=%RX32 pFastInt=%p\n", VALID_PTR(pFastInt) ? pFastInt->u32Magic : 0, pFastInt), 463 AssertPtrReturn(pFastInt, VERR_INVALID_PARAMETER); 464 AssertMsgReturn(pFastInt->u32Magic == RTSEMFASTMUTEX_MAGIC, 465 ("pFastInt->u32Magic=%RX32 pFastInt=%p\n", pFastInt->u32Magic, pFastInt), 387 466 VERR_INVALID_PARAMETER); 388 467 lck_mtx_unlock(pFastInt->pMtx);
Note:
See TracChangeset
for help on using the changeset viewer.