On Windows, sceKernelRaiseException threw for a thread created suspended
and not resumed yet. FreeBSD libthr starts such a thread with signals
blocked and restores its mask on resume, so the signal stays pending and
is delivered on that thread once it runs.
The raise is now recorded in the thread's pendingException with a
compare-exchange, and the thread exchanges it for -1 when it leaves the
creation wait and delivers it to itself before its start routine. Both
sides use one atomic, so a raise racing a resume is either taken by the
thread or, after it started, delivered as for a running thread. Raises
while pending are merged, as for a standard signal.
guest_pthread_create_suspended now runs the deferred-delivery case on
every host, with a second raise while the thread is suspended.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
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.