| 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 |