Changeset 25720 in vbox for trunk/src/VBox/Runtime/r0drv/freebsd
- Timestamp:
- Jan 11, 2010 1:57:09 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56460
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c
r22819 r25720 64 64 65 65 66 RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem) 67 { 68 Assert(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *)); 69 AssertPtrReturn(pEventMultiSem, VERR_INVALID_POINTER); 70 71 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)RTMemAllocZ(sizeof(*pEventMultiInt)); 72 if (pEventMultiInt) 73 { 74 pEventMultiInt->u32Magic = RTSEMEVENTMULTI_MAGIC; 75 pEventMultiInt->cWaiters = 0; 76 pEventMultiInt->cWaking = 0; 77 pEventMultiInt->fSignaled = 0; 78 int rc = RTSpinlockCreate(&pEventMultiInt->hSpinLock); 66 RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem) 67 { 68 return RTSemEventMultiCreateEx(phEventMultiSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL); 69 } 70 71 72 RTDECL(int) RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass, 73 const char *pszNameFmt, ...) 74 { 75 AssertCompile(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *)); 76 AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER); 77 AssertPtrReturn(phEventMultiSem, VERR_INVALID_POINTER); 78 79 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAllocZ(sizeof(*pThis)); 80 if (pThis) 81 { 82 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC; 83 pThis->cWaiters = 0; 84 pThis->cWaking = 0; 85 pThis->fSignaled = 0; 86 int rc = RTSpinlockCreate(&pThis->hSpinLock); 79 87 if (RT_SUCCESS(rc)) 80 88 { 81 *p EventMultiSem = pEventMultiInt;89 *phEventMultiSem = pThis; 82 90 return VINF_SUCCESS; 83 91 } 84 92 85 RTMemFree(p EventMultiInt);93 RTMemFree(pThis); 86 94 return rc; 87 95 } … … 90 98 91 99 92 RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem) 93 { 94 if (EventMultiSem == NIL_RTSEMEVENTMULTI) /* don't bitch */ 95 return VERR_INVALID_HANDLE; 96 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 100 RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem) 101 { 102 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem; 97 103 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 98 104 99 AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE); 100 AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC, 101 ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic), 105 if (pThis == NIL_RTSEMEVENTMULTI) 106 return VINF_SUCCESS; 107 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 108 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE); 109 110 RTSpinlockAcquire(pThis->hSpinLock, &Tmp); 111 ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */ 112 if (pThis->cWaiters > 0) 113 { 114 /* abort waiting thread, last man cleans up. */ 115 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters); 116 sleepq_lock(pThis); 117 sleepq_broadcast(pThis, SLEEPQ_CONDVAR, 0, 0); 118 sleepq_release(pThis); 119 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 120 } 121 else if (pThis->cWaking) 122 /* the last waking thread is gonna do the cleanup */ 123 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 124 else 125 { 126 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 127 RTSpinlockDestroy(pThis->hSpinLock); 128 RTMemFree(pThis); 129 } 130 131 return VINF_SUCCESS; 132 } 133 134 135 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem) 136 { 137 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 138 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem; 139 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 140 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, 141 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 102 142 VERR_INVALID_HANDLE); 103 143 104 RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp); 105 ASMAtomicIncU32(&pEventMultiInt->u32Magic); /* make the handle invalid */ 106 if (pEventMultiInt->cWaiters > 0) 107 { 108 /* abort waiting thread, last man cleans up. */ 109 ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters); 110 sleepq_lock(pEventMultiInt); 111 sleepq_broadcast(pEventMultiInt, SLEEPQ_CONDVAR, 0, 0); 112 sleepq_release(pEventMultiInt); 113 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 114 } 115 else if (pEventMultiInt->cWaking) 116 /* the last waking thread is gonna do the cleanup */ 117 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 118 else 119 { 120 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp); 121 RTSpinlockDestroy(pEventMultiInt->hSpinLock); 122 RTMemFree(pEventMultiInt); 123 } 124 125 return VINF_SUCCESS; 126 } 127 128 129 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem) 130 { 131 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 132 PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 133 AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE); 134 AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC, 135 ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic), 136 VERR_INVALID_HANDLE); 137 138 RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp); 139 140 ASMAtomicXchgU8(&pEventMultiInt->fSignaled, true); 141 if (pEventMultiInt->cWaiters > 0) 142 { 143 ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters); 144 ASMAtomicXchgU32(&pEventMultiInt->cWaiters, 0); 145 sleepq_lock(pEventMultiInt); 146 int fWakeupSwapProc = sleepq_signal(pEventMultiInt, SLEEPQ_CONDVAR, 0, 0); 147 sleepq_release(pEventMultiInt); 144 RTSpinlockAcquire(pThis->hSpinLock, &Tmp); 145 146 ASMAtomicXchgU8(&pThis->fSignaled, true); 147 if (pThis->cWaiters > 0) 148 { 149 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters); 150 ASMAtomicXchgU32(&pThis->cWaiters, 0); 151 sleepq_lock(pThis); 152 int fWakeupSwapProc = sleepq_signal(pThis, SLEEPQ_CONDVAR, 0, 0); 153 sleepq_release(pThis); 148 154 if (fWakeupSwapProc) 149 155 kick_proc0(); 150 156 } 151 157 152 RTSpinlockRelease(p EventMultiInt->hSpinLock, &Tmp);158 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 153 159 return VINF_SUCCESS; 154 160 } 155 161 156 162 157 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)163 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem) 158 164 { 159 165 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 160 PRTSEMEVENTMULTIINTERNAL p EventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;161 AssertPtrReturn(p EventMultiInt, VERR_INVALID_HANDLE);162 AssertMsgReturn(p EventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,163 ("p EventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),166 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem; 167 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 168 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, 169 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 164 170 VERR_INVALID_HANDLE); 165 171 166 RTSpinlockAcquire(p EventMultiInt->hSpinLock, &Tmp);167 ASMAtomicXchgU8(&p EventMultiInt->fSignaled, false);168 RTSpinlockRelease(p EventMultiInt->hSpinLock, &Tmp);172 RTSpinlockAcquire(pThis->hSpinLock, &Tmp); 173 ASMAtomicXchgU8(&pThis->fSignaled, false); 174 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 169 175 return VINF_SUCCESS; 170 176 } 171 177 172 178 173 static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, bool fInterruptible)179 static int rtSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, unsigned cMillies, bool fInterruptible) 174 180 { 175 181 int rc; 176 182 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 177 PRTSEMEVENTMULTIINTERNAL p EventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;178 AssertPtrReturn(p EventMultiInt, VERR_INVALID_HANDLE);179 AssertMsgReturn(p EventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,180 ("p EventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),183 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem; 184 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 185 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, 186 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 181 187 VERR_INVALID_HANDLE); 182 188 183 RTSpinlockAcquire(p EventMultiInt->hSpinLock, &Tmp);184 185 if (p EventMultiInt->fSignaled)189 RTSpinlockAcquire(pThis->hSpinLock, &Tmp); 190 191 if (pThis->fSignaled) 186 192 rc = VINF_SUCCESS; 187 193 else … … 191 197 else 192 198 { 193 ASMAtomicIncU32(&p EventMultiInt->cWaiters);199 ASMAtomicIncU32(&pThis->cWaiters); 194 200 195 201 int fFlags = SLEEPQ_CONDVAR; … … 198 204 fFlags |= SLEEPQ_INTERRUPTIBLE; 199 205 200 sleepq_lock(p EventMultiInt);201 sleepq_add(p EventMultiInt, NULL, "IPRT Event Semaphore", fFlags, 0);206 sleepq_lock(pThis); 207 sleepq_add(pThis, NULL, "IPRT Event Semaphore", fFlags, 0); 202 208 203 209 if (cMillies != RT_INDEFINITE_WAIT) … … 211 217 tv.tv_usec = (cMillies % 1000) * 1000; 212 218 213 sleepq_set_timeout(p EventMultiInt, tvtohz(&tv));214 215 RTSpinlockRelease(p EventMultiInt->hSpinLock, &Tmp);219 sleepq_set_timeout(pThis, tvtohz(&tv)); 220 221 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 216 222 217 223 if (fInterruptible) 218 rc = SLEEPQ_TIMEDWAIT_SIG(p EventMultiInt);224 rc = SLEEPQ_TIMEDWAIT_SIG(pThis); 219 225 else 220 rc = SLEEPQ_TIMEDWAIT(p EventMultiInt);226 rc = SLEEPQ_TIMEDWAIT(pThis); 221 227 } 222 228 else 223 229 { 224 RTSpinlockRelease(p EventMultiInt->hSpinLock, &Tmp);230 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 225 231 226 232 if (fInterruptible) 227 rc = SLEEPQ_WAIT_SIG(p EventMultiInt);233 rc = SLEEPQ_WAIT_SIG(pThis); 228 234 else 229 235 { 230 236 rc = 0; 231 SLEEPQ_WAIT(p EventMultiInt);237 SLEEPQ_WAIT(pThis); 232 238 } 233 239 } 234 240 235 RTSpinlockAcquire(p EventMultiInt->hSpinLock, &Tmp);241 RTSpinlockAcquire(pThis->hSpinLock, &Tmp); 236 242 237 243 switch (rc) 238 244 { 239 245 case 0: 240 if (p EventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC)246 if (pThis->u32Magic == RTSEMEVENTMULTI_MAGIC) 241 247 { 242 ASMAtomicDecU32(&p EventMultiInt->cWaking);248 ASMAtomicDecU32(&pThis->cWaking); 243 249 rc = VINF_SUCCESS; 244 250 } … … 247 253 rc = VERR_SEM_DESTROYED; /** @todo this isn't necessarily correct, we've 248 254 * could've woken up just before destruction... */ 249 if (!ASMAtomicDecU32(&p EventMultiInt->cWaking))255 if (!ASMAtomicDecU32(&pThis->cWaking)) 250 256 { 251 257 /* The event was destroyed, as the last thread do the cleanup. 252 258 we don't actually know whether */ 253 RTSpinlockRelease(p EventMultiInt->hSpinLock, &Tmp);254 RTSpinlockDestroy(p EventMultiInt->hSpinLock);255 RTMemFree(p EventMultiInt);259 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 260 RTSpinlockDestroy(pThis->hSpinLock); 261 RTMemFree(pThis); 256 262 return rc; 257 263 } … … 261 267 case EWOULDBLOCK: 262 268 Assert(cMillies != RT_INDEFINITE_WAIT); 263 if (p EventMultiInt->cWaiters > 0)264 ASMAtomicDecU32(&p EventMultiInt->cWaiters);269 if (pThis->cWaiters > 0) 270 ASMAtomicDecU32(&pThis->cWaiters); 265 271 rc = VERR_TIMEOUT; 266 272 break; … … 269 275 case ERESTART: 270 276 Assert(fInterruptible); 271 if (p EventMultiInt->cWaiters > 0)272 ASMAtomicDecU32(&p EventMultiInt->cWaiters);277 if (pThis->cWaiters > 0) 278 ASMAtomicDecU32(&pThis->cWaiters); 273 279 rc = VERR_INTERRUPTED; 274 280 break; … … 282 288 } 283 289 284 RTSpinlockRelease(p EventMultiInt->hSpinLock, &Tmp);290 RTSpinlockRelease(pThis->hSpinLock, &Tmp); 285 291 return rc; 286 292 } 287 293 288 294 289 RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)290 { 291 return rtSemEventMultiWait( EventMultiSem, cMillies, false /* not interruptible */);292 } 293 294 295 RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)296 { 297 return rtSemEventMultiWait( EventMultiSem, cMillies, true /* interruptible */);298 } 299 295 RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, unsigned cMillies) 296 { 297 return rtSemEventMultiWait(hEventMultiSem, cMillies, false /* not interruptible */); 298 } 299 300 301 RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, unsigned cMillies) 302 { 303 return rtSemEventMultiWait(hEventMultiSem, cMillies, true /* interruptible */); 304 } 305
Note:
See TracChangeset
for help on using the changeset viewer.