Skip to content

test(libkernel): cover the return values of pthread_mutex_trylock - #11500

Open
xXPBSXx wants to merge 3 commits into
boykopovar:mainfrom
xXPBSXx:test/pthread-mutex-trylock-behavior
Open

xXPBSXx wants to merge 3 commits into
boykopovar:mainfrom
xXPBSXx:test/pthread-mutex-trylock-behavior

Conversation

@xXPBSXx

@xXPBSXx xXPBSXx commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds guest_posix_mutex_trylock, a behaviour test for pthread_mutex_trylock, the POSIX export that returns an errno value. It wraps scePthreadMutexTrylock, which has tests, but the wrapper's own results had none. It follows FreeBSD 11.4's lib/libthr/thread/thr_mutex.c (__pthread_mutex_trylock and mutex_self_trylock):

  • a statically initialised mutex and a free mutex return 0, and a second call by the holder returns EBUSY (16) for the statically initialised, the error-checking and the normal type;
  • a recursive mutex returns 0 again for the holder and needs two unlocks;
  • a mutex held by another thread returns EBUSY; the helper thread signals that it holds the lock, the main thread waits for that with a 5 s deadline, and then checks;
  • after the holder unlocks, trylock returns 0 again.

No production code changes. There is no failing arm on main: this is coverage of the POSIX wrapper over an already tested Sce function, not a fix. The test takes well under a second.

