X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Faio%2Faio_suspend.c;h=9b24b6af2487a199591530fec4b2d7e13a7ba4c0;hb=0847902ab99065a48f9bd3729b6e676288dfd69e;hp=dcdf60196931201e0f07721d5bc707c14f1ce298;hpb=36c30c4ddd92ec3a058d54aac31a5734be6380f8;p=musl diff --git a/src/aio/aio_suspend.c b/src/aio/aio_suspend.c index dcdf6019..9b24b6af 100644 --- a/src/aio/aio_suspend.c +++ b/src/aio/aio_suspend.c @@ -1,60 +1,76 @@ #include #include +#include +#include "atomic.h" #include "pthread_impl.h" -#include "libc.h" - -/* Due to the requirement that aio_suspend be async-signal-safe, we cannot - * use any locks, wait queues, etc. that would make it more efficient. The - * only obviously-correct algorithm is to generate a wakeup every time any - * aio operation finishes and have aio_suspend re-evaluate the completion - * status of each aiocb it was waiting on. */ - -static volatile int seq; - -void __aio_wake(void) -{ - a_inc(&seq); - __wake(&seq, -1, 1); -} int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec *ts) { - int i, last, first=1, ret=0; + int i, tid = 0, ret, expect = 0; struct timespec at; + volatile int dummy_fut, *pfut; + int nzcnt = 0; + const struct aiocb *cb = 0; + + pthread_testcancel(); if (cnt<0) { errno = EINVAL; return -1; } - for (;;) { - last = seq; + for (i=0; i__err != EINPROGRESS) - return 0; + if (ts) { + clock_gettime(CLOCK_MONOTONIC, &at); + at.tv_sec += ts->tv_sec; + if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) { + at.tv_nsec -= 1000000000; + at.tv_sec++; } + } - if (first && ts) { - clock_gettime(CLOCK_MONOTONIC, &at); - at.tv_sec += ts->tv_sec; - if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) { - at.tv_nsec -= 1000000000; - at.tv_sec++; - } - first = 0; - } + for (;;) { + for (i=0; i__err; + expect = EINPROGRESS | 0x80000000; + a_cas(pfut, EINPROGRESS, expect); + break; + default: + pfut = &__aio_fut; + if (!tid) tid = __pthread_self()->tid; + expect = a_cas(pfut, 0, tid); + if (!expect) expect = tid; + /* Need to recheck the predicate before waiting. */ + for (i=0; i