The last waiter to leave RwlockLock cleared the waiter bit outside the
bucket lock. If a new waiter published that same bit and incremented
the blocked count in the window between the decrement and the clear,
the clear erased its bit and a later unlock woke nobody. Re-check the
blocked count after clearing and restore the bit if a waiter appeared
in that window.
ConditionWaitRejectsAPriorityProtectedMutexWithoutLeakingAWaiter also
required the priority-protected wait to throw; a condition wait on
such a mutex is a valid, merely unsupported form, so only the queue
cleanliness is asserted now. Extended the rwlock stress test to 8
threads and more, shorter rounds to give the window more chances to
show up.
Depends on: none
RwlockLock set its waiter bit unconditionally after deciding the lock
was unheld, so an unlock landing in that window woke nobody and the
waiter published its bit onto an already-free lock and slept forever.
Set the bit with a CAS against the value just checked, retrying the
freedom check on failure, as the mutex path already does for
UMUTEX_CONTESTED.
ConditionWait queues its stack waiter and drops the bucket lock before
calling MutexUnlock; MutexUnlock throws for a priority-protected
umutex, which unwound past the cleanup that removes the queue entry,
leaving a dangling pointer for a later ConditionWake to use. Reject
the unsupported mutex before the waiter is queued.
Depends on: none
Follow FreeBSD 11's do_sem_wait and do_sem_wake (COMPAT_FREEBSD9/10) on
a struct _usem: a wait sets _has_waiters, returns at once while _count
is non-zero and otherwise sleeps on the semaphore's queue; a wake clears
_has_waiters when one waiter is left and releases one waiter.
Co-Authored-By: Claude Haiku 5.5 <[email protected]>
Operation 1 threw as unverified, so a title whose call_once path reaches it
stopped. In a payload process on a PS5 (firmware 12.70) operations 0 and 1
fail with EOPNOTSUPP and leave the word unchanged for every word tried,
as FreeBSD 11's __umtx_op_unimpl does. Answer operation 1 like operation 0.
Titles that ship their own libc.prx or Unity's PS5Util.prx import
_umtx_op (04AjkP0jO9U) for atomic waits, call_once and futex-style
waits. Implement UMTX_OP_WAIT, UMTX_OP_WAKE, UMTX_OP_WAIT_UINT,
UMTX_OP_WAIT_UINT_PRIVATE and UMTX_OP_WAKE_PRIVATE as FreeBSD 11's
kern_umtx.c does, on the sceKernelSyncOnAddressWait waiter queue.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HeC9bA3n74TzJRYv9AgBE8