From ec2db4e40e9ab05ff697e0d9b37209aa70179137 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 24 Dec 2024 10:30:11 -0800 Subject: [PATCH] Avoid pthread_rwlock_wrlock() starvation --- libc/thread/pthread_rwlock_rdlock.c | 3 +++ libc/thread/pthread_rwlock_wrlock.c | 2 ++ libc/thread/thread.h | 1 + 3 files changed, 6 insertions(+) diff --git a/libc/thread/pthread_rwlock_rdlock.c b/libc/thread/pthread_rwlock_rdlock.c index 743c84924..e097bb0ef 100644 --- a/libc/thread/pthread_rwlock_rdlock.c +++ b/libc/thread/pthread_rwlock_rdlock.c @@ -42,6 +42,9 @@ errno_t pthread_rwlock_rdlock(pthread_rwlock_t *lk) { for (;;) if (~(w = atomic_load_explicit(&lk->_word, memory_order_relaxed)) & 1) break; + // xxx: avoid writer starvation in pthread_rwlock_rdlock_test + while (atomic_load(&lk->_waiters)) + pthread_yield_np(); if (atomic_compare_exchange_weak_explicit( &lk->_word, &w, w + 2, memory_order_acquire, memory_order_relaxed)) return 0; diff --git a/libc/thread/pthread_rwlock_wrlock.c b/libc/thread/pthread_rwlock_wrlock.c index 0120a80a0..382eba828 100644 --- a/libc/thread/pthread_rwlock_wrlock.c +++ b/libc/thread/pthread_rwlock_wrlock.c @@ -42,8 +42,10 @@ errno_t pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) { if (atomic_compare_exchange_weak_explicit( &rwlock->_word, &w, 1, memory_order_acquire, memory_order_relaxed)) return 0; + atomic_fetch_add(&rwlock->_waiters, 1); for (;;) if (!(w = atomic_load_explicit(&rwlock->_word, memory_order_relaxed))) break; + atomic_fetch_sub(&rwlock->_waiters, 1); } } diff --git a/libc/thread/thread.h b/libc/thread/thread.h index 15952c2a7..f45d88095 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -111,6 +111,7 @@ typedef struct pthread_rwlock_s { char _pshared; char _iswrite; _PTHREAD_ATOMIC(uint32_t) _word; + _PTHREAD_ATOMIC(uint32_t) _waiters; }; }; } pthread_rwlock_t;