about summary refs log tree commit diff
path: root/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog8
-rw-r--r--linuxthreads/internals.h1
-rw-r--r--linuxthreads/pthread.c2
-rw-r--r--linuxthreads/spinlock.c16
4 files changed, 20 insertions, 7 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index ab97529a83..dfb0e3d66a 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,11 @@
+1999-06-23  Robey Pointer  <robey@netscape.com>
+
+	* internals.h: Added p_nextlock entry to separate queueing for a
+	lock from queueing for a CV (sometimes a thread queues on a lock
+	to serialize removing itself from a CV queue).
+	* pthread.c: Added p_nextlock to initializers.
+	* spinlock.c: Changed to use p_nextlock instead of p_nextwaiting.
+
 1999-07-09  Ulrich Drepper  <drepper@cygnus.com>
 
 	* manager.c (pthread_handle_create): Free mmap region after stack
diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h
index db84707312..bcbfbcf5eb 100644
--- a/linuxthreads/internals.h
+++ b/linuxthreads/internals.h
@@ -74,6 +74,7 @@ struct _pthread_descr_struct {
   pthread_descr p_nextlive, p_prevlive;
                                 /* Double chaining of active threads */
   pthread_descr p_nextwaiting;  /* Next element in the queue holding the thr */
+  pthread_descr p_nextlock;	/* can be on a queue and waiting on a lock */
   pthread_t p_tid;              /* Thread identifier */
   int p_pid;                    /* PID of Unix process */
   int p_priority;               /* Thread priority (== 0 if not realtime) */
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index b7cf573fe9..c94e7e6f31 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -34,6 +34,7 @@ struct _pthread_descr_struct __pthread_initial_thread = {
   &__pthread_initial_thread,  /* pthread_descr p_nextlive */
   &__pthread_initial_thread,  /* pthread_descr p_prevlive */
   NULL,                       /* pthread_descr p_nextwaiting */
+  NULL,			      /* pthread_descr p_nextlock */
   PTHREAD_THREADS_MAX,        /* pthread_t p_tid */
   0,                          /* int p_pid */
   0,                          /* int p_priority */
@@ -75,6 +76,7 @@ struct _pthread_descr_struct __pthread_manager_thread = {
   NULL,                       /* pthread_descr p_nextlive */
   NULL,                       /* pthread_descr p_prevlive */
   NULL,                       /* pthread_descr p_nextwaiting */
+  NULL,			      /* pthread_descr p_nextlock */
   0,                          /* int p_tid */
   0,                          /* int p_pid */
   0,                          /* int p_priority */
diff --git a/linuxthreads/spinlock.c b/linuxthreads/spinlock.c
index c8f8f71293..ce6ff9e310 100644
--- a/linuxthreads/spinlock.c
+++ b/linuxthreads/spinlock.c
@@ -27,7 +27,7 @@
      1: fastlock is taken, no thread is waiting on it
   ADDR: fastlock is taken, ADDR is address of thread descriptor for
         first waiting thread, other waiting threads are linked via
-        their p_nextwaiting field.
+        their p_nextlock field.
    The waiting list is not sorted by priority order.
    Actually, we always insert at top of list (sole insertion mode
    that can be performed without locking).
@@ -50,8 +50,10 @@ void internal_function __pthread_lock(struct _pthread_fastlock * lock,
 	self = thread_self();
       newstatus = (long) self;
     }
-    if (self != NULL)
-      THREAD_SETMEM(self, p_nextwaiting, (pthread_descr) oldstatus);
+    if (self != NULL) {
+      ASSERT(self->p_nextlock == NULL);
+      THREAD_SETMEM(self, p_nextlock, (pthread_descr) oldstatus);
+    }
   } while(! compare_and_swap(&lock->__status, oldstatus, newstatus,
                              &lock->__spinlock));
   if (oldstatus != 0) suspend(self);
@@ -83,7 +85,7 @@ again:
       maxptr = ptr;
       maxprio = thr->p_priority;
     }
-    ptr = &(thr->p_nextwaiting);
+    ptr = &(thr->p_nextlock);
     thr = *ptr;
   }
   /* Remove max prio thread from waiting list. */
@@ -92,16 +94,16 @@ again:
        to guard against concurrent lock operation */
     thr = (pthread_descr) oldstatus;
     if (! compare_and_swap(&lock->__status,
-                           oldstatus, (long)(thr->p_nextwaiting),
+                           oldstatus, (long)(thr->p_nextlock),
                            &lock->__spinlock))
       goto again;
   } else {
     /* No risk of concurrent access, remove max prio thread normally */
     thr = *maxptr;
-    *maxptr = thr->p_nextwaiting;
+    *maxptr = thr->p_nextlock;
   }
   /* Wake up the selected waiting thread */
-  thr->p_nextwaiting = NULL;
+  thr->p_nextlock = NULL;
   restart(thr);
 }