]>
Commit | Line | Data |
---|---|---|
320054e8 DG |
1 | #include <semaphore.h> |
2 | #include "pthread_impl.h" | |
3 | ||
4 | static void cleanup(void *p) | |
5 | { | |
6 | a_dec(p); | |
7 | } | |
8 | ||
9 | int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at) | |
10 | { | |
11 | pthread_testcancel(); | |
12 | ||
13 | if (!sem_trywait(sem)) return 0; | |
14 | ||
15 | int spins = 100; | |
16 | while (spins-- && sem->__val[0] <= 0 && !sem->__val[1]) a_spin(); | |
17 | ||
18 | while (sem_trywait(sem)) { | |
19 | int r; | |
20 | a_inc(sem->__val+1); | |
21 | a_cas(sem->__val, 0, -1); | |
22 | pthread_cleanup_push(cleanup, (void *)(sem->__val+1)); | |
23 | r = __timedwait_cp(sem->__val, -1, CLOCK_REALTIME, at, sem->__val[2]); | |
24 | pthread_cleanup_pop(1); | |
25 | if (r) { | |
26 | errno = r; | |
27 | return -1; | |
28 | } | |
29 | } | |
30 | return 0; | |
31 | } |