Main's #9573 implements scePthreadResume right after the
scePthreadMutexattrSetkind stub this branch removes from libkernel_sys;
the merge takes main's scePthreadResume and leaves the stub out.
Main's public-header audit wants one header declaration per export, so
the merge declares this branch's scePthreadMutexattrSetkind,
scePthreadMutexattrGetkind and pthread_rwlockattr_settype_np in
libkernel's Api.hpp, drops their stub declarations from libkernel_sys's
Api.hpp, has Mutex.cpp take sceKernelError from libkernel's Api.hpp,
and has the test include the libkernel headers instead of its own
declarations.
Implement pthread_attr_setcreatesuspend_np, pthread_resume_np,
pthread_resume_all_np and pthread_multi_np with the sce forms
scePthreadAttrSetcreatesuspend, scePthreadResume, scePthreadResumeAll
and scePthreadMulti, following FreeBSD 11.4 libthr and the firmware
13.42 libkernel_sys module. A thread created suspended waits before its
start routine, outside any cancellation point, until it is resumed.
sceKernelRaiseException throws on Windows for a thread still suspended
at creation.
scePthreadMutexTimedlock on a mutex the caller holds, and
scePthreadRwlockTimedrdlock and scePthreadRwlockTimedwrlock on a rwlock
it holds for writing, returned EDEADLK at once. The console returns
ETIMEDOUT, as the prosper console oracle measured. They now sleep until
the timeout and return ETIMEDOUT, as FreeBSD libthr does. The POSIX
timed locks call these and change with them.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Kept both sides of GuestLibcThreads.cpp: main's ThreadHelpers test and this PR's VersionedSync test, both called from main().
Co-Authored-By: Claude Opus 5.5 <[email protected]>
scePthreadCreate returns ENAMETOOLONG for a name of 32 bytes or more without creating the thread, and scePthreadDetach returns ESRCH for a joined thread.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
scePthreadRwlockattrSettype stored any type and threw on a null
attribute. Measured against firmware 13.42's libkernel by BunnyFl in
#9632, it is the same function as pthread_rwlockattr_settype_np with
the error converted to an SCE code: types 1 and 2 are stored and return
0, and any other type, 0 included, or a null attribute or object
returns SCE_KERNEL_ERROR_EINVAL and stores nothing.
BunnyFl measured these functions against firmware 13.42's libkernel and
libkernel_sys in the PR thread (behaviour only):
- pthread_rwlockattr_settype_np stores only types 1 and 2. Any other
type, 0 included, and a null attribute or object return EINVAL and
store nothing; type 0 was stored before.
- scePthreadMutexattrSetkind returns 0x8001FFFF, sceKernelError(-1), for
a null attribute or object instead of throwing. Kinds 1 to 4 are set as
before; other kinds still throw, since the firmware stores them
unchecked and a mutex's behaviour with them is not measured.
- scePthreadMutexattrGetkind takes the attribute itself and returns
sceKernelError of its kind, or 0x8001FFFF for a null one.
#9272 keeps liveStacks and protectedStackPages alive through static
destruction so that a late mprotect from an atexit handler can still
look up guest thread stacks. The mutex guarding them is still a static
std::mutex. libstdc++'s std::mutex has a trivial destructor, so it keeps
working on Linux, but libc++ destroys the pthread mutex, and a later lock
throws "mutex lock failed: Invalid argument": on macOS the exit probe of
guest_memory_lifetime fails at its mapping protection stage. The lock is
now allocated and never destroyed, like the maps.
The same change is part of #7201 and #8658.
Co-Authored-By: marion909 <[email protected]>
Co-Authored-By: iamthehimansh <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A null or uninitialized attribute, and a kind outside 1 to 4, threw
std::invalid_argument. They now go through NotImplemented_nid_no_patch,
as pthread_rwlockattr_settype_np's unmeasured types do. FreeBSD 11
libthr stores an unknown kind unchecked and answers a null attribute
with -1 and errno EINVAL, so scePthreadMutexattrSettype's
SCE_KERNEL_ERROR_EINVAL would match neither answer.
FreeBSD 11 libthr's pthread_condattr_setclock returns EINVAL for any clock
other than CLOCK_REALTIME, CLOCK_VIRTUAL, CLOCK_PROF and CLOCK_MONOTONIC.
scePthreadCondattrSetclock stored any clock id; it now answers
SCE_KERNEL_ERROR_EINVAL for the others, and pthread_condattr_setclock
EINVAL through it.
pthread_rwlockattr_settype_np stored any type and returned 0. The console's answer to a type outside 0 to 2 is unknown, and shadPS4 returns EINVAL once the stored type is above 2, so such a type now goes through NotImplemented_nid_no_patch. Types 0 to 2 are stored but not applied, so the debt entry moves to the silent stubs.
The SCE name moves from a libkernel_sys stub to libkernel. Kinds
MutexType::ErrorCheck (1) to MutexType::Adaptive (4) are the mutex
types FreeBSD 11 libthr's pthread_mutexattr_setkind_np stores, and are
set through scePthreadMutexattrSettype, which maps the same values onto
those types. Other kinds and a null or uninitialized attribute throw, as
their console answer is not known.
guest_kernel_sys_pthread_np_kind round-trips kinds 2, 3, 4 and 1
through pthread_mutexattr_gettype, checks that kind 1 makes a second
lock return EDEADLK and kind 2 lets it succeed, and checks the throws
for kinds 0, 5 and -1 (the type unchanged) and for a destroyed or null
attribute.
The POSIX name moves from a libkernel_sys stub to libkernel and stores the
type through its SCE twin scePthreadRwlockattrSettype, converting the
result as the other POSIX rwlock calls do.
guest_kernel_sys_pthread_np_rwlockattr checks types 0, 1 and 2 through
both names, a rwlock built from the attribute, and the throws for a
destroyed or null attribute.