Commit Graph
81 Commits
Author SHA1 Message Date
Dean 72a848ca52 Merge pull request #4533 from Roojool/contrib/g07-pthread-getname
fix(libkernel): answer pthread_getname_np for a joined thread with ESRCH
2026-10-17 13:05:38 +13:00
Adrià 63b377b51b Merge pull request #5612 from JJenkx/feat/private-mutex-sharing
fix(libkernel): store mutex process-sharing attributes
2026-10-15 17:03:30 +02:00
Nixitov 4091519b04 feat(libkernel): implement rtprio_thread and the pthread concurrency controls
Morrowind imports rtprio_thread, pthread_setconcurrency and pthread_getconcurrency and stops at start-up. Report every guest thread as normal priority and accept a set without applying it; store the concurrency level as a hint. Recorded in the libkernel debt.
2026-10-14 16:23:12 +02:00
Rujul Talekar 7ef0931ffd fix(libkernel): answer pthread_getname_np for a joined thread with ESRCH 2026-10-14 10:59:48 +05:30
JJenkx bfa0de72cb fix(libkernel): retain shared mutex attributes 2026-10-13 23:13:51 -04:00
JJenkx 9bd29e4767 Merge commit '30f961266ade83b41d5c9de7dec1393e7fcecfb7' into feat/private-mutex-sharing 2026-10-13 18:59:59 -04:00
Dean ea2b2d364f Merge pull request #4514 from kallmek3nny/feat/libkernel-pthread-setaffinity
feat(libkernel): implement pthread_setaffinity_np
2026-10-14 10:20:33 +13:00
Dean 40047f46bd Merge pull request #4377 from MarcZX100/codex/carry-pthread-atfork-3628
feat(libkernel): implement pthread_atfork registration
2026-10-14 05:54:54 +13:00
screammandClaude Opus 5.5 74c3fb6576 feat(libkernel): implement pthread_setaffinity_np
PS5CEMU-HAR (PPSA99360, ps5-payload-dev build, relinks with
--trap-sdk-syscall-stubs) imports pthread_setaffinity_np (5KWrg7-ZqvE)
from libkernel.prx. babyhuey's run with #3787 merged onto main e7c70a2d
(PR #3787, 2026-10-12T10:54:44Z) stops at it:

  Windows: FAIL: unresolved ELF import 5KWrg7-ZqvE (pthread_setaffinity_np) from libkernel.prx
  Linux: undefined symbol: 5KWrg7-ZqvE (pthread_setaffinity_np)

It follows FreeBSD 11.4 libthr thr_affinity.c (8c639945) over
kern_cpuset_setaffinity: another thread is looked up first (EINVAL for
null, ESRCH when unknown or finished, as _thr_find_thread without dead
threads), a size other than the 32-byte cpuset_t returns ERANGE, the
mask is clipped to sceKernelGetAvailableCpumask and an empty result
returns EDEADLK, as cpuset_setaffinity does. The affinity is stored on
the guest thread through scePthreadSetaffinity, for the caller and for
any live guest thread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:39:07 +00:00
JJenkx 9258d2eba8 Merge current main into feat/private-mutex-sharing 2026-10-13 11:57:54 -04:00
Adrià 9c05bf25f5 Merge pull request #4585 from jagrat04/feat/libkernel-cpuset-affinity-errors-pr
feat(libkernel): return ESRCH and EINVAL for unsupported cpuset affinity targets
2026-10-13 17:23:01 +02:00
hugodearaujoandClaude Opus 5.5 5c6a9d22c4 fix(libkernel): check and keep the scheduling policy of a thread
On a PS5 (firmware 13.60) pthread_setschedparam and
scePthreadSetschedparam accept only SCHED_FIFO and SCHED_RR with a
priority of 256 to 767 or 896 to 959, return EINVAL otherwise, and
keep the policy for pthread_getschedparam. A created thread takes the
policy of explicit scheduling attributes, or its creator's when it
inherits. Here any policy and priority were accepted and SCHED_FIFO
was always reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:53:19 +02:00
jagrat Singh 9efabff1cb feat(libkernel): return ESRCH and EINVAL for unsupported cpuset affinity targets
Allow calling threads to query and set affinity using their own thread ID in addition to -1. Return ESRCH for non-matching thread or process IDs and EINVAL for invalid level/which arguments instead of throwing NotImplemented, matching FreeBSD cpuset semantics.
2026-10-13 15:58:11 +05:30
David e8fd542f03 feat(libkernel): implement pthread_atfork
pthread_atfork (U9t5kJAWPnA, aerolib) appends the prepare, parent and
child handlers to a process-wide list under a lock and returns 0, or
ENOMEM when the entry cannot be allocated, as FreeBSD 11.4's
_pthread_atfork does (lib/libthr/thread/thr_fork.c:78-100, freebsd-src
8c639945a44588f6cfdddfb057bb5aad88735da0). Null handlers are accepted;
FreeBSD's fork skips them. The handlers never run: fork
(libkernel_sys) throws and vfork is absent, so no child process is
created. The list is kept, in registration order, for a later fork
(PthreadAtforkHandlers_nid_no_patch); recorded in TechnicalDebt.

XPSemu (PPSA97358) calls it from a constructor, before main
(ZiZc3/XPSemu 8eec07b4, util/rcu.c:488-495):

    static void __attribute__((__constructor__)) rcu_init(void)
    {
        smp_mb_global_init();
    #ifdef CONFIG_POSIX
        pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_child);
    #endif
        rcu_init_complete();
    }

