Changeset 2294
- Timestamp:
- Aug 21, 2005, 11:03:21 AM (20 years ago)
- Location:
- trunk/src/emx
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/ChangeLog.LIBC
-
Property cvs2svn:cvs-rev
changed from
1.120
to1.121
r2293 r2294 2 2 3 3 TODO: open replace on RAMFS fails with error 32! 4 5 2005-08-21: knut st. osmundsen <bird-gccos2-spam@anduin.net> 6 - libc: 7 o Tried to workaround the race conditions in __libc_Back_safesemEvSleep/Wakeup. 8 These might affect SysV sems and shm. 4 9 5 10 2005-08-20: Lorne Sunley <lsunley@mb.sympatico. > -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/include/InnoTekLIBC/backend.h
-
Property cvs2svn:cvs-rev
changed from
1.29
to1.30
r2293 r2294 1063 1063 * @returns Negative error code (errno.h) on failure. 1064 1064 * @param hev Event semaphore to post. 1065 */ 1066 int __libc_Back_safesemEvWakeup(uintptr_t hev); 1065 * @param hmtx The semaphore protecting hev (see __libc_Back_safesemEvSleep). 1066 * The caller should own this semaphore, it's purpose is debug strictness only! 1067 */ 1068 int __libc_Back_safesemEvWakeup(uintptr_t hev, uintptr_t hmtx); 1067 1069 1068 1070 -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/safesems.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r2293 r2294 32 32 #define INCL_DOSEXCEPTIONS 33 33 #define INCL_DOSERRORS 34 #define INCL_DOSPROCESS 34 35 #define INCL_FSMACROS 35 36 #define INCL_EXAPIS … … 37 38 #include <sys/errno.h> 38 39 #include "syscalls.h" 40 #include <emx/umalloc.h> 39 41 #include <InnoTekLIBC/thread.h> 40 42 #include <InnoTekLIBC/backend.h> 43 #include <InnoTekLIBC/sharedpm.h> 41 44 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_IPC 42 45 #include <InnoTekLIBC/logstrict.h> 46 47 48 /******************************************************************************* 49 * Structures and Typedefs * 50 *******************************************************************************/ 51 /** 52 * Event semaphore tracking structure. 53 * 54 * The event semaphore business is difficult because the lack of 55 * atomic mutex release + event wait apis in OS/2. We have to 56 * jump around the place to get this working nearly safly... 57 */ 58 typedef struct __LIBC_SAFESEMEV 59 { 60 /** The event semaphore. */ 61 HEV hev; 62 /** Number of threads which are supposed to be blocking on the above event semaphore. */ 63 uint32_t volatile cWaiters; 64 /** Number of processes using the semaphore. */ 65 uint32_t volatile cUsers; 66 /** Set if the semaphore is shared. 67 * If shared this structure is allocated from SPM, else it's from the heap. */ 68 unsigned fShared; 69 #ifdef __LIBC_STRICT 70 /** The mutex semaphore used to protect the event semaphore. 71 * Strict builds only. */ 72 uintptr_t hmtx; 73 #endif 74 } __LIBC_SAFESEMEV, *__LIBC_PSAFESEMEV; 75 76 77 /** 78 * Arguments to semEvSleepSignalCallback(). 79 */ 80 struct SignalArgs 81 { 82 /** Set if pfnComplete have already been executed. */ 83 int volatile fDone; 84 /** Number of attempts at doing it. (in case of crashes in pfnComplete) */ 85 int volatile cTries; 86 /** Callback to execute. */ 87 void (*pfnComplete)(void *pvUser); 88 /** User arg. */ 89 void *pvUser; 90 /** The old priority - to be restored when we're unblocked. */ 91 ULONG ulOldPri; 92 /** Pointer to the semaphore structure. */ 93 __LIBC_PSAFESEMEV pEv; 94 }; 43 95 44 96 … … 206 258 int __libc_Back_safesemEvCreate(uintptr_t *phev, int fShared) 207 259 { 208 FS_VAR_SAVE_LOAD(); 209 HEV hev = NULLHANDLE; 210 int rc = DosCreateEventSemEx(NULL, &hev, fShared ? DC_SEM_SHARED : 0, FALSE); 211 FS_RESTORE(); 212 if (rc) 213 return -__libc_native2errno(rc); 214 *phev = hev; 215 return 0; 260 LIBCLOG_ENTER("phev=%p fShared=%d\n", (void *)phev, fShared); 261 int rc; 262 __LIBC_PSAFESEMEV pEv = NULL; 263 FS_VAR_SAVE_LOAD(); 264 if (fShared) 265 { 266 /* 267 * Allocate from SPM, be very careful. 268 */ 269 __LIBC_SPMXCPTREGREC RegRec; 270 rc = __libc_spmLock(&RegRec, NULL); 271 if (!rc) 272 { 273 pEv = __libc_spmAllocLocked(sizeof(*pEv)); 274 if (pEv) 275 { 276 pEv->hev = NULLHANDLE; 277 pEv->cWaiters = 0; 278 pEv->cUsers = 1; 279 pEv->fShared = fShared; 280 #ifdef __LIBC_STRICT 281 pEv->hmtx = 0; 282 #endif 283 284 rc = DosCreateEventSemEx(NULL, &pEv->hev, fShared ? DC_SEM_SHARED : 0, FALSE); 285 if (rc) 286 { 287 __libc_spmFree(pEv); 288 rc = -__libc_native2errno(rc); 289 } 290 } 291 else 292 rc = -ENOMEM; 293 __libc_spmUnlock(&RegRec); 294 } 295 } 296 else 297 { 298 /* 299 * Allocate from high mem heap. 300 */ 301 pEv = _hmalloc(sizeof(*pEv)); 302 if (pEv) 303 { 304 pEv->hev = NULLHANDLE; 305 pEv->cWaiters = 0; 306 pEv->cUsers = 1; 307 pEv->fShared = fShared; 308 #ifdef __LIBC_STRICT 309 pEv->hmtx = 0; 310 #endif 311 312 rc = DosCreateEventSemEx(NULL, &pEv->hev, fShared ? DC_SEM_SHARED : 0, FALSE); 313 if (rc) 314 { 315 free(pEv); 316 rc = -__libc_native2errno(rc); 317 } 318 } 319 else 320 rc = -ENOMEM; 321 } 322 FS_RESTORE(); 323 324 if (!rc) 325 *phev = (uintptr_t)pEv; 326 LIBCLOG_RETURN_MSG(rc, "ret %d *phev=%#x\n", rc, *phev); 216 327 } 217 328 … … 226 337 int __libc_Back_safesemEvOpen(uintptr_t hev) 227 338 { 228 FS_VAR_SAVE_LOAD(); 229 HMTX hevOS2 = hev; 230 int rc = DosOpenEventSemEx(NULL, &hevOS2); 231 FS_RESTORE(); 232 if (rc) 233 return -__libc_native2errno(rc); 234 return 0; 339 LIBCLOG_ENTER("hev=%#x\n", hev); 340 __LIBC_PSAFESEMEV pEv = (__LIBC_PSAFESEMEV)hev; 341 FS_VAR_SAVE_LOAD(); 342 int rc = DosOpenEventSemEx(NULL, &pEv->hev); 343 FS_RESTORE(); 344 if (!rc) 345 __atomic_increment_u32(&pEv->cUsers); 346 else 347 rc = -__libc_native2errno(rc); 348 LIBCLOG_RETURN_INT(rc); 235 349 } 236 350 … … 245 359 int __libc_Back_safesemEvClose(uintptr_t hev) 246 360 { 247 FS_VAR_SAVE_LOAD(); 248 int rc = DosCloseEventSemEx(hev); 249 FS_RESTORE(); 250 if (rc) 251 return -__libc_native2errno(rc); 252 return 0; 253 } 254 255 256 257 /** 258 * Arguments to semEvSleepSignalCallback(). 259 */ 260 struct SignalArgs 261 { 262 /** Set if pfnComplete have already been executed. */ 263 volatile int fDone; 264 /** Number of attempts at doing it. (in case of crashes in pfnComplete) */ 265 volatile int cTries; 266 /** Callback to execute. */ 267 void (*pfnComplete)(void *pvUser); 268 /** User arg. */ 269 void *pvUser; 270 }; 361 LIBCLOG_ENTER("hev=%#x\n", hev); 362 __LIBC_PSAFESEMEV pEv = (__LIBC_PSAFESEMEV)hev; 363 FS_VAR_SAVE_LOAD(); 364 int rc = DosCloseEventSemEx(pEv->hev); 365 FS_RESTORE(); 366 if (!rc) 367 { 368 if ( pEv->cUsers 369 && !__atomic_decrement_u32(&pEv->cUsers)) 370 { 371 pEv->hev = NULLHANDLE; 372 if (pEv->fShared) 373 __libc_spmFree(pEv); 374 else 375 free(pEv); 376 } 377 } 378 else 379 rc = -__libc_native2errno(rc); 380 LIBCLOG_RETURN_INT(rc); 381 } 382 271 383 272 384 /** 273 385 * Signal notification callback. 386 * 387 * This will call the completion handler and restore the thread priority before 388 * any signal is executed. We're protect by the signal mutex/must-complete here. 274 389 */ 275 390 static void semEvSleepSignalCallback(int iSignal, void *pvUser) 276 391 { 392 LIBCLOG_ENTER("iSignal=%d pvUser=%p\n", iSignal, pvUser); 277 393 struct SignalArgs *pArgs = (struct SignalArgs *)pvUser; 394 278 395 if (!pArgs->fDone && pArgs->cTries++ < 5) 279 396 { 280 397 pArgs->pfnComplete(pArgs->pvUser); 398 int rc = DosSetPriority(PRTYS_THREAD, pArgs->ulOldPri >> 8, pArgs->ulOldPri & 0xff, 0); 399 if (rc) 400 __libc_Back_panic(0, NULL, "DosSetPriority(PRTYS_THREAD, %x, %x, 0) -> %d\n", 401 (unsigned)pArgs->ulOldPri >> 8, (unsigned)pArgs->ulOldPri & 0xff, rc); 281 402 pArgs->fDone = 1; 282 403 } 283 } 404 LIBCLOG_RETURN_VOID(); 405 } 406 284 407 285 408 /** … … 300 423 { 301 424 LIBCLOG_ENTER("hev=%#x hmtx=%#x pfnComplete=%p pvUser=%p\n", hev, hmtx, (void *)pfnComplete, pvUser); 302 303 /* 304 * Setup signal notification. 305 */ 425 __LIBC_PSAFESEMEV pEv = (__LIBC_PSAFESEMEV)hev; 426 427 #ifdef __LIBC_STRICT 428 /* 429 * Keep track of hmtx. 430 */ 431 if (pEv->hmtx) 432 LIBC_ASSERTM(pEv->hmtx == hmtx, "pEv->hmtx=%#x hmtx=%#x\n", pEv->hmtx, hmtx); 433 else 434 pEv->hmtx = hmtx; 435 #endif 436 437 /* 438 * Setup signal notification callback. 439 */ 440 int rc; 306 441 __LIBC_PTHREAD pThrd = __libc_threadCurrentNoAuto(); 307 int rc;308 442 if (pThrd) 309 443 { 444 FS_VAR_SAVE_LOAD(); 445 PTIB pTib; 446 PPIB pPib; 447 DosGetInfoBlocks(&pTib, &pPib); 448 310 449 struct SignalArgs Args; 450 Args.ulOldPri = pTib->tib_ptib2->tib2_ulpri; 311 451 Args.fDone = 0; 312 452 Args.cTries = 0; 313 453 Args.pfnComplete = pfnComplete; 314 454 Args.pvUser = pvUser; 455 315 456 pThrd->pvSigCallbackUser = &Args; 316 457 pThrd->pfnSigCallback = semEvSleepSignalCallback; 317 458 318 459 /* 319 * Reset the event semaphore. 460 * Raise priority to time critical to increase our chances of actually getting 461 * blocked before something bad like rescheduling or signaling strikes us. 320 462 */ 321 ULONG ulIgnore; 322 FS_VAR_SAVE_LOAD(); 323 rc = DosResetEventSem(hev, &ulIgnore); 324 if (!rc || rc == ERROR_ALREADY_RESET) 463 rc = DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 31, 0); 464 LIBC_ASSERTM(!rc, "DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 31, 0) -> %d\n", rc); 465 if (rc && (Args.ulOldPri >> 8) != PRTYC_TIMECRITICAL) 466 { 467 rc = DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); 468 LIBC_ASSERTM(!rc, "DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0) -> %d\n", rc); 469 } 470 471 /* 472 * Release the sempahore and exit the must complete section. 473 */ 474 __atomic_increment_u32(&pEv->cWaiters); 475 rc = __libc_Back_safesemMtxUnlock(hmtx); 476 if (!rc) 325 477 { 326 478 /* 327 * Release the sempahore and exit the must complete section.479 * Now, lets block until something happens. 328 480 */ 329 rc = __libc_Back_safesemMtxUnlock(hmtx); 330 if (!rc) 481 int rc2 = 0; 482 if (!Args.fDone) 483 rc2 = DosWaitEventSem(pEv->hev, SEM_INDEFINITE_WAIT); 484 485 /* 486 * Reclaim the ownership of the sempahore (w/must-complete) and deregister 487 * the signal notification callback before we check if we was interrupted or not during the wait. 488 */ 489 __atomic_decrement_u32(&pEv->cWaiters); 490 LIBCLOG_MSG("woke up - rc2=%d\n", rc2); 491 rc = __libc_Back_safesemMtxLock(hmtx); 492 pThrd->pfnSigCallback = NULL; 493 pThrd->pvSigCallbackUser = NULL; 494 if (!Args.fDone) 331 495 { 332 /* 333 * Now, lets wait. 496 /* 497 * Not interrupted. 498 * Check for errors, do completion and restore priority. 334 499 */ 335 DosWaitEventSem(hev, SEM_INDEFINITE_WAIT); 336 337 /* 338 * Regain access to the semaphore and must complete section 339 * before checking if we got an interrupt or not. 340 */ 341 rc = __libc_Back_safesemMtxLock(hmtx); 342 if (!Args.fDone) 343 pfnComplete(pvUser); 344 else if (!rc) 345 rc = -EINTR; 500 if (rc2) 501 rc = -__libc_native2errno(rc2); 502 pfnComplete(pvUser); 503 rc2 = DosSetPriority(PRTYS_THREAD, Args.ulOldPri >> 8, Args.ulOldPri & 0xff, 0); 504 if (rc2) 505 __libc_Back_panic(0, NULL, "DosSetPriority(PRTYS_THREAD, %x, %x, 0) -> %d\n", 506 (unsigned)Args.ulOldPri >> 8, (unsigned)Args.ulOldPri & 0xff, rc2); 346 507 } 508 else if (!rc) 509 rc = -EINTR; 510 511 /* 512 * Reset the event semaphore. 513 */ 514 ULONG ulIgnore; 515 rc2 = DosResetEventSem(pEv->hev, &ulIgnore); 516 LIBC_ASSERTM(!rc2 && ERROR_ALREADY_RESET, "DosResetEventSem(%#lx,)->%d\n", pEv->hev, rc2); 347 517 } 348 else349 rc = -__libc_native2errno(rc);350 518 FS_RESTORE(); 351 519 } … … 363 531 * @returns Negative error code (errno.h) on failure. 364 532 * @param hev Event semaphore to post. 365 */ 366 int __libc_Back_safesemEvWakeup(uintptr_t hev) 367 { 368 LIBCLOG_ENTER("hev=%#x\n", hev); 369 FS_VAR_SAVE_LOAD(); 370 int rc = DosPostEventSem(hev); 371 FS_RESTORE(); 372 if (rc) 533 * @param hmtx The semaphore protecting hev (see __libc_Back_safesemEvSleep). 534 * The caller should own this semaphore, it's purpose is debug strictness only! 535 */ 536 int __libc_Back_safesemEvWakeup(uintptr_t hev, uintptr_t hmtx) 537 { 538 LIBCLOG_ENTER("hev=%#x hmtx=%#x\n", hev, hmtx); 539 __LIBC_PSAFESEMEV pEv = (__LIBC_PSAFESEMEV)hev; 540 FS_VAR_SAVE_LOAD(); 541 int rc; 542 543 #ifdef __LIBC_STRICT 544 /* 545 * Check hmtx. 546 */ 547 LIBC_ASSERTM(!pEv->hmtx || pEv->hmtx == hmtx, "pEv->hmtx=%#x hmtx=%#x\n", pEv->hmtx, hmtx); 548 ULONG cNesting; 549 PID pid; 550 TID tid; 551 rc = DosQueryMutexSem(hmtx, &pid, &tid, &cNesting); 552 LIBC_ASSERTM(!rc, "DosQueryMutexSem(%#x,,,) -> %d\n", hmtx, rc); 553 if (!rc) 554 LIBC_ASSERTM(pid == fibGetPid() && tid == fibGetTid(), 555 "pid=%d fibGetPid()->%d tid=%d fibGetTid()->%d\n", (int)pid, fibGetPid(), (int)tid, fibGetTid()); 556 #endif 557 558 /* 559 * Post it. 560 */ 561 rc = DosPostEventSem(hev); 562 if (!rc) 563 { 564 if (!rc && pEv->cWaiters) 565 { 566 /* give the waiting threads a fair chance to get past the DosWaitEventSem() call. */ 567 unsigned cYields = 3; 568 do 569 { 570 DosSleep(0); 571 LIBCLOG_MSG("cWaiters=%d cYields=%d\n", pEv->cWaiters, cYields); 572 } while (pEv->cWaiters && --cYields > 0); 573 } 574 } 575 else 373 576 { 374 577 if (rc == ERROR_ALREADY_POSTED || rc == ERROR_TOO_MANY_POSTS) … … 377 580 rc = -__libc_native2errno(rc); 378 581 } 582 FS_RESTORE(); 379 583 LIBCLOG_RETURN_INT(rc); 380 584 } -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/sysv_sem.c
-
Property cvs2svn:cvs-rev
changed from
1.4
to1.5
r2293 r2294 628 628 semundo_clear(semid, -1); 629 629 SEMUNDO_UNLOCK(); 630 __libc_Back_safesemEvWakeup(semaptr->hev );630 __libc_Back_safesemEvWakeup(semaptr->hev, semaptr->hmtx); 631 631 break; 632 632 … … 742 742 semundo_clear(semid, semnum); 743 743 SEMUNDO_UNLOCK(); 744 __libc_Back_safesemEvWakeup(semaptr->hev );744 __libc_Back_safesemEvWakeup(semaptr->hev, semaptr->hmtx); 745 745 break; 746 746 … … 778 778 semundo_clear(semid, -1); 779 779 SEMUNDO_UNLOCK(); 780 __libc_Back_safesemEvWakeup(semaptr->hev );780 __libc_Back_safesemEvWakeup(semaptr->hev, semaptr->hmtx); 781 781 break; 782 782 … … 1208 1208 if (do_wakeup) { 1209 1209 DPRINTF(("semop: doing wakeup\n")); 1210 __libc_Back_safesemEvWakeup(semaptr->hev );1210 __libc_Back_safesemEvWakeup(semaptr->hev, semaptr->hmtx); 1211 1211 DPRINTF(("semop: back from wakeup\n")); 1212 1212 } … … 1298 1298 semaptr->u.sem_base[semnum].semval += adjval; 1299 1299 1300 __libc_Back_safesemEvWakeup(semaptr->hev );1300 __libc_Back_safesemEvWakeup(semaptr->hev, semaptr->hmtx); 1301 1301 DPRINTF(("semexit: back from wakeup\n")); 1302 1302 skip: -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/lib/sys/sysv_shm.c
-
Property cvs2svn:cvs-rev
changed from
1.4
to1.5
r2293 r2294 286 286 pGlobals->shm_nused--; 287 287 shmseg->shm_perm.mode = SHMSEG_FREE; 288 __libc_Back_safesemEvWakeup(pGlobals->hevDaemon );288 __libc_Back_safesemEvWakeup(pGlobals->hevDaemon, pGlobals->hmtx); 289 289 } 290 290 … … 314 314 pGlobals->shm_last_free = segnum; 315 315 } 316 __libc_Back_safesemEvWakeup(pGlobals->hevDaemon );316 __libc_Back_safesemEvWakeup(pGlobals->hevDaemon, pGlobals->hmtx); 317 317 return (0); 318 318 } -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.