UFC 6 (PPSA23566) passes type 0 to pthread_mutexattr_settype during
startup. libkernel rejects it with EINVAL and leaves the attribute
unchanged, as fpPS4's decompiled body does, instead of aborting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The PS5 libthr (FreeBSD) creates error-checking mutexes by default and has
PTHREAD_MUTEX_ADAPTIVE_NP (type 4); relocking an error-checking or adaptive
mutex returns EDEADLK. Default mutexes were Normal and type 4 was mapped to
Normal, so a relock threw instead of returning EDEADLK, which aborted an
Unreal Engine title's recursive directory scan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scePthreadMutexattrSetprotocol threw for SCE_PTHREAD_PRIO_INHERIT, so a
title creating its mutexes with priority inheritance stopped at the
first one.
Guest thread priorities are recorded (scePthreadSetprio/Getprio) but
never applied to host scheduling, so there is no priority for a waiter
to lend to the owner: an inheriting mutex locks, unlocks and reports
errors exactly like a PRIO_NONE one here, and the protocol is accepted.
The POSIX pthread_mutexattr_setprotocol wrapper already accepts it.
Priority protection (PRIO_PROTECT, with its ceilings) and unknown
protocols still throw.
SCE kernel errors are 0x80020000 plus the FreeBSD errno. The equeue and
direct memory constants used an unrelated 0x8001xxxx range with mismatched
errno values (e.g. ETIMEDOUT was 0x80010023), so a guest checking
sceKernelWaitEqueue for SCE_KERNEL_ERROR_ETIMEDOUT saw an unexpected error.
SCE_KERNEL_ERROR_EDEADLK in Mutex.cpp held the EAGAIN value.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>