so a throwing export would stop the title before main. Predicted stop
removed (registry index 255, not run):
FAIL: unresolved ELF import U9t5kJAWPnA from libkernel.prx

guest_pthread_atfork checks registration order, null handlers,
concurrent registration from four threads and that no handler runs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit f37bccf6efd76edcde5d582800c89b83fdd30472)
2026-10-13 07:38:13 +00:00
JJenkx 05f2dc4c91 feat(libkernel): support process-private mutex sharing attributes 2026-10-12 12:22:44 -04:00
Dean 2a5eca11cd Merge pull request #4350 from milescoviello/fix/once-reset-on-exit
fix(libkernel): reset a once control when its initializer exits or is cancelled
2026-10-13 04:53:46 +13:00
Dean ddc713fbcf Merge pull request #4004 from zmeizy/claude/mutex-timedlock-try-first
fix(libkernel): try the lock before checking the pthread_mutex_timedl…
2026-10-13 02:34:16 +13:00
083c98a067 fix(libkernel): leave a once initializer's own cleanup handlers alone when it throws
pthread_once and scePthreadOnce removed their reset handler with a pop
that runs whatever handler is on top of the cleanup stack. An
initializer that pushed a handler of its own and then threw left that
handler on top, so the pop ran it with dangling state. Both now record
the stack top before pushing the reset handler; on a throw they restore
the stack to it and reset the control directly, and a normal return
restores it as well.

Reported in review by Hussein Kadhim, who fixed it the same way.

