- for (;;) {
- if (a_fetch_add(sem->__val, -1) > 0) return 0;
- val = a_fetch_add(sem->__val, 1);
- CANCELPT_BEGIN;
- if (val <= 0 && __timedwait(sem->__val, val, CLOCK_REALTIME, at, 0) == ETIMEDOUT) {
- errno = ETIMEDOUT;
+int sem_timedwait(sem_t *sem, const struct timespec *at)
+{
+ while (sem_trywait(sem)) {
+ int r;
+ a_inc(sem->__val+1);
+ a_cas(sem->__val, 0, -1);
+ r = __timedwait(sem->__val, -1, CLOCK_REALTIME, at, cleanup, sem->__val+1, 0);
+ a_dec(sem->__val+1);
+ if (r) {
+ errno = r;