OLD | NEW |
(Empty) | |
| 1 #include <pthread.h> |
| 2 #include <time.h> |
| 3 #include <errno.h> |
| 4 #include "futex.h" |
| 5 #include "syscall.h" |
| 6 #include "pthread_impl.h" |
| 7 |
| 8 int __pthread_setcancelstate(int, int *); |
| 9 int __clock_gettime(clockid_t, struct timespec *); |
| 10 |
| 11 int __timedwait_cp(volatile int *addr, int val, |
| 12 clockid_t clk, const struct timespec *at, int priv) |
| 13 { |
| 14 int r; |
| 15 struct timespec to, *top=0; |
| 16 |
| 17 if (priv) priv = 128; |
| 18 |
| 19 if (at) { |
| 20 if (at->tv_nsec >= 1000000000UL) return EINVAL; |
| 21 if (__clock_gettime(clk, &to)) return EINVAL; |
| 22 to.tv_sec = at->tv_sec - to.tv_sec; |
| 23 if ((to.tv_nsec = at->tv_nsec - to.tv_nsec) < 0) { |
| 24 to.tv_sec--; |
| 25 to.tv_nsec += 1000000000; |
| 26 } |
| 27 if (to.tv_sec < 0) return ETIMEDOUT; |
| 28 top = &to; |
| 29 } |
| 30 |
| 31 r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT|priv, val, top); |
| 32 if (r == ENOSYS) r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT, val, top
); |
| 33 if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0; |
| 34 |
| 35 return r; |
| 36 } |
| 37 |
| 38 int __timedwait(volatile int *addr, int val, |
| 39 clockid_t clk, const struct timespec *at, int priv) |
| 40 { |
| 41 int cs, r; |
| 42 __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
| 43 r = __timedwait_cp(addr, val, clk, at, priv); |
| 44 __pthread_setcancelstate(cs, 0); |
| 45 return r; |
| 46 } |
OLD | NEW |