Co-authored-by: Hussein Kadhim <husseinkad.dev@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 07:49:09 +00:00
Dean abd73fbc0d Merge pull request #4002 from zmeizy/claude/barrier-destroy-after-release
fix(libkernel): let pthread_barrier_destroy wait for released waiters
2026-10-12 18:19:21 +13:00
Dean a18b088d39 Merge pull request #4005 from zmeizy/claude/posix-deadline-overflow
fix(libkernel): clamp POSIX deadlines beyond the clock range instead …
2026-10-12 16:12:38 +13:00
Dean d1758a91c8 Merge pull request #3494 from babyhuey/carry/pthread-attr-scope-3377
feat(libkernel): implement pthread_attr_getscope, setscope, getinheritsched and getstackaddr
2026-10-12 15:33:56 +13:00
Adrià 6426baa107 Merge pull request #3691 from MarcZX100/fix/sem-timedwait-available-first
fix(libkernel): handle available sem_timedwait counts first
2026-10-12 00:35:17 +02:00
Adrià 5aaf26bd32 Merge pull request #3689 from MarcZX100/codex/libkernel-spin-reltimedwait-3554
feat(libkernel): implement pthread spinlocks and relative condition wait
2026-10-12 00:23:53 +02:00
MarcZX100andmilescoviello 8935160160 fix(libkernel): handle available sem_timedwait counts first
Co-authored-by: milescoviello <kitslayer29@gmail.com>
2026-10-11 23:54:18 +02:00
David 774f21845d feat(libkernel): implement pthread_cond_reltimedwait_np
Add pthread_cond_reltimedwait_np (K953PF5u6Pc; computed with
tools/nid_names.py and matching aerolib.csv) as scePthreadCondTimedwait
with POSIX error numbers: ETIMEDOUT when the relative timeout expires,
EPERM when the caller does not hold the mutex, and the mutex held again on
return in every waiting case.

Titles: Porpoise PPSA99764 and RetroArch PPSA99169 import it.
Predicted from relink registry order, not observed: Porpoise stops with
"FAIL: unresolved ELF import K953PF5u6Pc from libkernel.prx" (registry
index 384; RetroArch index 490). No call site is resolved in the registry.

The third argument is a relative timeout in microseconds, not a
struct timespec. FreeBSD 11.4 libthr (8c639945a44588f6cfdddfb057bb5aad88735da0)
has no such function. shadPS4 (3a9f57265d28975658f1ca941daa5c879c7a74bd,
src/core/libraries/kernel/threads/condvar.cpp:229-234, 445, 467-468)
registers posix_pthread_cond_reltimedwait_np(cond, mutex, u64 usec) for this
NID and the same function for scePthreadCondTimedwait (BmMjYxmew1w), whose
microsecond argument this repository already implements. The width follows
the SCE twin's 32-bit SceKernelUseconds, as sem_reltimedwait_np does, not
shadPS4's u64. There is no timespec to validate, so no EINVAL case.
Recorded in TechnicalDebt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit c86ec8417d12f5b12136b0f06eae06493b0e7a62)
2026-10-11 23:53:37 +02:00
David 092f7ef00a feat(libkernel): implement the pthread spinlock calls
Add pthread_spin_init (ZMn3clnAGBA), pthread_spin_destroy (IJIggoPZExk),
pthread_spin_lock (pw+70ClLYlY), pthread_spin_trylock (rCTGkBIHfPY) and
pthread_spin_unlock (LEfMMCT+SlM). The NIDs were computed with
tools/nid_names.py and match aerolib.csv. libkernel has no scePthreadSpin*
twin in aerolib, so the calls are implemented directly, like the barrier.

Titles: Porpoise PPSA99764 and RetroArch PPSA99169 import pthread_spin_lock.
Predicted from relink registry order, not observed: after
pthread_cond_reltimedwait_np, Porpoise stops with
"FAIL: unresolved ELF import pw+70ClLYlY from libkernel.prx" (registry
index 387; RetroArch index 493). No call site is resolved in the registry.

