Changeset 22582 in vbox
- Timestamp:
- Aug 30, 2009 8:47:57 PM (15 years ago)
- Location:
- trunk/src/VBox/Runtime/r0drv/freebsd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/freebsd/semevent-r0drv-freebsd.c
r20448 r22582 39 39 #include <iprt/assert.h> 40 40 #include <iprt/err.h> 41 #include <iprt/spinlock.h> 41 42 42 43 #include "internal/magics.h" … … 59 60 /** The number of threads in the process of waking up. */ 60 61 uint32_t volatile cWaking; 61 /** The FreeBSD spinlock protecting this structure. */62 struct mtx Mtx;62 /** Spinlock protecting this structure. */ 63 RTSPINLOCK hSpinLock; 63 64 } RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL; 64 65 … … 76 77 pEventInt->cWaking = 0; 77 78 pEventInt->fSignaled = 0; 78 mtx_init(&pEventInt->Mtx, "IPRT Event Semaphore", NULL, 0); 79 *pEventSem = pEventInt; 80 return VINF_SUCCESS; 79 int rc = RTSpinlockCreate(&pEventInt->hSpinLock); 80 if (RT_SUCCESS(rc)) 81 { 82 *pEventSem = pEventInt; 83 return VINF_SUCCESS; 84 } 85 86 RTMemFree(pEventInt); 87 return rc; 81 88 } 82 89 return VERR_NO_MEMORY; … … 88 95 if (EventSem == NIL_RTSEMEVENT) /* don't bitch */ 89 96 return VERR_INVALID_HANDLE; 97 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 98 RTSPINLOCKTMP Tmp; 99 100 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 101 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 102 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 103 VERR_INVALID_HANDLE); 104 105 RTSpinlockAcquire(pEventInt->hSpinLock, &Tmp); 106 107 ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */ 108 if (pEventInt->cWaiters > 0) 109 { 110 /* abort waiting thread, last man cleans up. */ 111 ASMAtomicXchgU32(&pEventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters); 112 sleepq_lock(pEventInt); 113 sleepq_broadcast(pEventInt, SLEEPQ_CONDVAR, 0, 0); 114 sleepq_release(pEventInt); 115 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 116 } 117 else if (pEventInt->cWaking) 118 /* the last waking thread is gonna do the cleanup */ 119 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 120 else 121 { 122 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 123 RTSpinlockDestroy(pEventInt->hSpinLock); 124 RTMemFree(pEventInt); 125 } 126 127 return VINF_SUCCESS; 128 } 129 130 131 RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem) 132 { 133 RTSPINLOCKTMP Tmp; 90 134 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 91 135 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); … … 94 138 VERR_INVALID_HANDLE); 95 139 96 mtx_lock(&pEventInt->Mtx);97 ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */ 140 RTSpinlockAcquire(pEventInt->hSpinLock, &Tmp); 141 98 142 if (pEventInt->cWaiters > 0) 99 143 { 100 /* abort waiting thread, last man cleans up. */101 ASMAtomic XchgU32(&pEventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters);102 wakeup(pEventInt);103 mtx_unlock(&pEventInt->Mtx);104 }105 else if (pEventInt->cWaking)106 /* the last waking thread is gonna do the cleanup */107 mtx_unlock(&pEventInt->Mtx);144 ASMAtomicDecU32(&pEventInt->cWaiters); 145 ASMAtomicIncU32(&pEventInt->cWaking); 146 sleepq_lock(pEventInt); 147 int fWakeupSwapProc = sleepq_signal(pEventInt, SLEEPQ_CONDVAR, 0, 0); 148 sleepq_release(pEventInt); 149 if (fWakeupSwapProc) 150 kick_proc0(); 151 } 108 152 else 109 { 110 mtx_unlock(&pEventInt->Mtx); 111 mtx_destroy(&pEventInt->Mtx); 112 RTMemFree(pEventInt); 113 } 114 153 ASMAtomicXchgU8(&pEventInt->fSignaled, true); 154 155 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 115 156 return VINF_SUCCESS; 116 157 } 117 158 118 159 119 RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem) 120 { 160 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fInterruptible) 161 { 162 int rc; 163 RTSPINLOCKTMP Tmp; 121 164 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 122 165 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); … … 125 168 VERR_INVALID_HANDLE); 126 169 127 mtx_lock(&pEventInt->Mtx); 128 129 if (pEventInt->cWaiters > 0) 130 { 131 ASMAtomicDecU32(&pEventInt->cWaiters); 132 ASMAtomicIncU32(&pEventInt->cWaking); 133 wakeup_one(pEventInt); 134 } 135 else 136 ASMAtomicXchgU8(&pEventInt->fSignaled, true); 137 138 mtx_unlock(&pEventInt->Mtx); 139 return VINF_SUCCESS; 140 } 141 142 143 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fInterruptible) 144 { 145 int rc; 146 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 147 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 148 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 149 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 150 VERR_INVALID_HANDLE); 151 152 mtx_lock(&pEventInt->Mtx); 170 RTSpinlockAcquire(pEventInt->hSpinLock, &Tmp); 153 171 154 172 if (pEventInt->fSignaled) … … 160 178 else 161 179 { 162 /* 163 * Translate milliseconds into ticks and go to sleep. 164 */ 165 struct timeval tv; 166 167 if (cMillies != RT_INDEFINITE_WAIT) 180 if (cMillies == 0) 181 rc = VERR_TIMEOUT; 182 else 168 183 { 169 tv.tv_sec = cMillies / 1000; 170 tv.tv_usec = (cMillies % 1000) * 1000; 171 } 172 173 ASMAtomicIncU32(&pEventInt->cWaiters); 174 175 /** @todo r=bird: This doesn't handle cMillies == 0 correctly, it will assert 176 * and or sleep for ever according to r47861. (That's probably an old bug 177 * of my making.) 178 */ 179 rc = mtx_sleep(pEventInt, /* block id */ 180 &pEventInt->Mtx, /* mtx */ 181 fInterruptible ? PZERO | PCATCH : PZERO, 182 "iprtev", /* max 6 chars */ 183 cMillies == RT_INDEFINITE_WAIT 184 ? 0 185 : tvtohz(&tv)); 186 187 switch (rc) 188 { 189 case 0: 190 if (pEventInt->u32Magic == RTSEMEVENT_MAGIC) 191 { 192 ASMAtomicDecU32(&pEventInt->cWaking); 193 rc = VINF_SUCCESS; 194 } 184 ASMAtomicIncU32(&pEventInt->cWaiters); 185 186 int fFlags = SLEEPQ_CONDVAR; 187 188 if (fInterruptible) 189 fFlags |= SLEEPQ_INTERRUPTIBLE; 190 191 sleepq_lock(pEventInt); 192 sleepq_add(pEventInt, NULL, "IPRT Event Semaphore", fFlags, 0); 193 194 if (cMillies != RT_INDEFINITE_WAIT) 195 { 196 /* 197 * Translate milliseconds into ticks and go to sleep. 198 */ 199 struct timeval tv; 200 201 tv.tv_sec = cMillies / 1000; 202 tv.tv_usec = (cMillies % 1000) * 1000; 203 204 sleepq_set_timeout(pEventInt, tvtohz(&tv)); 205 206 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 207 208 if (fInterruptible) 209 rc = sleepq_timedwait_sig(pEventInt, 0); 210 else 211 rc = sleepq_timedwait(pEventInt, 0); 212 } 213 else 214 { 215 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 216 217 if (fInterruptible) 218 rc = sleepq_wait_sig(pEventInt, 0); 195 219 else 196 220 { 197 rc = VERR_SEM_DESTROYED; /** @todo this isn't necessarily correct, we've 198 * could've woken up just before destruction... */ 199 if (!ASMAtomicDecU32(&pEventInt->cWaking)) 221 rc = 0; 222 sleepq_wait(pEventInt, 0); 223 } 224 } 225 226 RTSpinlockAcquire(pEventInt->hSpinLock, &Tmp); 227 228 switch (rc) 229 { 230 case 0: 231 if (pEventInt->u32Magic == RTSEMEVENT_MAGIC) 200 232 { 201 /* The event was destroyed, as the last thread do the cleanup. 202 we don't actually know whether */ 203 mtx_unlock(&pEventInt->Mtx); 204 mtx_destroy(&pEventInt->Mtx); 205 RTMemFree(pEventInt); 206 return rc; 233 ASMAtomicDecU32(&pEventInt->cWaking); 234 rc = VINF_SUCCESS; 207 235 } 208 } 209 break; 210 211 case EWOULDBLOCK: 212 Assert(cMillies != RT_INDEFINITE_WAIT); 213 if (pEventInt->cWaiters > 0) 214 ASMAtomicDecU32(&pEventInt->cWaiters); 215 rc = VERR_TIMEOUT; 216 break; 217 218 case EINTR: 219 case ERESTART: 220 Assert(fInterruptible); 221 if (pEventInt->cWaiters > 0) 222 ASMAtomicDecU32(&pEventInt->cWaiters); 223 rc = VERR_INTERRUPTED; 224 break; 225 226 default: 227 AssertMsgFailed(("tsleep -> %d\n", rc)); 228 rc = VERR_GENERAL_FAILURE; 229 break; 236 else 237 { 238 rc = VERR_SEM_DESTROYED; /** @todo this isn't necessarily correct, we've 239 * could've woken up just before destruction... */ 240 if (!ASMAtomicDecU32(&pEventInt->cWaking)) 241 { 242 /* The event was destroyed, as the last thread do the cleanup. 243 we don't actually know whether */ 244 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 245 RTSpinlockDestroy(pEventInt->hSpinLock); 246 RTMemFree(pEventInt); 247 return rc; 248 } 249 } 250 break; 251 252 case EWOULDBLOCK: 253 Assert(cMillies != RT_INDEFINITE_WAIT); 254 if (pEventInt->cWaiters > 0) 255 ASMAtomicDecU32(&pEventInt->cWaiters); 256 rc = VERR_TIMEOUT; 257 break; 258 259 case EINTR: 260 case ERESTART: 261 Assert(fInterruptible); 262 if (pEventInt->cWaiters > 0) 263 ASMAtomicDecU32(&pEventInt->cWaiters); 264 rc = VERR_INTERRUPTED; 265 break; 266 267 default: 268 AssertMsgFailed(("sleepq_* -> %d\n", rc)); 269 rc = VERR_GENERAL_FAILURE; 270 break; 271 } 230 272 } 231 273 } 232 274 233 mtx_unlock(&pEventInt->Mtx); 275 RTSpinlockRelease(pEventInt->hSpinLock, &Tmp); 276 234 277 return rc; 235 278 } -
trunk/src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c
r19565 r22582 39 39 #include <iprt/assert.h> 40 40 #include <iprt/err.h> 41 #include <iprt/spinlock.h> 41 42 42 43 #include "internal/magics.h" … … 59 60 /** The number of threads in the process of waking up. */ 60 61 uint32_t volatile cWaking; 61 /** The FreeBSD spinlock protecting this structure. */62 struct mtx Mtx;62 /** Spinlock protecting this structure. */ 63 RTSPINLOCK hSpinLock; 63 64 } RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL; 64 65 … … 76 77 pEventMultiInt->cWaking = 0; 77 78 pEventMultiInt->fSignaled = 0; 78 mtx_init(&pEventMultiInt->Mtx, "IPRT Multiple Release Event Semaphore", NULL, MTX_SPIN); 79 *pEventMultiSem = pEventMultiInt; 80 return VINF_SUCCESS; 79 int rc = RTSpinlockCreate(&pEventMultiInt->hSpinLock); 80 if (RT_SUCCESS(rc)) 81 { 82 *pEventMultiSem = pEventMultiInt; 83 return VINF_SUCCESS; 84 } 85 86 RTMemFree(pEventMultiInt); 87 return rc; 81 88 } 82 89 return VERR_NO_MEMORY; … … 88 95 if (EventMultiSem == NIL_RTSEMEVENTMULTI) /* don't bitch */ 89 96 return VERR_INVALID_HANDLE; 97 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 98 RTSPINLOCKTMP Tmp; 99 100 AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE); 101 AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC, 102 ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic), 103 VERR_INVALID_HANDLE); 104 105 RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp); 106 ASMAtomicIncU32(&pEventMultiInt->u32Magic); /* make the handle invalid */ 107 if (pEventMultiInt->cWaiters > 0) 108 { 109 /* abort waiting thread, last man cleans up. */ 110 ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters); 111 sleepq_lock(pEventMultiInt); 112 sleepq_broadcast(pEventMultiInt, SLEEPQ_CONDVAR, 0, 0); 113 sleepq_release(pEventMultiInt); 114 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 115 } 116 else if (pEventMultiInt->cWaking) 117 /* the last waking thread is gonna do the cleanup */ 118 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 119 else 120 { 121 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 122 RTSpinlockDestroy(pEventMultiInt->hSpinLock); 123 RTMemFree(pEventMultiInt); 124 } 125 126 return VINF_SUCCESS; 127 } 128 129 130 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem) 131 { 132 RTSPINLOCKTMP Tmp; 90 133 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 91 134 AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE); … … 94 137 VERR_INVALID_HANDLE); 95 138 96 mtx_lock_spin(&pEventMultiInt->Mtx); 97 ASMAtomicIncU32(&pEventMultiInt->u32Magic); /* make the handle invalid */ 139 RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp); 140 141 ASMAtomicXchgU8(&pEventMultiInt->fSignaled, true); 98 142 if (pEventMultiInt->cWaiters > 0) 99 143 { 100 /* abort waiting thread, last man cleans up. */101 144 ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters); 102 wakeup(pEventMultiInt); 103 mtx_unlock_spin(&pEventMultiInt->Mtx); 104 } 105 else if (pEventMultiInt->cWaking) 106 /* the last waking thread is gonna do the cleanup */ 107 mtx_unlock_spin(&pEventMultiInt->Mtx); 108 else 109 { 110 mtx_unlock_spin(&pEventMultiInt->Mtx); 111 mtx_destroy(&pEventMultiInt->Mtx); 112 RTMemFree(pEventMultiInt); 113 } 114 145 ASMAtomicXchgU32(&pEventMultiInt->cWaiters, 0); 146 sleepq_lock(pEventMultiInt); 147 int fWakeupSwapProc = sleepq_signal(pEventMultiInt, SLEEPQ_CONDVAR, 0, 0); 148 sleepq_release(pEventMultiInt); 149 if (fWakeupSwapProc) 150 kick_proc0(); 151 } 152 153 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 115 154 return VINF_SUCCESS; 116 155 } 117 156 118 157 119 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem) 120 { 158 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem) 159 { 160 RTSPINLOCKTMP Tmp; 121 161 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 122 162 AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE); … … 125 165 VERR_INVALID_HANDLE); 126 166 127 mtx_lock_spin(&pEventMultiInt->Mtx); 128 129 ASMAtomicXchgU8(&pEventMultiInt->fSignaled, true); 130 if (pEventMultiInt->cWaiters > 0) 131 { 132 ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters); 133 ASMAtomicXchgU32(&pEventMultiInt->cWaiters, 0); 134 wakeup(pEventMultiInt); 135 } 136 137 mtx_unlock_spin(&pEventMultiInt->Mtx); 167 RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp); 168 ASMAtomicXchgU8(&pEventMultiInt->fSignaled, false); 169 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 138 170 return VINF_SUCCESS; 139 171 } 140 172 141 173 142 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem) 143 { 174 static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, bool fInterruptible) 175 { 176 int rc; 177 RTSPINLOCKTMP Tmp; 144 178 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 145 179 AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE); … … 148 182 VERR_INVALID_HANDLE); 149 183 150 mtx_lock_spin(&pEventMultiInt->Mtx); 151 ASMAtomicXchgU8(&pEventMultiInt->fSignaled, false); 152 mtx_unlock_spin(&pEventMultiInt->Mtx); 153 return VINF_SUCCESS; 154 } 155 156 157 static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, bool fInterruptible) 158 { 159 int rc; 160 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 161 AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE); 162 AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC, 163 ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic), 164 VERR_INVALID_HANDLE); 165 166 mtx_lock_spin(&pEventMultiInt->Mtx); 184 RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp); 167 185 168 186 if (pEventMultiInt->fSignaled) … … 170 188 else 171 189 { 172 /* 173 * Translate milliseconds into ticks and go to sleep. 174 */ 175 int cTicks; 176 if (cMillies != RT_INDEFINITE_WAIT) 190 if (cMillies == 0) 191 rc = VERR_TIMEOUT; 192 else 177 193 { 178 if (hz == 1000) 179 cTicks = cMillies; 180 else if (hz == 100) 181 cTicks = cMillies / 10; 194 ASMAtomicIncU32(&pEventMultiInt->cWaiters); 195 196 int fFlags = SLEEPQ_CONDVAR; 197 198 if (fInterruptible) 199 fFlags |= SLEEPQ_INTERRUPTIBLE; 200 201 sleepq_lock(pEventMultiInt); 202 sleepq_add(pEventMultiInt, NULL, "IPRT Event Semaphore", fFlags, 0); 203 204 if (cMillies != RT_INDEFINITE_WAIT) 205 { 206 /* 207 * Translate milliseconds into ticks and go to sleep. 208 */ 209 struct timeval tv; 210 211 tv.tv_sec = cMillies / 1000; 212 tv.tv_usec = (cMillies % 1000) * 1000; 213 214 sleepq_set_timeout(pEventMultiInt, tvtohz(&tv)); 215 216 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 217 218 if (fInterruptible) 219 rc = sleepq_timedwait_sig(pEventMultiInt, 0); 220 else 221 rc = sleepq_timedwait(pEventMultiInt, 0); 222 } 182 223 else 183 224 { 184 int64_t cTicks64 = ((uint64_t)cMillies * hz) / 1000; 185 cTicks = (int)cTicks64; 186 if (cTicks != cTicks64) 187 cTicks = INT_MAX; 225 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 226 227 if (fInterruptible) 228 rc = sleepq_wait_sig(pEventMultiInt, 0); 229 else 230 { 231 rc = 0; 232 sleepq_wait(pEventMultiInt, 0); 233 } 234 } 235 236 RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp); 237 238 switch (rc) 239 { 240 case 0: 241 if (pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC) 242 { 243 ASMAtomicDecU32(&pEventMultiInt->cWaking); 244 rc = VINF_SUCCESS; 245 } 246 else 247 { 248 rc = VERR_SEM_DESTROYED; /** @todo this isn't necessarily correct, we've 249 * could've woken up just before destruction... */ 250 if (!ASMAtomicDecU32(&pEventMultiInt->cWaking)) 251 { 252 /* The event was destroyed, as the last thread do the cleanup. 253 we don't actually know whether */ 254 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 255 RTSpinlockDestroy(pEventMultiInt->hSpinLock); 256 RTMemFree(pEventMultiInt); 257 return rc; 258 } 259 } 260 break; 261 262 case EWOULDBLOCK: 263 Assert(cMillies != RT_INDEFINITE_WAIT); 264 if (pEventMultiInt->cWaiters > 0) 265 ASMAtomicDecU32(&pEventMultiInt->cWaiters); 266 rc = VERR_TIMEOUT; 267 break; 268 269 case EINTR: 270 case ERESTART: 271 Assert(fInterruptible); 272 if (pEventMultiInt->cWaiters > 0) 273 ASMAtomicDecU32(&pEventMultiInt->cWaiters); 274 rc = VERR_INTERRUPTED; 275 break; 276 277 default: 278 AssertMsgFailed(("sleepq_* -> %d\n", rc)); 279 rc = VERR_GENERAL_FAILURE; 280 break; 188 281 } 189 282 } 190 else 191 cTicks = 0; 192 193 ASMAtomicIncU32(&pEventMultiInt->cWaiters); 194 195 rc = msleep_spin(pEventMultiInt, /* block id */ 196 &pEventMultiInt->Mtx, 197 //fInterruptible ? PZERO | PCATCH : PZERO, 198 "iprte", /* max 6 chars */ 199 cTicks); 200 switch (rc) 201 { 202 case 0: 203 if (pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC) 204 { 205 ASMAtomicDecU32(&pEventMultiInt->cWaking); 206 rc = VINF_SUCCESS; 207 } 208 else 209 { 210 rc = VERR_SEM_DESTROYED; /** @todo this isn't necessarily correct, we've 211 * could've woken up just before destruction... */ 212 if (!ASMAtomicDecU32(&pEventMultiInt->cWaking)) 213 { 214 /* The event was destroyed, as the last thread do the cleanup. 215 we don't actually know whether */ 216 mtx_unlock_spin(&pEventMultiInt->Mtx); 217 mtx_destroy(&pEventMultiInt->Mtx); 218 RTMemFree(pEventMultiInt); 219 return rc; 220 } 221 } 222 break; 223 224 case EWOULDBLOCK: 225 Assert(cMillies != RT_INDEFINITE_WAIT); 226 if (pEventMultiInt->cWaiters > 0) 227 ASMAtomicDecU32(&pEventMultiInt->cWaiters); 228 rc = VERR_TIMEOUT; 229 break; 230 231 case EINTR: 232 case ERESTART: 233 Assert(fInterruptible); 234 if (pEventMultiInt->cWaiters > 0) 235 ASMAtomicDecU32(&pEventMultiInt->cWaiters); 236 rc = VERR_INTERRUPTED; 237 break; 238 239 default: 240 AssertMsgFailed(("msleep -> %d\n", rc)); 241 rc = VERR_GENERAL_FAILURE; 242 break; 243 } 244 } 245 246 mtx_unlock_spin(&pEventMultiInt->Mtx); 283 } 284 285 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 247 286 return rc; 248 287 }
Note:
See TracChangeset
for help on using the changeset viewer.