Changeset 823 in vbox
- Timestamp:
- Feb 10, 2007 8:00:14 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/linux/sems-linux.cpp
r822 r823 181 181 { 182 182 int32_t iCur = pIntEventSem->cWaiters; 183 if (iCur < 0)184 break; /* already signaled */185 183 if (iCur == 0) 186 184 { … … 188 186 break; /* nobody is waiting */ 189 187 } 190 else if (ASMAtomicCmpXchgS32(&pIntEventSem->cWaiters, iCur - 1, iCur)) 191 { 192 /* somebody is waiting, wake up one. */ 188 else if (iCur < 0) 189 break; /* already signaled */ 190 else 191 { 192 /* somebody is waiting, try wake up one of them. */ 193 193 long cWoken = sys_futex(&pIntEventSem->cWaiters, FUTEX_WAKE, 1, NULL, NULL, 0); 194 if (cWoken == 1) 194 if (RT_LIKELY(cWoken == 1)) 195 { 196 ASMAtomicDecS32(&pIntEventSem->cWaiters); 195 197 break; 196 ASMAtomicIncS32(&pIntEventSem->cWaiters);198 } 197 199 AssertMsg(cWoken == 0, ("%ld\n", cWoken)); 198 200 199 201 /* 200 * We're waiting for the threads to start executing, that's kind of 201 * silly really. But for now, take care that we don't prevent them 202 * from executing. 202 * This path is taken in two situations: 203 * 1) A waiting thread is returning from the sys_futex call with a 204 * non-zero return value. 205 * 2) There are two threads signaling the event at the 206 * same time and only one thread waiting. 207 * 208 * At this point we know that nobody is activly waiting on the event but 209 * at the same time, we are racing someone updating the state. The current 210 * strategy is to spin till the thread racing us is done, this is kind of 211 * brain dead and need fixing of course. 203 212 */ 204 if ((i % 128) == 127) 205 usleep(1000); 206 else if ((i % 16) == 15) 207 pthread_yield(); 208 else 209 Assert(i < 1024); 213 if (RT_UNLIKELY(i > 32)) 214 { 215 if ((i % 128) == 127) 216 usleep(1000); 217 else if (!(i % 4)) 218 pthread_yield(); 219 else 220 AssertReleaseMsg(i < 4096, ("iCur=%#x pIntEventSem=%p\n", iCur, pIntEventSem)); 221 } 210 222 } 211 223 } … … 260 272 if (RT_UNLIKELY(pIntEventSem->iMagic != RTSEMEVENT_MAGIC)) 261 273 return VERR_SEM_DESTROYED; 274 275 /* Did somebody wake us up us from RTSemEventSignal()? */ 262 276 if (rc == 0) 263 277 return VINF_SUCCESS; 264 278 265 /* don't count us among the waiters. */279 /* No, then the kernel woke us up or we failed going to sleep. Adjust the accounting. */ 266 280 iNew = ASMAtomicDecS32(&pIntEventSem->cWaiters); 267 281 Assert(iNew >= 0); … … 291 305 else 292 306 { 293 /* 294 * Somebody is signaling the semaphore, let's try again. 295 * But take care to yield and sleep after a while like always. 296 * (Could probably change this to string only and return right away...) 297 */ 298 ASMAtomicDecS32(&pIntEventSem->cWaiters); 299 if ((i % 128) == 127) 300 usleep(1000); 301 else if ((i % 16) == 15) 302 pthread_yield(); 303 else 304 AssertReleaseMsg(i < 4096, ("iNew=%d\n", iNew)); 307 /* this can't happen. */ 305 308 if (RT_UNLIKELY(pIntEventSem->iMagic != RTSEMEVENT_MAGIC)) 306 309 return VERR_SEM_DESTROYED; 310 AssertReleaseMsgFailed(("iNew=%d\n", iNew)); 307 311 } 308 312 }
Note:
See TracChangeset
for help on using the changeset viewer.