Behaviour follows FreeBSD 11.4 libthr thr_pspinlock.c and thr_umtx.h
(8c639945a44588f6cfdddfb057bb5aad88735da0). The guest pthread_spinlock_t
holds a pointer to an allocated lock. EINVAL for a null or destroyed lock and
for a pshared other than PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED,
EBUSY from trylock while any thread holds the lock, EPERM from unlock by a
thread that does not hold it. libthr spins forever when the holder locks
again; that call throws here. A shared lock is allocated like a private one,
since guest code runs in one process. Recorded in TechnicalDebt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 13ebf7f926fa2ee1c825cb1fcf18451a8781c045)
2026-10-11 23:53:36 +02:00
pushkarreddyy 324669722e feat(libkernel): implement pthread_attr_getstackaddr 2026-10-11 17:45:35 -04:00
pushkarreddyy 91bfd6a18c feat(libkernel): implement pthread_attr_getinheritsched, pthread_attr_getscope and pthread_attr_setscope 2026-10-11 17:45:17 -04:00
milescovielloandClaude Opus 5.5 3ba4532352 fix(libkernel): reset a once control when its initializer exits or is cancelled
pthread_once and scePthreadOnce marked the control as running, called
the initializer and marked the control done only after it returned. A
thread that left the initializer through pthread_exit or a
cancellation point never came back, so the control stayed in progress
and every later call on it waited forever.

