This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

rwlocks writer preference patch


Hi,

The 2.1.3 implementation of rwlocks (and the current CVS, FWIW)
still allows for excessive starvation for writers, no matter
if writer preference is set. The attached patch makes a waiting
writer the owner of the lock upon wakeup.

Regards,
-velco

PS. Joel, note this hunk from the patch, this bug is already fixed in
the CVS, but you might still want to add it to the Debian patches
(along with the rest).

@@ -362,7 +364,8 @@
 	}
       rwlock->__rw_writer = NULL;
 
-      if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
+      if ((rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
+	   && !queue_is_empty(&rwlock->__rw_read_waiting))
 	  || (th = dequeue (&rwlock->__rw_write_waiting)) == NULL)
 	{
 	  /* Restart all waiting readers.  */

-velco
--- rwlock.c~	Fri Jan 21 01:40:19 2000
+++ rwlock.c	Thu Nov  9 10:39:37 2000
@@ -313,7 +313,9 @@
   while(1)
     {
       __pthread_lock (&rwlock->__rw_lock, self);
-      if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL)
+      if (rwlock->__rw_readers == 0
+	  && (rwlock->__rw_writer == NULL
+	      || rwlock->__rw_writer == self))
 	{
 	  rwlock->__rw_writer = self;
 	  __pthread_unlock (&rwlock->__rw_lock);
@@ -362,7 +364,8 @@
 	}
       rwlock->__rw_writer = NULL;
 
-      if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
+      if ((rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
+	   && !queue_is_empty(&rwlock->__rw_read_waiting))
 	  || (th = dequeue (&rwlock->__rw_write_waiting)) == NULL)
 	{
 	  /* Restart all waiting readers.  */
@@ -375,6 +378,7 @@
       else
 	{
 	  /* Restart one waiting writer.  */
+	  rwlock->__rw_writer = th;
 	  __pthread_unlock (&rwlock->__rw_lock);
 	  restart (th);
 	}
@@ -390,8 +394,11 @@
 
       --rwlock->__rw_readers;
       if (rwlock->__rw_readers == 0)
-	/* Restart one waiting writer, if any.  */
-	th = dequeue (&rwlock->__rw_write_waiting);
+	{
+	  /* Restart one waiting writer, if any.  */
+	  th = dequeue (&rwlock->__rw_write_waiting);
+	  rwlock->__rw_writer = th;
+	}
       else
 	th = NULL;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]