X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fthread%2Fsem_timedwait.c;h=aa67376c2dcd805bd0b830e8641472aa3f1b9782;hb=d055e6a45a17673b8dd3ec16e786bb2fe1700dd5;hp=df5f3a6ccb832abee3db21aa759547ac8224c9de;hpb=2ff714c6138da8abb50fd532503fd8d68a18811a;p=musl diff --git a/src/thread/sem_timedwait.c b/src/thread/sem_timedwait.c index df5f3a6c..aa67376c 100644 --- a/src/thread/sem_timedwait.c +++ b/src/thread/sem_timedwait.c @@ -1,4 +1,5 @@ #include +#include #include "pthread_impl.h" static void cleanup(void *p) @@ -8,17 +9,21 @@ static void cleanup(void *p) int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at) { + pthread_testcancel(); + if (!sem_trywait(sem)) return 0; int spins = 100; - while (spins-- && sem->__val[0] <= 0) a_spin(); + while (spins-- && !(sem->__val[0] & SEM_VALUE_MAX) && !sem->__val[1]) + a_spin(); while (sem_trywait(sem)) { - int r; + int r, priv = sem->__val[2]; a_inc(sem->__val+1); - a_cas(sem->__val, 0, -1); - r = __timedwait(sem->__val, -1, CLOCK_REALTIME, at, cleanup, sem->__val+1, sem->__val[2]); - a_dec(sem->__val+1); + a_cas(sem->__val, 0, 0x80000000); + pthread_cleanup_push(cleanup, (void *)(sem->__val+1)); + r = __timedwait_cp(sem->__val, 0x80000000, CLOCK_REALTIME, at, priv); + pthread_cleanup_pop(1); if (r) { errno = r; return -1;