FreeBSD libthr runs the initializer under a cleanup handler
(lib/libthr/thread/thr_once.c, _pthread_once:
"THR_CLEANUP_PUSH(curthread, once_cancel_handler, once_control);
init_routine(); THR_CLEANUP_POP(curthread, 0);"). once_cancel_handler
stores ONCE_NEVER_DONE and wakes the waiters, and thread exit and
cancellation run the cleanup handlers. POSIX requires this for
cancellation: "if init_routine is a cancellation point and is canceled,
the effect on once_control shall be as if pthread_once() was never
called."

Both functions now push such a handler around the initializer, so the
control returns to its initial state and the next caller, or one
already waiting, runs the initializer. scePthreadOnce waiters now retry
when the control goes back to its initial state, and an exception from
its initializer resets the control as it already did for pthread_once.
CleanupHandler moves to Cancel.hpp so that Once.cpp can use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:30:23 +00:00
Claude e463c5d11f fix(libkernel): clamp POSIX deadlines beyond the clock range instead of overflowing
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
2026-10-11 21:01:57 +00:00
Claude 74d44b8e6c fix(libkernel): try the lock before checking the pthread_mutex_timedlock deadline
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
2026-10-11 21:00:30 +00:00
Claude 602a76fc26 fix(libkernel): let pthread_barrier_destroy wait for released waiters
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
2026-10-11 20:57:22 +00:00
Semir Kabir 2124cfba5f feat(libkernel): report the process affinity from cpuset_getaffinity 2026-10-11 16:43:36 +00:00
Adrià fd1a66cab6 Merge pull request #3484 from AchrafReyani/feat/libkernel-pthread-mutexattr-gettype
feat(libkernel): implement pthread_mutexattr_gettype
2026-10-11 13:53:23 +02:00
Adrià 97fbc7e629 Merge pull request #3447 from sypher69/fix/thread-process-affinity-inheritance
fix(libkernel): inherit process affinity in new guest threads
2026-10-11 13:44:45 +02:00
Achraf ReyaniandClaude Opus 5.5 466c86255f feat(libkernel): implement pthread_mutexattr_gettype
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:05:46 +09:00
Dani 21f4be11ad fix(libkernel): inherit process affinity in new guest threads 2026-10-11 12:44:26 +02:00
Hannah Lyons 2741e96172 feat(libkernel): implement pthread_getthreadid_np 2026-10-11 06:38:14 -04:00
Ramzi 45eb492335 feat(libkernel): implement pthread_getaffinity_np
Report the thread's affinity mask as a 32-byte FreeBSD cpuset_t, with
FreeBSD 11's errors: ERANGE for any other set size, ESRCH for a null
thread and EFAULT for a null set.

EVO-PLAYER (PPSA99039 v0.11.0) imports it (Jb2uGFMr688) and calls it
once with a 32-byte set on pthread_self().
2026-10-11 10:23:50 +02:00
Scott SchusterandClaude Opus 5.5 bb4b938e34 feat(libkernel): implement cpuset_setaffinity for the calling thread or process
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:31:57 -05:00
Dean 90f26c996c Merge pull request #3031 from TheAggie/feat/libkernel-pthread-set-name-np
feat(libkernel): implement pthread_set_name_np
2026-10-11 18:40:30 +13:00
DavidandClaude Fable 5.1 064f5ca825 feat(libkernel): implement pthread_attr_setsolosched_np
The POSIX alias takes (attr, int), returns EINVAL (22) for a null or
uninitialized attribute like the other pthread_attr setters, and
stores the value through scePthreadAttrSetsolosched, returning its
result in errno form. The signature and the stored int follow the SCE
twin in KytyPS5 and sharpemu; PS5PCEM implements the alias the same
way. The value is not applied to scheduling, recorded in TechnicalDebt.

Returnal (PPSA01285 v03.000.005) stops on it after eager binding
(#2872, #1155):

    what(): pthread_attr_setsolosched_np_nid_postfix not implemented

LEGO Horizon Adventures (PPSA14632, #734) and Palworld (PPSA23126,
#2598) import it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 02:06:30 +02:00
Adrià dc105f8abf Merge pull request #2973 from babyhuey/feat/libkernel-rwlockattr
feat(libkernel): implement pthread_rwlockattr_init and pthread_rwlockattr_destroy
2026-10-10 23:53:36 +02:00
Scott SchusterandClaude Opus 5.5 ce98a61a83 feat(libkernel): implement pthread_set_name_np
pthread_set_name_np renames through scePthreadRename; a null name clears it,
as in FreeBSD.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 15:41:36 -05:00
Dean 0ed05471e5 Merge pull request #2899 from MarcZX100/codex/mutexattr-prioceiling-2689
feat(libkernel): implement mutex priority ceiling attributes
2026-10-11 09:02:05 +13:00
Hannah Lyons 5a43c9b0b9 feat(libkernel): implement pthread_rwlockattr_init and pthread_rwlockattr_destroy 2026-10-10 15:07:43 -04:00
ps54all 08728f95b9 feat(libkernel): implement pthread_mutexattr_setprioceiling and getprioceiling
The mutex attribute now keeps its protocol and priority ceiling the way
FreeBSD's libthr does: the ceiling can be set and read only under
PTHREAD_PRIO_PROTECT (EINVAL otherwise), and setting a protocol resets it
to the highest SCHED_RR priority. Mutexes still do not apply priority
protection; that is listed as a silent stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit d10c024f8f)
2026-10-10 18:12:31 +00:00
Hannah Lyons d2c160be76 feat(libkernel): implement cpuset_getaffinity for the calling thread 2026-10-10 12:40:56 -04:00
Nicolas Abosch ef9d0dd7d2 chore(libkernel): drop the pthread_cancel comment 2026-10-10 11:32:09 +02:00
Nicolas Abosch 3acca27f27 feat(libkernel): implement thread cancellation
scePthreadCancel and pthread_cancel threw, scePthreadTestcancel did
nothing and the cleanup handler exports did not exist.

A cancel request is now recorded on the thread and acted on at
scePthreadTestcancel, the condition variable waits, scePthreadSem and
sem waits, scePthreadJoin and the sleeps, and under their POSIX names.
A thread blocked in one of the waits is woken; a condition wait takes
its mutex back before the thread exits. The thread exits with
PTHREAD_CANCELED through scePthreadExit, which now runs the handlers
of __pthread_cleanup_push_imp and __pthread_cleanup_pop_imp.
scePthreadSetcancelstate and scePthreadSetcanceltype reject unknown
values, and pthread_setcanceltype is added.

Constants, the handler node layout and the order of events follow
FreeBSD libthr. A sleep is not interrupted, file and socket calls are
not cancellation points and the asynchronous type acts like the
deferred one except at the two set calls (TechnicalDebt). New test:
guest_pthread_cancel.
2026-10-10 11:32:09 +02:00