OLD | NEW |
1 #include <aio.h> | 1 #include <aio.h> |
2 #include <errno.h> | 2 #include <errno.h> |
3 #include <time.h> | 3 #include <time.h> |
4 #include "atomic.h" | 4 #include "atomic.h" |
5 #include "libc.h" | 5 #include "libc.h" |
6 #include "pthread_impl.h" | 6 #include "pthread_impl.h" |
7 | 7 |
8 extern volatile int __aio_fut; | 8 extern volatile int __aio_fut; |
9 | 9 |
10 int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec
*ts) | 10 int aio_suspend(const struct aiocb* const cbs[], |
11 { | 11 int cnt, |
12 » int i, tid = 0, ret, expect = 0; | 12 const struct timespec* ts) { |
13 » struct timespec at; | 13 int i, tid = 0, ret, expect = 0; |
14 » volatile int dummy_fut, *pfut; | 14 struct timespec at; |
15 » int nzcnt = 0; | 15 volatile int dummy_fut, *pfut; |
16 » const struct aiocb *cb = 0; | 16 int nzcnt = 0; |
| 17 const struct aiocb* cb = 0; |
17 | 18 |
18 » pthread_testcancel(); | 19 pthread_testcancel(); |
19 | 20 |
20 » if (cnt<0) { | 21 if (cnt < 0) { |
21 » » errno = EINVAL; | 22 errno = EINVAL; |
22 » » return -1; | 23 return -1; |
23 » } | 24 } |
24 | 25 |
25 » for (i=0; i<cnt; i++) if (cbs[i]) { | 26 for (i = 0; i < cnt; i++) |
26 » » if (aio_error(cbs[i]) != EINPROGRESS) return 0; | 27 if (cbs[i]) { |
27 » » nzcnt++; | 28 if (aio_error(cbs[i]) != EINPROGRESS) |
28 » » cb = cbs[i]; | 29 return 0; |
29 » } | 30 nzcnt++; |
| 31 cb = cbs[i]; |
| 32 } |
30 | 33 |
31 » if (ts) { | 34 if (ts) { |
32 » » clock_gettime(CLOCK_MONOTONIC, &at); | 35 clock_gettime(CLOCK_MONOTONIC, &at); |
33 » » at.tv_sec += ts->tv_sec; | 36 at.tv_sec += ts->tv_sec; |
34 » » if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) { | 37 if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) { |
35 » » » at.tv_nsec -= 1000000000; | 38 at.tv_nsec -= 1000000000; |
36 » » » at.tv_sec++; | 39 at.tv_sec++; |
37 » » } | 40 } |
38 » } | 41 } |
39 | 42 |
40 » for (;;) { | 43 for (;;) { |
41 » » for (i=0; i<cnt; i++) | 44 for (i = 0; i < cnt; i++) |
42 » » » if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS) | 45 if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS) |
43 » » » » return 0; | 46 return 0; |
44 | 47 |
45 » » switch (nzcnt) { | 48 switch (nzcnt) { |
46 » » case 0: | 49 case 0: |
47 » » » pfut = &dummy_fut; | 50 pfut = &dummy_fut; |
48 » » » break; | 51 break; |
49 » » case 1: | 52 case 1: |
50 » » » pfut = (void *)&cb->__err; | 53 pfut = (void*)&cb->__err; |
51 » » » expect = EINPROGRESS | 0x80000000; | 54 expect = EINPROGRESS | 0x80000000; |
52 » » » a_cas(pfut, EINPROGRESS, expect); | 55 a_cas(pfut, EINPROGRESS, expect); |
53 » » » break; | 56 break; |
54 » » default: | 57 default: |
55 » » » pfut = &__aio_fut; | 58 pfut = &__aio_fut; |
56 » » » if (!tid) tid = __pthread_self()->tid; | 59 if (!tid) |
57 » » » expect = a_cas(pfut, 0, tid); | 60 tid = __pthread_self()->tid; |
58 » » » if (!expect) expect = tid; | 61 expect = a_cas(pfut, 0, tid); |
59 » » » /* Need to recheck the predicate before waiting. */ | 62 if (!expect) |
60 » » » for (i=0; i<cnt; i++) | 63 expect = tid; |
61 » » » » if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS) | 64 /* Need to recheck the predicate before waiting. */ |
62 » » » » » return 0; | 65 for (i = 0; i < cnt; i++) |
63 » » » break; | 66 if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS) |
64 » » } | 67 return 0; |
| 68 break; |
| 69 } |
65 | 70 |
66 » » ret = __timedwait_cp(pfut, expect, CLOCK_MONOTONIC, ts?&at:0, 1)
; | 71 ret = __timedwait_cp(pfut, expect, CLOCK_MONOTONIC, ts ? &at : 0, 1); |
67 | 72 |
68 » » switch (ret) { | 73 switch (ret) { |
69 » » case ETIMEDOUT: | 74 case ETIMEDOUT: |
70 » » » ret = EAGAIN; | 75 ret = EAGAIN; |
71 » » case ECANCELED: | 76 case ECANCELED: |
72 » » case EINTR: | 77 case EINTR: |
73 » » » errno = ret; | 78 errno = ret; |
74 » » » return -1; | 79 return -1; |
75 » » } | 80 } |
76 » } | 81 } |
77 } | 82 } |
78 | 83 |
79 LFS64(aio_suspend); | 84 LFS64(aio_suspend); |
OLD | NEW |