Skip to content

fix(libkernel): time out timed locks of a lock the caller already holds - #9165

Open
MaxLikesCode wants to merge 1 commit into
boykopovar:mainfrom
MaxLikesCode:fix/pthread-timed-self-lock
Open

MaxLikesCode wants to merge 1 commit into
boykopovar:mainfrom
MaxLikesCode:fix/pthread-timed-self-lock

Conversation

@MaxLikesCode

@MaxLikesCode MaxLikesCode commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

What

A timed lock of a lock the caller already holds now waits out its timeout and returns ETIMEDOUT, instead of returning EDEADLK at once:

  • scePthreadMutexTimedlock on a non-recursive mutex the caller holds.
  • scePthreadRwlockTimedrdlock and scePthreadRwlockTimedwrlock on a rwlock the caller holds for writing.

The untimed scePthreadMutexLock, scePthreadRwlockRdlock and scePthreadRwlockWrlock still return EDEADLK.

Where the behaviour comes from:

  • Console measurement. The prosper console oracle measured ETIMEDOUT (0x8002003c) after a 1000 us timeout for a default mutex and for both rwlock calls (mutex, rwlock). Only the result was measured, not whether the console waited.
  • FreeBSD 11.4 libthr. mutex_self_lock sleeps until the deadline and returns ETIMEDOUT for error-checking, adaptive and normal mutexes (thr_mutex.c L878-L928). The rwlock locks have no deadlock check and wait in the kernel (thr_rwlock.c L159-L329). So the calls here sleep until the timeout too.

The POSIX pthread_mutex_timedlock, pthread_mutex_reltimedlock_np, pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock call these functions and change with them. Two tests expected EDEADLK from them, which no measurement or FreeBSD source supports:

  • guest_pthread_rwlock, from the POSIX timed rwlock locks. It now expects ETIMEDOUT, and its 5 s deadline is now 20 ms, since the call really waits.
  • guest_pthread_mutex_errors, from pthread_mutex_reltimedlock_np on a mutex the caller holds (added in feat(libkernel): add mutex ownership, relative lock and spin/yield accessors #8400, which describes that function as scePthreadMutexTimedlock with POSIX error numbers). It now expects ETIMEDOUT after its 1000 us timeout.

The adaptive and normal mutex types and the POSIX names were not measured; docs/dev/debt/libkernel.md says so.

Tested

  • Windows 11 Pro 26200, WinLibs GCC 15.2.0 r7, full Release build with BUILD_TESTING=ON, on main 1b5d702.
  • guest_kernel_errors passes with new cases: a timed lock of an error-checking, adaptive, default and normal mutex the caller holds, and both timed rwlock locks while the caller holds the write lock. Each returns ETIMEDOUT after at least 15 ms of a 20 ms timeout, and the lock is taken normally once released. It fails without the changes to Mutex.cpp and Rwlock.cpp. guest_kernel_errors, guest_pthread_rwlock, guest_pthread_mutex_errors and guest_pthread_timed_locks pass 3 of 3.
  • python tools/select_tests.py ctest build --output-on-failure --timeout 120 --parallel 4: on main 1b5d702 all 739 selected tests outside agc_ pass. A run of all 1517 selected tests one rebase earlier, on main 47fa6ee, passed 1514; the 3 failures were agc_driver_sample_order, agc_driver_sample_order_grid_reference and agc_driver_sample_order_recipe_depth_locations from fix(agc): keep the guest's sample order where pixel (0,0)'s locations stand in for a 2x2 grid #6683, which fail with the same messages on that main on this RTX 4090. agc_driver_image_array_window_past_layer_limit is not built: it does not compile with MinGW on main (test(agc): align the array window test's texels at run time #8310).
  • python tools/check_conventions.py --base origin/main passes. python tools/pr_overlap.py --branch fix/pthread-timed-self-lock reports no open PR changing the same lines or exports.
  • Linux: @xXPBSXx ran it on WSL2 Ubuntu 24.04 (GCC 13.3.0, Release) at 3959305a27: guest_pthread_mutex_errors, guest_pthread_rwlock and guest_kernel_errors pass 3 of 3, and all three fail with Mutex.cpp and Rwlock.cpp restored to the merge base.
  • Not tested: a console, a title or homebrew.

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 under Silent stubs in their library's technical debt file
  • 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
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes. Written with Claude Code (Claude Opus 5.5).

🤖 Generated with Claude Code

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 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 10177 docs/dev/debt/libkernel.md L64-65

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 4630 docs/dev/debt/libkernel.md
PR 5021 docs/dev/debt/libkernel.md
PR 6044 core/libs/tests/GuestKernelErrors.cpp
core/libs/tests/GuestPthreadMutexErrors.cpp
core/libs/tests/GuestPthreadRwlock.cpp
PR 6149 docs/dev/debt/libkernel.md
PR 6740 docs/dev/debt/libkernel.md
PR 6830 docs/dev/debt/libkernel.md
PR 6936 docs/dev/debt/libkernel.md
PR 7049 docs/dev/debt/libkernel.md
PR 7088 docs/dev/debt/libkernel.md
PR 7105 docs/dev/debt/libkernel.md
PR 7121 docs/dev/debt/libkernel.md
PR 7149 docs/dev/debt/libkernel.md
PR 7509 docs/dev/debt/libkernel.md
PR 7511 docs/dev/debt/libkernel.md
PR 7653 docs/dev/debt/libkernel.md
PR 8010 docs/dev/debt/libkernel.md
PR 8520 docs/dev/debt/libkernel.md
PR 8553 docs/dev/debt/libkernel.md
PR 9074 docs/dev/debt/libkernel.md
PR 9123 docs/dev/debt/libkernel.md
PR 9133 docs/dev/debt/libkernel.md
PR 9156 docs/dev/debt/libkernel.md
PR 9160 docs/dev/debt/libkernel.md
PR 9199 docs/dev/debt/libkernel.md
PR 9284 docs/dev/debt/libkernel.md
PR 9293 docs/dev/debt/libkernel.md
PR 9297 docs/dev/debt/libkernel.md
PR 9302 docs/dev/debt/libkernel.md
PR 9557 docs/dev/debt/libkernel.md
PR 9561 docs/dev/debt/libkernel.md
PR 9566 docs/dev/debt/libkernel.md
PR 9575 docs/dev/debt/libkernel.md
PR 9669 docs/dev/debt/libkernel.md
PR 9693 docs/dev/debt/libkernel.md
PR 10319 docs/dev/debt/libkernel.md

@xXPBSXx

xXPBSXx commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Linux data point for 3959305a27: WSL2 Ubuntu 24.04 (virtualised kernel, not bare-metal Linux), GCC 13.3.0, Release, BUILD_TESTING=ON, PR head alone (not merged onto main; its merge-base is 1b5d7021a).

  • With the PR: ctest -R '^(guest_pthread_mutex_errors|guest_pthread_rwlock|guest_kernel_errors)$' passes 3 of 3 (all three tests).
  • With libkernel/Pthread/src/Mutex.cpp and Rwlock.cpp restored to the merge-base (the PR's tests kept): fails: guest_pthread_mutex_errors and guest_pthread_rwlock abort, guest_kernel_errors fails too.
    Not tested: macOS, Windows, a title run.
    AI-assisted (Claude Code).

@MaxLikesCode

Copy link
Copy Markdown
Contributor Author

Thanks @xXPBSXx for the Linux run and the check with Mutex.cpp and Rwlock.cpp restored. I added it to the Tested section.

AI-assisted: yes (Claude Code)

This branch has not been deployed

No deployments
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.

3 participants