[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Hurd_condition_wait in glibc libpthreads in Debian



Hi folks,

OK, I have a patch that adds pthread_hurd_cond_wait into the libpthreads that Samuel has migrated
into Debian's glibc.  It builds but it isn't creating the symbol in libpthreads.so.  What stupid
thing am I missing?

Attached is the patch.

Thanks!

Barry deFreese

diff -pruN libpthread.orig/forward.c libpthread/forward.c
--- a/libpthread.orig/forward.c	2012-07-27 23:19:19.000000000 +0000
+++ b/libpthread/forward.c	2012-07-27 23:22:03.000000000 +0000
@@ -84,6 +84,8 @@ FORWARD (pthread_cond_init,
 FORWARD (pthread_cond_signal, (pthread_cond_t *cond), (cond), 0)
 FORWARD (pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
 	 (cond, mutex), 0)
+FORWARD (pthread_hurd_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
+	 (cond, mutex), 0)
 FORWARD (pthread_cond_timedwait,
 	 (pthread_cond_t *cond, pthread_mutex_t *mutex,
 	  const struct timespec *abstime), (cond, mutex, abstime), 0)
diff -pruN libpthread.orig/include/pthread/pthread.h libpthread/include/pthread/pthread.h
--- a/libpthread.orig/include/pthread/pthread.h	2012-07-27 23:19:19.000000000 +0000
+++ b/libpthread/include/pthread/pthread.h	2012-07-27 23:19:54.000000000 +0000
@@ -421,6 +421,10 @@ extern int pthread_cond_broadcast (pthre
 extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
 			      pthread_mutex_t *__restrict __mutex);
 
+/* Same as pthread_cond_wait but cancellable. */
+extern int pthread_hurd_cond_wait (pthread_cond_t *__restrict __cond,
+			      pthread_mutex_t *__restrict __mutex);
+
 /* Block on condition variable COND.  MUTEX should be held by the
    calling thread. On success, MUTEX will be held by the calling
    thread.  If the time specified by ABSTIME passes, ETIMEDOUT is
diff -pruN libpthread.orig/sysdeps/generic/pt-cond-wait.c libpthread/sysdeps/generic/pt-cond-wait.c
--- a/libpthread.orig/sysdeps/generic/pt-cond-wait.c	2012-07-27 23:19:20.000000000 +0000
+++ b/libpthread/sysdeps/generic/pt-cond-wait.c	2012-07-27 23:20:48.000000000 +0000
@@ -21,6 +21,9 @@
 
 #include <pt-internal.h>
 
+#include <hurd/signal.h>
+#include <assert.h>
+
 /* Implemented in pt-cond-timedwait.c.  */
 extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond,
 					      pthread_mutex_t *mutex,
@@ -36,4 +39,93 @@ __pthread_cond_wait (pthread_cond_t *con
   return __pthread_cond_timedwait_internal (cond, mutex, 0);
 }
 
+/* Just like condition_wait, but cancellable.  Returns true if cancelled.  */
+int
+__pthread_hurd_cond_wait (pthread_cond_t *c, pthread_mutex_t *m)
+{
+  /* This function will be called by hurd_thread_cancel while we are blocked
+     in the condition_wait.  We wake up all threads blocked on C,
+     so our thread will wake up and notice the cancellation flag.  */
+  struct __pthread *self = _pthread_self ();
+
+  void cancel_me (void)
+    {
+      __pthread_spin_lock (&c->__lock);
+
+      /* If self has been dequeued, self->prevp == 0 */
+      if (self->prevp)
+        {
+          __pthread_dequeue (self);
+          __pthread_spin_unlock (&c->__lock);
+          __pthread_wakeup (self);
+        }
+      else
+        {
+          /* There is no thread to wakeup */
+          __pthread_spin_unlock (&c->__lock);
+        }
+    }
+
+  struct hurd_sigstate *ss = _hurd_self_sigstate ();
+
+  int cancel;
+
+  assert (ss->intr_port == MACH_PORT_NULL); /* Sanity check for signal bugs. */
+
+
+  /* Atomically enqueue our cproc on the condition variable's queue of
+     waiters, and mark our sigstate to indicate that `cancel_me' must be
+     called to wake us up.  We must hold the sigstate lock while acquiring
+     the condition variable's lock and tweaking it, so that
+     hurd_thread_cancel can never suspend us and then deadlock in
+     condition_broadcast waiting for the condition variable's lock.  */
+
+  __pthread_spin_lock (&ss->lock);
+  __pthread_spin_lock (&c->__lock);
+  cancel = ss->cancel;
+  if (cancel)
+    /* We were cancelled before doing anything.  Don't block at all.  */
+    ss->cancel = 0;
+  else
+    {
+      /* Put us on the queue so that condition_broadcast will know to wake
+         us up.  */
+      __pthread_enqueue (&c->__queue, self);
+      /* Tell hurd_thread_cancel how to unblock us.  */
+      ss->cancel_hook = &cancel_me;
+    }
+  __pthread_spin_unlock (&c->__lock);
+  __pthread_spin_unlock (&ss->lock);
+
+  if (cancel)
+    {
+      /* Cancelled on entry.  Just leave the mutex locked.  */
+      m = NULL;
+    }
+  else
+    {
+      /* Now unlock the mutex and block until woken.  */
+      pthread_mutex_unlock (m);
+      __pthread_block (self);
+    }
+
+  __pthread_spin_lock (&ss->lock);
+  /* Clear the hook, now that we are done blocking.  */
+  ss->cancel_hook = NULL;
+  /* Check the cancellation flag; we might have unblocked due to
+     cancellation rather than a normal condition_signal or
+     condition_broadcast (or we might have just happened to get cancelled
+     right after waking up).  */
+  cancel |= ss->cancel;
+  ss->cancel = 0;
+  __pthread_spin_unlock (&ss->lock);
+
+  if (m)
+    /* Reacquire the mutex and return.  */
+    __pthread_mutex_lock (m);
+
+  return cancel;
+}
+
 strong_alias (__pthread_cond_wait, pthread_cond_wait);
+strong_alias (__pthread_hurd_cond_wait, pthread_hurd_cond_wait);
diff -pruN libpthread.orig/Versions libpthread/Versions
--- a/libpthread.orig/Versions	2012-07-27 23:19:22.000000000 +0000
+++ b/libpthread/Versions	2012-07-27 23:21:24.000000000 +0000
@@ -9,7 +9,7 @@ libc {
     pthread_condattr_destroy; pthread_condattr_init;
     pthread_cond_broadcast; pthread_cond_destroy;
     pthread_cond_init; pthread_cond_signal; pthread_cond_wait;
-    pthread_cond_timedwait;
+    pthread_cond_timedwait; pthread_hurd_cond_wait;
     pthread_equal;
     pthread_exit; pthread_getschedparam; pthread_setschedparam;
     pthread_mutex_destroy; pthread_mutex_init;
--- a/libpthread/pthread/pthread-functions.h       2012-07-30 09:29:58.000000000 +0000
+++ b/libpthread/pthread/pthread-functions.h     2012-07-29 12:38:23.000000000 +0000
@@ -44,6 +44,7 @@ int __pthread_cond_init (pthread_cond_t
                       const pthread_condattr_t *);
 int __pthread_cond_signal (pthread_cond_t *);
 int __pthread_cond_wait (pthread_cond_t *, pthread_mutex_t *);
+int __pthread_hurd_cond_wait (pthread_cond_t *, pthread_mutex_t *);
 int __pthread_cond_timedwait (pthread_cond_t *, pthread_mutex_t *,
                             const struct timespec *);
 int __pthread_equal (pthread_t, pthread_t);
@@ -89,6 +90,7 @@ struct pthread_functions
                               const pthread_condattr_t *);
   int (*ptr_pthread_cond_signal) (pthread_cond_t *);
   int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
+  int (*ptr_pthread_hurd_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
   int (*ptr_pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
                                     const struct timespec *);
   int (*ptr_pthread_equal) (pthread_t, pthread_t);


Reply to: