1 #include <semaphore.h>
2 
3 #include <stdatomic.h>
4 
5 #include "atomic.h"
6 #include "threads_impl.h"
7 
sem_timedwait(sem_t * restrict sem,const struct timespec * restrict at)8 int sem_timedwait(sem_t* restrict sem, const struct timespec* restrict at) {
9     if (!sem_trywait(sem))
10         return 0;
11 
12     int spins = 100;
13     while (spins-- && atomic_load(&sem->_s_value) <= 0 && !atomic_load(&sem->_s_waiters))
14         a_spin();
15 
16     while (sem_trywait(sem)) {
17         atomic_fetch_add(&sem->_s_waiters, 1);
18         a_cas_shim(&sem->_s_value, 0, -1);
19         int r = __timedwait(&sem->_s_value, -1, CLOCK_REALTIME, at);
20         if (r) {
21             errno = r;
22             return -1;
23         }
24     }
25     return 0;
26 }
27