diff options
Diffstat (limited to 'rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c')
-rw-r--r-- | rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c b/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c index 0b3380f98a..2400c5223c 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c +++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c @@ -1,5 +1,6 @@ /* Suspend until termination of a requests. - Copyright (C) 1997,1998,1999,2000,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -37,8 +38,10 @@ #include <assert.h> #include <errno.h> +#include <stdbool.h> #include <stdlib.h> #include <sys/time.h> + #include <bits/libc-lock.h> #include <sysdep-cancel.h> @@ -48,7 +51,9 @@ struct clparam const struct aiocb *const *list; struct waitlist *waitlist; struct requestlist **requestlist; +#ifndef DONT_NEED_AIO_MISC_COND pthread_cond_t *cond; +#endif int nent; }; @@ -56,6 +61,12 @@ struct clparam static void cleanup (void *arg) { +#ifdef DONT_NEED_AIO_MISC_COND + /* Acquire the mutex. If pthread_cond_*wait is used this would + happen implicitly. */ + pthread_mutex_lock (&__aio_requests_mutex); +#endif + const struct clparam *param = (const struct clparam *) arg; /* Now remove the entry in the waiting list for all requests @@ -79,8 +90,10 @@ cleanup (void *arg) *listp = (*listp)->next; } +#ifndef DONT_NEED_AIO_MISC_COND /* Release the conditional variable. */ (void) pthread_cond_destroy (param->cond); +#endif /* Release the mutex. */ pthread_mutex_unlock (&__aio_requests_mutex); @@ -93,11 +106,20 @@ aio_suspend (list, nent, timeout) int nent; const struct timespec *timeout; { + if (__builtin_expect (nent < 0, 0)) + { + __set_errno (EINVAL); + return -1; + } + struct waitlist waitlist[nent]; struct requestlist *requestlist[nent]; +#ifndef DONT_NEED_AIO_MISC_COND pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +#endif int cnt; int result = 0; + int cntr = 1; int total = 0, ktotal = 0; /* Request the mutex. */ @@ -114,9 +136,12 @@ aio_suspend (list, nent, timeout) if (requestlist[cnt] != NULL) { +#ifndef DONT_NEED_AIO_MISC_COND waitlist[cnt].cond = &cond; +#endif + waitlist[cnt].result = NULL; waitlist[cnt].next = requestlist[cnt]->waiting; - waitlist[cnt].counterp = &total; + waitlist[cnt].counterp = &cntr; waitlist[cnt].sigevp = NULL; #ifdef BROKEN_THREAD_SIGNALS waitlist[cnt].caller_pid = 0; /* Not needed. */ @@ -144,13 +169,15 @@ aio_suspend (list, nent, timeout) .list = list, .waitlist = waitlist, .requestlist = requestlist, +#ifndef DONT_NEED_AIO_MISC_COND .cond = &cond, +#endif .nent = nent }; pthread_cleanup_push (cleanup, &clparam); - if (!__kernel_thread_started) + if (!__kernel_thread_started && ktotal) { /* If the kernel aio thread was not started yet all requests are served by the kernel and there are no other threads running, @@ -160,7 +187,7 @@ aio_suspend (list, nent, timeout) { if (timeout == NULL) { - while (total == ktotal) + while (cntr == 1) __aio_wait_for_events (__aio_kioctx, NULL); } else @@ -180,7 +207,7 @@ aio_suspend (list, nent, timeout) for (;;) { result = __aio_wait_for_events (__aio_kioctx, timeout); - if (total < ktotal) + if (cntr < 1) break; if (result == ETIMEDOUT) break; @@ -201,7 +228,7 @@ aio_suspend (list, nent, timeout) timeout = &ts; } - if (total < ktotal) + if (cntr < 1) result = 0; else result = ETIMEDOUT; @@ -219,6 +246,10 @@ aio_suspend (list, nent, timeout) if (total == 0) /* Suspending was handled above. */ ; +#ifdef DONT_NEED_AIO_MISC_COND + else + AIO_MISC_WAIT (result, cntr, timeout, 1); +#else else if (timeout == NULL) result = pthread_cond_wait (&cond, &__aio_requests_mutex); else @@ -240,6 +271,7 @@ aio_suspend (list, nent, timeout) result = pthread_cond_timedwait (&cond, &__aio_requests_mutex, &abstime); } +#endif pthread_cleanup_pop (0); } @@ -263,19 +295,23 @@ aio_suspend (list, nent, timeout) *listp = (*listp)->next; } +#ifndef DONT_NEED_AIO_MISC_COND /* Release the conditional variable. */ if (__builtin_expect (pthread_cond_destroy (&cond) != 0, 0)) /* This must never happen. */ abort (); +#endif if (result != 0) { - /* An error occurred. Possibly it's EINTR. We have to translate +#ifndef DONT_NEED_AIO_MISC_COND + /* An error occurred. Possibly it's ETIMEDOUT. We have to translate the timeout error report of `pthread_cond_timedwait' to the form expected from `aio_suspend'. */ if (result == ETIMEDOUT) __set_errno (EAGAIN); else +#endif __set_errno (result); result = -1; |