Tested

  • Windows 10 Pro, MinGW-w64 GCC 15.2, Release, head fc08fd38c4 on main 48c160c58b (ninja exit code 0): guest_posix_mutex_trylock passes 5 of 5 runs.
  • Ubuntu 24.04 under WSL2 (a virtualised kernel, not bare-metal), GCC 13.3, Release, head fc08fd38c4 (ninja exit code 0): passes 5 of 5 runs.
  • To see what the test catches, I changed the code on Windows six ways and built the test each time (ninja exit code 0). In pthread_mutex_trylock_nid_postfix (Pthread/Posix/Mutex.cpp): the result of scePthreadMutexTrylock returned without ToErrno (line 74), EBUSY reported as success (line 74) and a timed lock with no wait instead of the trylock (line 74) each fail the check "trylock of a held statically initialised mutex returns EBUSY". In the Sce trylock logic (Pthread/src/Mutex.cpp): giving a recursive holder EBUSY (line 68, owned && tryOnly) fails "recursive trylock by the holder returns 0 again", and reporting success for a busy mutex (line 248, sceBusy replaced by 0) fails "trylock of a mutex held by another thread returns EBUSY". Removing the wrapper's static initialisation (line 73) is not caught: scePthreadMutexTrylock initialises a static mutex itself. Each change was reverted afterwards.
  • check_conventions --base upstream/main passes.
  • Run by others on macOS (Apple M5 Pro, macOS 27.2, Apple clang 21, x86-64 Release under Rosetta 2, main 801d5b9bc1 plus the open macOS build PRs, this PR's diff on top): guest_posix_mutex_trylock passes 6 of 6 on head 6a6ffb62d4 (comment).
  • Not run: a sanitizer build, the EAGAIN overflow of a recursive mutex, the rest of the libkernel tests on this head. The expected behaviour comes from the FreeBSD 11.4 source; the console itself is not measured.

Overlap

No open PR adds a test for pthread_mutex_trylock; git grep on main finds no test that calls it. 55 open PRs change core/libs/prx/libkernel/CMakeLists.txt or this test. git merge-tree of this head with each of them conflicts for 17 (measured against main 761eaba441); 16 of those already conflict with main on their own. The seventeenth is my own #10979, where both PRs add a test block before guest_rename_dot_tests and #10979 merges cleanly into main alone. Whichever lands second rebases; this PR depends on none of them.

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

AI-assisted (Claude Code).

🤖 Generated with Claude Code

pthread_mutex_trylock returns an errno value, unlike the Sce function it
wraps, and had no test. Check the FreeBSD 11.4 results of
__pthread_mutex_trylock and mutex_self_trylock (lib/libthr/thread/thr_mutex.c
lines 611-640 and 850-873): a free or statically initialised mutex returns 0,
a mutex held by the caller returns EBUSY for the error-checking and normal
types and 0 for the recursive type, and a mutex held by another thread returns
EBUSY.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test cases match the current POSIX wrapper behavior: ToErrno maps the SCE busy result to EBUSY, same-thread reacquisition of normal/error-checking mutexes returns busy, recursive reacquisition succeeds, and a different thread holding the mutex returns busy. The Open Group specification requires EBUSY when trylock cannot acquire an already locked mutex, and FreeBSD 11.4's mutex_self_trylock explicitly returns EBUSY for normal/error-checking mutexes and allows recursive acquisition. The author reports five successful runs each on Windows and WSL/Linux; I have not independently run this C++ test. Current-main conventions and git diff --check pass.

The branch is based on 48c160c, while current main is 88795ed. CONTRIBUTING.md requires branches to stay up to date. Main has no intervening change to the CMake file or test source, but please sync before merge and rerun the registered test on the resulting head.

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

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 4563 core/libs/prx/libkernel/CMakeLists.txt
PR 5021 core/libs/prx/libkernel/CMakeLists.txt
PR 6936 core/libs/prx/libkernel/CMakeLists.txt
PR 7192 core/libs/prx/libkernel/CMakeLists.txt
PR 9019 core/libs/prx/libkernel/CMakeLists.txt
PR 9156 core/libs/prx/libkernel/CMakeLists.txt
PR 9284 core/libs/prx/libkernel/CMakeLists.txt
PR 9293 core/libs/prx/libkernel/CMakeLists.txt
PR 9297 core/libs/prx/libkernel/CMakeLists.txt
PR 9302 core/libs/prx/libkernel/CMakeLists.txt
PR 9383 core/libs/prx/libkernel/CMakeLists.txt
PR 9389 core/libs/prx/libkernel/CMakeLists.txt
PR 9557 core/libs/prx/libkernel/CMakeLists.txt
PR 9566 core/libs/prx/libkernel/CMakeLists.txt
PR 9575 core/libs/prx/libkernel/CMakeLists.txt
PR 11002 core/libs/prx/libkernel/CMakeLists.txt
PR 11625 core/libs/prx/libkernel/CMakeLists.txt
PR 11969 core/libs/prx/libkernel/CMakeLists.txt
PR 12068 core/libs/prx/libkernel/CMakeLists.txt

@xXPBSXx

xXPBSXx commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

Merged main (88795ed448) into the branch without conflicts; head 6a6ffb62d41b8c0a9fbb2c7cee18702ebb1b6a63, and the diff against main is unchanged (the new test and its CMake registration). Retested on that exact head: guest_posix_mutex_trylock passes 5 of 5 runs on Windows 10 (MinGW-w64 GCC 15.2, Release) and 5 of 5 on Ubuntu 24.04 under WSL2 (a virtualised kernel, not bare-metal), GCC 13.3. check_conventions passes and git merge-tree against current main is clean. Could you re-review?

AI-assisted (Claude Code).

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The branch is now based on current main (88795ed448) and the author reports the registered test passing five times each on Windows and Ubuntu under WSL2. The cases cover free/static/error-checking/normal/recursive mutexes and a mutex held by another thread; the FreeBSD behavior reference supports the expected EBUSY results. Conventions and diff checks pass.

I built the exact test and registration in a current-main scratch checkout; guest_posix_mutex_trylock_tests passed under QEMU user-mode emulation. Native execution is unavailable on this host because it lacks the required CPU extensions. Hosted product jobs are skipped, but the author supplied repeat runs on the updated head. I found no remaining blocker and approve.

@Gonic0

Gonic0 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

macOS run of head 6a6ffb62d4, for the "Not run: macOS" line: Apple M5 Pro, macOS 27.2, Apple clang 21, x86-64 Release under Rosetta 2. Tree: main 801d5b9bc1 plus the open macOS build PRs (#7631, #11249, #11358, #10669, #10552, #7804, #11447, #11437, #11554), with this PR's diff on top.

guest_posix_mutex_trylock passes 6 of 6.

AI-assisted: yes

@xXPBSXx xXPBSXx mentioned this pull request Oct 27, 2026
12 tasks done
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 27, 2026
The test block of guest_posix_specific landed in main at the place where this branch adds its own; keep both blocks.
@xXPBSXx

xXPBSXx commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Merged main (6e9b9134f6) into the branch; the only conflict was in libkernel/CMakeLists.txt, where the guest_posix_specific test block that landed with #11799 sits in the same place as this branch's block, and I kept both blocks. On the merge head b8685f717e, guest_posix_mutex_trylock passes 3 of 3 runs on Windows 10 (MinGW-w64 GCC 15.2, Release) and 3 of 3 on Ubuntu 24.04 under WSL2 (a virtualised kernel, not bare-metal); check_conventions passes with the live title and description, and git merge-tree against main is clean.

AI-assisted (Claude Code).

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 28, 2026

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.

4 participants