Source-Changes-HG archive

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

[src/trunk]: src/lib/libpthread Prevent ptc_mutex from remaining set if a CV ...



details:   https://anonhg.NetBSD.org/src/rev/c51fc0e5b9f1
branches:  trunk
changeset: 555567:c51fc0e5b9f1
user:      nathanw <nathanw%NetBSD.org@localhost>
date:      Fri Nov 21 22:08:00 2003 +0000

description:
Prevent ptc_mutex from remaining set if a CV sleep is woken by
cancellation:

 * Arrange to not set ptc_mutex until after the pre-sleep cancellation
   test.

 * In the post-sleep cancellation test, check if there are no more
   sleepers and clear ptc_mutex if so.

While here, sprinkle some __predict_false() around the cancellation
tests.

diffstat:

 lib/libpthread/pthread_cond.c |  67 ++++++++++++++++++++++++++----------------
 1 files changed, 41 insertions(+), 26 deletions(-)

diffs (127 lines):

diff -r 764aee6032af -r c51fc0e5b9f1 lib/libpthread/pthread_cond.c
--- a/lib/libpthread/pthread_cond.c     Fri Nov 21 22:05:06 2003 +0000
+++ b/lib/libpthread/pthread_cond.c     Fri Nov 21 22:08:00 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_cond.c,v 1.11 2003/04/23 19:36:12 nathanw Exp $        */
+/*     $NetBSD: pthread_cond.c,v 1.12 2003/11/21 22:08:00 nathanw Exp $        */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_cond.c,v 1.11 2003/04/23 19:36:12 nathanw Exp $");
+__RCSID("$NetBSD: pthread_cond.c,v 1.12 2003/11/21 22:08:00 nathanw Exp $");
 
 #include <errno.h>
 #include <sys/time.h>
@@ -118,6 +118,14 @@
                return pthread_cond_wait_nothread(self, mutex, NULL);
 
        pthread_spinlock(self, &cond->ptc_lock);
+       SDPRINTF(("(cond wait %p) Waiting on %p, mutex %p\n",
+           self, cond, mutex));
+       pthread_spinlock(self, &self->pt_statelock);
+       if (__predict_false(self->pt_cancel)) {
+               pthread_spinunlock(self, &self->pt_statelock);
+               pthread_spinunlock(self, &cond->ptc_lock);
+               pthread_exit(PTHREAD_CANCELED);
+       }
 #ifdef ERRORCHECK
        if (cond->ptc_mutex == NULL)
                cond->ptc_mutex = mutex;
@@ -126,28 +134,27 @@
                    "Multiple mutexes used for condition wait", 
                    cond->ptc_mutex == mutex);
 #endif
-
-       SDPRINTF(("(cond wait %p) Waiting on %p, mutex %p\n",
-           self, cond, mutex));
-       pthread_spinlock(self, &self->pt_statelock);
-       if (self->pt_cancel) {
-               pthread_spinunlock(self, &self->pt_statelock);
-               pthread_spinunlock(self, &cond->ptc_lock);
-               pthread_exit(PTHREAD_CANCELED);
-       }
        self->pt_state = PT_STATE_BLOCKED_QUEUE;
        self->pt_sleepobj = cond;
        self->pt_sleepq = &cond->ptc_waiters;
        self->pt_sleeplock = &cond->ptc_lock;
        pthread_spinunlock(self, &self->pt_statelock);
-
        PTQ_INSERT_HEAD(&cond->ptc_waiters, self, pt_sleep);
        pthread_mutex_unlock(mutex);
 
        pthread__block(self, &cond->ptc_lock);
        /* Spinlock is unlocked on return */
        pthread_mutex_lock(mutex);
-       pthread__testcancel(self);
+       if (__predict_false(self->pt_cancel)) {
+#ifdef ERRORCHECK
+               pthread_spinlock(self, &cond->ptc_lock);
+               if (PTQ_EMPTY(&cond->ptc_waiters))
+                       cond->ptc_mutex = NULL;
+               pthread_spinunlock(self, &cond->ptc_lock);
+#endif         
+               pthread_exit(PTHREAD_CANCELED);
+       }
+
        SDPRINTF(("(cond wait %p) Woke up on %p, mutex %p\n",
            self, cond, mutex));
 
@@ -187,6 +194,18 @@
                return pthread_cond_wait_nothread(self, mutex, abstime);
 
        pthread_spinlock(self, &cond->ptc_lock);
+       wait.ptw_thread = self;
+       wait.ptw_cond = cond;
+       retval = 0;
+       SDPRINTF(("(cond timed wait %p) Waiting on %p until %d.%06ld\n",
+           self, cond, abstime->tv_sec, abstime->tv_nsec/1000));
+
+       pthread_spinlock(self, &self->pt_statelock);
+       if (__predict_false(self->pt_cancel)) {
+               pthread_spinunlock(self, &self->pt_statelock);
+               pthread_spinunlock(self, &cond->ptc_lock);
+               pthread_exit(PTHREAD_CANCELED);
+       }
 #ifdef ERRORCHECK
        if (cond->ptc_mutex == NULL)
                cond->ptc_mutex = mutex;
@@ -196,18 +215,6 @@
                    cond->ptc_mutex == mutex);
 #endif
        
-       wait.ptw_thread = self;
-       wait.ptw_cond = cond;
-       retval = 0;
-       SDPRINTF(("(cond timed wait %p) Waiting on %p until %d.%06ld\n",
-           self, cond, abstime->tv_sec, abstime->tv_nsec/1000));
-
-       pthread_spinlock(self, &self->pt_statelock);
-       if (self->pt_cancel) {
-               pthread_spinunlock(self, &self->pt_statelock);
-               pthread_spinunlock(self, &cond->ptc_lock);
-               pthread_exit(PTHREAD_CANCELED);
-       }
        pthread__alarm_add(self, &alarm, abstime, pthread_cond_wait__callback,
            &wait);
        self->pt_state = PT_STATE_BLOCKED_QUEUE;
@@ -229,7 +236,15 @@
        SDPRINTF(("(cond timed wait %p) %s\n",
            self, (retval == ETIMEDOUT) ? "(timed out)" : ""));
        pthread_mutex_lock(mutex);
-       pthread__testcancel(self);
+       if (__predict_false(self->pt_cancel)) {
+#ifdef ERRORCHECK
+               pthread_spinlock(self, &cond->ptc_lock);
+               if (PTQ_EMPTY(&cond->ptc_waiters))
+                       cond->ptc_mutex = NULL;
+               pthread_spinunlock(self, &cond->ptc_lock);
+#endif         
+               pthread_exit(PTHREAD_CANCELED);
+       }
 
        return retval;
 }



Home | Main Index | Thread Index | Old Index