Files
AnyPS5/docs/dev
milescovielloandClaude Opus 5.5 953ae58bc8 fix(libkernel): hold back new rwlock readers while a writer waits
Guest rwlocks were a host std::shared_timed_mutex. On Linux that is a
glibc rwlock, which prefers readers: a reader is let in while a writer
is blocked, so a writer waiting on a lock that readers keep taking in
overlapping turns never gets it (a probe with four readers each holding
the lock for 4 ms still had scePthreadRwlockWrlock waiting after 5 s,
with 4924 read acquisitions meanwhile), and tryrdlock succeeds while a
writer waits.

FreeBSD 11.4 libthr gives waiting writers precedence. A rwlock starts
without URWLOCK_PREFER_READER (rwlock_init() callocs it), and
lib/libthr/thread/thr_umtx.h, _thr_rwlock_tryrdlock(), refuses a reader
while a writer waits:

	if ((flags & URWLOCK_PREFER_READER) != 0 ||
	    (rwlock->rw_flags & URWLOCK_PREFER_READER) != 0)
		wrflags = URWLOCK_WRITE_OWNER;
	else
		wrflags = URWLOCK_WRITE_OWNER | URWLOCK_WRITE_WAITERS;

as does do_rw_rdlock() in sys/kern/kern_umtx.c for the blocking wait.
The only exception is a thread that already holds a read lock, so that a
recursive read cannot deadlock (lib/libthr/thread/thr_rwlock.c,
rwlock_rdlock_common()):

	if (curthread->rdlock_count) {
	...
		flags = URWLOCK_PREFER_READER;

The rwlock is now a mutex and condition with a count of waiting writers:
a reader waits while a writer holds the lock or, unless the thread
already holds a read lock, while a writer waits; a timed writer that
gives up wakes the readers it held back. The TechnicalDebt note about
locking guest rwlocks once for winpthreads no longer applies to them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:43:43 +00:00
..