diff --git a/libc/src/__support/threads/raw_rwlock.h b/libc/src/__support/threads/raw_rwlock.h index 9bc1b88cabd69..1b0bba9c72675 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 LIBC_INLINE FutexWordType &serialization() { + template 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,9 @@ class RawRwLock { // sleep on the futex, we can avoid such waiting. old = RwState::fetch_set_pending_bit(state, cpp::MemoryOrder::RELAXED); - // no need to use atomic since it is already protected by the mutex. - serial_number = guard.serialization(); + // relaxed atomic since it is already protected by the mutex. + serial_number = + guard.serialization().load(cpp::MemoryOrder::RELAXED); } // Phase 6: do futex wait until the lock is available or timeout is @@ -437,10 +438,12 @@ class RawRwLock { { WaitingQueue::Guard guard = queue.acquire(is_pshared); if (guard.pending_count() != 0) { - guard.serialization()++; + guard.serialization().fetch_add( + 1, cpp::MemoryOrder::RELEASE); status = WakeTarget::Writers; } else if (guard.pending_count() != 0) { - guard.serialization()++; + guard.serialization().fetch_add( + 1, cpp::MemoryOrder::RELEASE); status = WakeTarget::Readers; } else { status = WakeTarget::None;