about summary refs log tree commit diff
path: root/sysdeps/pthread
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/pthread')
-rw-r--r--sysdeps/pthread/aio_misc.h2
-rw-r--r--sysdeps/pthread/aio_notify.c12
-rw-r--r--sysdeps/pthread/aio_suspend.c36
-rw-r--r--sysdeps/pthread/lio_listio.c12
4 files changed, 54 insertions, 8 deletions
diff --git a/sysdeps/pthread/aio_misc.h b/sysdeps/pthread/aio_misc.h
index d9aa6e8dd3..50962c7519 100644
--- a/sysdeps/pthread/aio_misc.h
+++ b/sysdeps/pthread/aio_misc.h
@@ -47,7 +47,9 @@ struct waitlist
     struct waitlist *next;
 
     /* The next two fields is used in synchronous `lio_listio' operations.  */
+#ifndef DONT_NEED_AIO_MISC_COND
     pthread_cond_t *cond;
+#endif
     int *result;
 
     volatile int *counterp;
diff --git a/sysdeps/pthread/aio_notify.c b/sysdeps/pthread/aio_notify.c
index 4d2611f0a1..3f7f70ef7c 100644
--- a/sysdeps/pthread/aio_notify.c
+++ b/sysdeps/pthread/aio_notify.c
@@ -143,20 +143,24 @@ __aio_notify (struct requestlist *req)
     {
       struct waitlist *next = waitlist->next;
 
-      /* Decrement the counter.  This is used in both cases.  */
-      --*waitlist->counterp;
-
       if (waitlist->sigevp == NULL)
 	{
 	  if (waitlist->result != NULL && aiocbp->__return_value == -1)
 	    *waitlist->result = -1;
 
+#ifdef DONT_NEED_AIO_MISC_COND
+	  AIO_MISC_NOTIFY (waitlist);
+#else
+	  /* Decrement the counter.  */
+	  --*waitlist->counterp;
+
 	  pthread_cond_signal (waitlist->cond);
+#endif
 	}
       else
 	/* This is part of a asynchronous `lio_listio' operation.  If
 	   this request is the last one, send the signal.  */
-	if (*waitlist->counterp == 0)
+	if (--*waitlist->counterp == 0)
 	  {
 #ifdef BROKEN_THREAD_SIGNALS
 	    __aio_notify_only (waitlist->sigevp, waitlist->caller_pid);
diff --git a/sysdeps/pthread/aio_suspend.c b/sysdeps/pthread/aio_suspend.c
index 9e3a1ee46e..b85b16d10e 100644
--- a/sysdeps/pthread/aio_suspend.c
+++ b/sysdeps/pthread/aio_suspend.c
@@ -44,7 +44,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;
 };
 
@@ -52,6 +54,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
@@ -75,8 +83,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);
@@ -89,13 +99,21 @@ 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;
   bool any = false;
   int result = 0;
-  int dummy;
+  int cntr = 1;
 
   /* Request the mutex.  */
   pthread_mutex_lock (&__aio_requests_mutex);
@@ -111,10 +129,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 = &dummy;
+		waitlist[cnt].counterp = &cntr;
 		waitlist[cnt].sigevp = NULL;
 #ifdef BROKEN_THREAD_SIGNALS
 		waitlist[cnt].caller_pid = 0;	/* Not needed.  */
@@ -140,12 +160,17 @@ 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);
 
+#ifdef DONT_NEED_AIO_MISC_COND
+      AIO_MISC_WAIT (result, cntr, timeout, 1);
+#else
       if (timeout == NULL)
 	result = pthread_cond_wait (&cond, &__aio_requests_mutex);
       else
@@ -167,6 +192,7 @@ aio_suspend (list, nent, timeout)
 	  result = pthread_cond_timedwait (&cond, &__aio_requests_mutex,
 					   &abstime);
 	}
+#endif
 
       pthread_cleanup_pop (0);
     }
@@ -190,19 +216,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;
diff --git a/sysdeps/pthread/lio_listio.c b/sysdeps/pthread/lio_listio.c
index d6ad5a2b48..39187f3025 100644
--- a/sysdeps/pthread/lio_listio.c
+++ b/sysdeps/pthread/lio_listio.c
@@ -122,9 +122,11 @@ lio_listio_internal (int mode, struct aiocb *const list[], int nent,
     }
   else if (LIO_MODE (mode) == LIO_WAIT)
     {
+#ifndef DONT_NEED_AIO_MISC_COND
       pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-      struct waitlist waitlist[nent];
       int oldstate;
+#endif
+      struct waitlist waitlist[nent];
 
       total = 0;
       for (cnt = 0; cnt < nent; ++cnt)
@@ -133,7 +135,9 @@ lio_listio_internal (int mode, struct aiocb *const list[], int nent,
 
 	  if (requests[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
 	    {
+#ifndef DONT_NEED_AIO_MISC_COND
 	      waitlist[cnt].cond = &cond;
+#endif
 	      waitlist[cnt].result = &result;
 	      waitlist[cnt].next = requests[cnt]->waiting;
 	      waitlist[cnt].counterp = &total;
@@ -146,6 +150,9 @@ lio_listio_internal (int mode, struct aiocb *const list[], int nent,
 	    }
 	}
 
+#ifdef DONT_NEED_AIO_MISC_COND
+      AIO_MISC_WAIT (result, total, NULL, 0);
+#else
       /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancellation
 	 points we must be careful.  We added entries to the waiting lists
 	 which we must remove.  So defer cancellation for now.  */
@@ -161,6 +168,7 @@ lio_listio_internal (int mode, struct aiocb *const list[], int nent,
       if (pthread_cond_destroy (&cond) != 0)
 	/* This must never happen.  */
 	abort ();
+#endif
 
       /* If any of the I/O requests failed, return -1 and set errno.  */
       if (result != 0)
@@ -193,7 +201,9 @@ lio_listio_internal (int mode, struct aiocb *const list[], int nent,
 	      if (requests[cnt] != NULL
 		  && list[cnt]->aio_lio_opcode != LIO_NOP)
 		{
+#ifndef DONT_NEED_AIO_MISC_COND
 		  waitlist->list[cnt].cond = NULL;
+#endif
 		  waitlist->list[cnt].result = NULL;
 		  waitlist->list[cnt].next = requests[cnt]->waiting;
 		  waitlist->list[cnt].counterp = &waitlist->counter;