[libc-commits] [libc] [libc][rwlock] fix the race condition in waiter queue (PR #201629)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Thu Jun 4 09:39:26 PDT 2026
https://github.com/SchrodingerZhu created https://github.com/llvm/llvm-project/pull/201629
None
>From 3c505266299bfe97241adf6dd337899b14d4aa94 Mon Sep 17 00:00:00 2001
From: Yifan Zhu <yfzhu at google.com>
Date: Thu, 4 Jun 2026 09:38:06 -0700
Subject: [PATCH] [libc][rwlock] fix the race condition in waiter queue
---
libc/src/__support/threads/raw_rwlock.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/libc/src/__support/threads/raw_rwlock.h b/libc/src/__support/threads/raw_rwlock.h
index 9bc1b88cabd69..e5b89c2ef7e6f 100644
--- a/libc/src/__support/threads/raw_rwlock.h
+++ b/libc/src/__support/threads/raw_rwlock.h
@@ -75,11 +75,11 @@ class WaitingQueue final : private RawMutex {
else
return queue.pending_writers;
}
- template <Role role> LIBC_INLINE FutexWordType &serialization() {
+ template <Role role> LIBC_INLINE Futex &serialization() {
if constexpr (role == Role::Reader)
- return queue.reader_serialization.val;
+ return queue.reader_serialization;
else
- return queue.writer_serialization.val;
+ return queue.writer_serialization;
}
friend WaitingQueue;
};
@@ -391,8 +391,8 @@ class RawRwLock {
// sleep on the futex, we can avoid such waiting.
old = RwState::fetch_set_pending_bit<role>(state,
cpp::MemoryOrder::RELAXED);
- // no need to use atomic since it is already protected by the mutex.
- serial_number = guard.serialization<role>();
+ // relaxed atomic since it is already protected by the mutex.
+ serial_number = guard.serialization<role>().load(cpp::MemoryOrder::RELAXED);
}
// Phase 6: do futex wait until the lock is available or timeout is
@@ -437,10 +437,10 @@ class RawRwLock {
{
WaitingQueue::Guard guard = queue.acquire(is_pshared);
if (guard.pending_count<Role::Writer>() != 0) {
- guard.serialization<Role::Writer>()++;
+ guard.serialization<Role::Writer>().fetch_add(1, cpp::MemoryOrder::RELEASE);
status = WakeTarget::Writers;
} else if (guard.pending_count<Role::Reader>() != 0) {
- guard.serialization<Role::Reader>()++;
+ guard.serialization<Role::Reader>().fetch_add(1, cpp::MemoryOrder::RELEASE);
status = WakeTarget::Readers;
} else {
status = WakeTarget::None;
More information about the libc-commits
mailing list