Changeset 30711 in vbox for trunk/src/VBox/Runtime/r0drv/solaris
- Timestamp:
- Jul 7, 2010 3:54:20 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 63476
- Location:
- trunk/src/VBox/Runtime/r0drv/solaris
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c
r30472 r30711 55 55 /** Magic value (RTSEMEVENT_MAGIC). */ 56 56 uint32_t volatile u32Magic; 57 /** The number of waiting threads. */58 uint32_t volatile cWaiters;59 /** The number of signalled threads. */60 uint32_t volatile cWakeUp;61 57 /** The number of threads referencing this object. */ 62 58 uint32_t volatile cRefs; 59 /** Set if the object is signalled when there are no waiters. */ 60 bool fSignaled; 61 /** Object generation. 62 * This is incremented every time the object is signalled and used to 63 * check for spurious wake-ups. */ 64 uint32_t uSignalGen; 65 /** The number of waiting threads. */ 66 uint32_t cWaiters; 67 /** The number of signalled threads. */ 68 uint32_t cWakeUp; 63 69 /** The Solaris mutex protecting this structure and pairing up the with the cv. */ 64 70 kmutex_t Mtx; … … 87 93 88 94 pThis->u32Magic = RTSEMEVENT_MAGIC; 95 pThis->cRefs = 1; 96 pThis->fSignaled = false; 97 pThis->uSignalGen = 0; 89 98 pThis->cWaiters = 0; 90 99 pThis->cWakeUp = 0; 91 pThis->cRefs = 1;92 100 mutex_init(&pThis->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, (void *)ipltospl(DISP_LEVEL)); 93 101 cv_init(&pThis->Cnd, "IPRT CV", CV_DRIVER, NULL); … … 111 119 ASMAtomicDecU32(&pThis->cRefs); 112 120 113 ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */121 pThis->u32Magic = RTSEMEVENT_MAGIC_DEAD; /* make the handle invalid */ 114 122 if (pThis->cWaiters > 0) 115 123 { … … 175 183 } 176 184 177 ASMAtomicIncU32(&pThis->cWakeUp);185 pThis->cWakeUp++; 178 186 if (pThis->cWakeUp <= pThis->cWaiters) 179 187 { … … 184 192 */ 185 193 cv_signal(&pThis->Cnd); 186 } 194 pThis->uSignalGen++; 195 } 196 else 197 pThis->fSignaled = true; 187 198 188 199 mutex_exit(&pThis->Mtx); … … 237 248 ASMAtomicIncU32(&pThis->cRefs); 238 249 239 if (pThis-> cWakeUp > 0)250 if (pThis->fSignaled) 240 251 { 241 252 /* … … 244 255 */ 245 256 Assert(!pThis->cWaiters); 246 ASMAtomicWriteU32((uint32_t volatile *)&pThis->cWakeUp, 0); 257 pThis->fSignaled = false; 258 pThis->cWakeUp = 0; 247 259 rc = VINF_SUCCESS; 248 260 } … … 251 263 else 252 264 { 253 uint32_t cWakeUp = ASMAtomicUoReadU32((uint32_t volatile *)&pThis->cWakeUp);254 ASMAtomicIncU32(&pThis->cWaiters);265 pThis->cWaiters++; 266 /* This loop is only for continuing after a spurious wake-up. */ 255 267 for (;;) 256 268 { 269 uint32_t const uSignalGenBeforeWait = pThis->uSignalGen; 257 270 rc = rtSemEventWaitWorker(pThis, cMillies, fInterruptible); 258 271 if (rc > 0) 259 272 { 260 if (pThis->u32Magic != RTSEMEVENT_MAGIC)273 if (pThis->u32Magic == RTSEMEVENT_MAGIC) 261 274 { 262 /* 263 * We're being destroyed. 264 */ 265 ASMAtomicDecU32(&pThis->cWaiters); 266 rc = VERR_SEM_DESTROYED; 267 break; 275 if (pThis->uSignalGen != uSignalGenBeforeWait) 276 { 277 /* We've been signaled by cv_signal(), consume the wake up. */ 278 --pThis->cWakeUp; 279 rc = VINF_SUCCESS; 280 } 281 else 282 /* Spurious wakeup due to some signal, go back to waiting. */ 283 continue; 268 284 } 269 285 else 270 { 271 uint32_t cWakeUpNow = ASMAtomicUoReadU32((uint32_t volatile *)&pThis->cWakeUp); 272 if (cWakeUpNow > cWakeUp) 273 { 274 /* 275 * We've been signaled by RTSemEventSignal(), consume the wake up. 276 */ 277 ASMAtomicDecU32(&pThis->cWaiters); 278 ASMAtomicDecU32(&pThis->cWakeUp); 279 rc = VINF_SUCCESS; 280 break; 281 } 282 else 283 { 284 /* 285 * Premature wakeup due to some signal, go back to waiting. 286 */ 287 continue; 288 } 289 } 286 /* We're being destroyed. */ 287 rc = VERR_SEM_DESTROYED; 290 288 } 291 289 else if (rc == -1) 292 { 293 /* 294 * Timeout reached. 295 */ 296 ASMAtomicDecU32(&pThis->cWaiters); 290 /* Timeout reached. */ 297 291 rc = VERR_TIMEOUT; 298 break;299 }300 292 else 301 {302 293 /* Returned due to pending signal */ 303 ASMAtomicDecU32(&pThis->cWaiters);304 294 rc = VERR_INTERRUPTED; 305 break; 306 } 295 296 --pThis->cWaiters; 297 break; 307 298 } 308 299 } -
trunk/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
r30579 r30711 284 284 else 285 285 { 286 287 286 /* This loop is only for continuing after a spurious wake-up. */ 288 287 for (;;)
Note:
See TracChangeset
for help on using the changeset viewer.