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