[PATCH RFC] nptl: On read lock timeout for a rwlock, wake up pending readers

Florian Weimer fweimer@redhat.com
Mon Sep 21 15:01:49 GMT 2026


I've been looking at a nptl/tst-rwlock9 failure.  So far, I've not been
able to reproduce this outside of our build system.

LLMs however identified that unregistration upon timeout during rdlock
does not wake up other readers, so that they can complete their
registration.  I wrote the patch below (based on
__pthread_rwlock_rdunlock) to cover this gap.

Do you think this fixes an actual bug?

Thanks,
Florian
---
 nptl/pthread_rwlock_common.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
index 9b0b528298..295a5fbfc1 100644
--- a/nptl/pthread_rwlock_common.c
+++ b/nptl/pthread_rwlock_common.c
@@ -467,13 +467,27 @@ __pthread_rwlock_rdlock_full64 (pthread_rwlock_t *rwlock, clockid_t clockid,
 	      r = atomic_load_relaxed (&rwlock->__data.__readers);
 	      while ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
 		{
+		  /* If we are the last reader, we also need to
+		     unblock any readers that are waiting for a writer
+		     to go first (PTHREAD_RWLOCK_RWAITING) so that
+		     they can register while the writer is active.
+		     See __pthread_rwlock_rdunlock above.  */
+		  unsigned int rnew = r - (1 << PTHREAD_RWLOCK_READER_SHIFT);
+		  if ((rnew >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
+		    rnew &= ~(unsigned int) PTHREAD_RWLOCK_RWAITING;
+
 		  /* We don't need to make anything else visible to
 		     others besides unregistering, so relaxed MO is
 		     sufficient.  */
 		  if (atomic_compare_exchange_weak_relaxed
-		      (&rwlock->__data.__readers, &r,
-		       r - (1 << PTHREAD_RWLOCK_READER_SHIFT)))
-		    return err;
+		      (&rwlock->__data.__readers, &r, rnew))
+		    {
+		      if ((r & PTHREAD_RWLOCK_RWAITING)
+			  != (rnew & PTHREAD_RWLOCK_RWAITING))
+			futex_wake (&rwlock->__data.__readers, INT_MAX,
+				    private);
+		      return err;
+		    }
 		  /* TODO Back-off.  */
 		}
 	      /* Use the acquire MO fence to mirror the steps taken in the

base-commit: adb18e934774ab454b244077d3123206d2e893c6



More information about the Libc-alpha mailing list