Skip to content

feat(libkernel): implement pthread spinlocks and relative condition wait - #3689

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
MarcZX10:codex/libkernel-spin-reltimedwait-3554
Oct 11, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
MarcZX10:codex/libkernel-spin-reltimedwait-3554

Conversation

@MarcZX10

Copy link
Copy Markdown
Contributor

What

Implement the POSIX pthread spinlock family and pthread_cond_reltimedwait_np in libkernel, carrying David's two commits from issue #3554 with his commit authorship preserved.

  • Spinlock initialization, destruction, lock, trylock, and unlock follow FreeBSD 11.4 libthr's owner checks and error results. Process-shared locks use process-local storage because guest code runs in one host process.
  • pthread_cond_reltimedwait_np forwards the relative timeout to scePthreadCondTimedwait and translates the SCE result to POSIX error numbers. The timeout unit/signature is inferred from shadPS4; console behavior remains unverified and is recorded in TechnicalDebt.
  • Tests cover lock ownership/errors, mutual exclusion across two threads, relative timeout and signal wakeup, and mutex ownership after each wait result.

Tested

  • Linux, GCC 12.2, Release: built libkernel, guest_pthread_spin_tests, and guest_cond_timedwait_tests successfully.
  • CTest guest_pthread_spin and guest_cond_timedwait passed 3 consecutive runs (6/6).
  • python3 tools/check_conventions.py --base upstream/main and git diff --check passed.
  • The source issue author reports Windows 11 / WinLibs GCC 15.2.0 focused tests; @blawesom independently reports Linux GCC 16.2.1 full-suite results on the source branch. Those reports are documented in libkernel: pthread spinlocks and pthread_cond_reltimedwait_np are absent (Porpoise, RetroArch); fix branch ready #3554; this PR's local validation is the Linux/GCC 12.2 run above.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

Closes #3554.

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Progress report (df64fa9 → 774f218)

📈 System libraries: 85.96% (+0.02%, +6 implemented functions)

✅ 6 implemented
Library Name
libkernel pthread_cond_reltimedwait_np_nid_postfix
libkernel pthread_spin_destroy_nid_postfix
libkernel pthread_spin_init_nid_postfix
libkernel pthread_spin_lock_nid_postfix
libkernel pthread_spin_trylock_nid_postfix
libkernel pthread_spin_unlock_nid_postfix

David and others added 2 commits October 11, 2026 23:53
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 13ebf7f)
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 c86ec84)
@adriadam10

Copy link
Copy Markdown
Collaborator

Rebased onto current main: the only conflict was the TechnicalDebt.md line adjacency (both lines kept). Rebuilt libkernel; guest_pthread_spin and guest_cond_timedwait pass on the rebased tree. Merging.

@adriadam10
adriadam10 force-pushed the codex/libkernel-spin-reltimedwait-3554 branch from 00e9aad to 774f218 Compare October 11, 2026 21:56
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 11, 2026
@adriadam10
adriadam10 merged commit 5aaf26b into boykopovar:main Oct 11, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

libkernel: pthread spinlocks and pthread_cond_reltimedwait_np are absent (Porpoise, RetroArch); fix branch ready

2 participants