Skip to content

feat(libSceAmpr): implement the std::_Pad thread launch helpers - #3743

Merged
adriadam10 merged 4 commits into
boykopovar:mainfrom
YossiYad:carry/ampr-pad-launch
Oct 13, 2026
Merged

adriadam10 merged 4 commits into
boykopovar:mainfrom
YossiYad:carry/ampr-pad-launch

Conversation

@YossiYad

@YossiYad YossiYad commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

What

Carries David's screamm/AnyPS5:feat/ampr-pad-launch commit from #3361 onto current main, preserving its author, and adds three follow-up commits:

  • Implement std::_Pad construction, destruction, _Launch(pthread**) and _Release() in libSceAmpr. The constructor creates and locks the synchronization objects; launch starts a guest pthread and waits for its _Go() callback to release the caller; destruction releases the synchronization objects while the worker can keep running. Deathloop and Minecraft Legends import these functions, as reported in libSceAmpr: the std::_Pad thread launch exports are stubs (Deathloop, Minecraft Legends); fix branch ready #3361.
  • Extend guest_ampr_threads with four simultaneous launchers, immediate release, exit codes with the high bit set, and overwriting the destroyed pad while its worker continues from its saved arguments.
  • Name the private entry trampoline with the _nid_no_patch suffix so it is excluded from the export inventory. The four public implementations move the library progress from 2903/3383 (85.81%) to 2907/3383 (85.93%), without counting that helper.
  • Raise _Pad failures as the guest std::system_error that Dinkumware's _Throw_C_error picks for the code (_Thrd_busy → device_or_resource_busy, _Thrd_error → invalid_argument, _Thrd_nomem/_Thrd_timedout and a failing thread start → resource_unavailable_try_again), through the _Throw_Cpp_error that main now has, instead of a host exception no guest catch sees. _Release now uses _Cnd_signal like threadcall.cpp, since libc has it now.

The implementation follows the Dinkumware thread-call sources cited in #3361. Console layout, named overloads, default thread attributes and error-reporting limitations remain recorded in docs/dev/debt/libSceAmpr.md.

Closes #3361.

Tested

Linux (Bazzite 44, GCC 16.2.1, Ninja, Release, -DBUILD_TESTING=ON), based on main a11c8f7f; rebased onto 0f2683cb on 2026-10-13:

  • Full build, libs, and full ctest: 824 pass, 8 skip, no failures (832 registered tests). The GPU agc_driver_pixel_interlock test failed on an earlier run and passed on the final full run; the changed library does not participate in that test.
  • guest_ampr_threads passes 10 consecutive runs. The final targeted run of guest_ampr_threads, guest_libc_threads, patched_libraries and progress_report passes (4/4).
  • The extended thread test against an isolated build of unchanged main fails at the unimplemented _Pad constructor.
  • After the rebase and the error commit: full build and ctest 1043/1044; the one failure, agc_driver_tessellation (segfault), does not have this PR's files among its build inputs. In a forked child with a guest terminate handler, guest_ampr_threads checks that _Release on the thread still holding the pad's mutex throws std::system_error with EBUSY. The test fails with the previous host exception and with busy mapped to invalid_argument.
  • tools/check_conventions.py --base upstream/main and git diff --check pass.
  • The original author reported Windows testing in libSceAmpr: the std::_Pad thread launch exports are stubs (Deathloop, Minecraft Legends); fix branch ready #3361. Windows and game titles were not run on this machine.

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; no silent stubs added
  • No notes, investigation .md files or images added to the repository
  • No new third-party code
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Progress report (0f2683c → dd1deb6)

📈 System libraries: 87.93% (+0.11%, +4 implemented functions)

✅ 4 implemented
Library Name
libSceAmpr _ZNSt4_Pad7_LaunchEPP7pthread_nid_postfix
libSceAmpr _ZNSt4_Pad8_ReleaseEv_nid_postfix
libSceAmpr _ZNSt4_PadC2Ev_nid_postfix
libSceAmpr _ZNSt4_PadD2Ev_nid_postfix

@github-actions

github-actions Bot commented Oct 11, 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
#4164 _ZNSt4_Pad7_LaunchEPP7pthread_nid_postfix
_ZNSt4_Pad8_ReleaseEv_nid_postfix
_ZNSt4_PadC2Ev_nid_postfix
_ZNSt4_PadD2Ev_nid_postfix

@YossiYad

Copy link
Copy Markdown
Contributor Author

#3742 carries the same commit from #3361. This PR adds two things on top: the private entry trampoline is renamed with _nid_no_patch so the inventory no longer counts PadEntry as an export (the progress report on #3742 lists it as a fifth implemented function), and guest_ampr_threads gains four simultaneous launchers, immediate release, high-bit exit codes and a destroyed pad whose worker keeps running. If #3742 is merged first, I'm happy to rebase the two follow-up commits onto it as a separate PR.

@blawesom

Copy link
Copy Markdown
Contributor

Cross-reference: #3742 (MarcZX100) implements the same functions (the std::_Pad thread-launch helpers) — opened at the same minute (16:16 UTC).

CONTRIBUTING.md asks authors to "check that no open pull request already implements the same functions" before starting — both PRs are open, so flagging for the maintainers.

The limitation this creates: only one of the two can be merged; the other gets closed as duplicate.

Related: this is also the fix tracked in #3361, which has a two-platform-verified branch (blawesom:verify/3361, full suite green on Linux and macOS) — cross-linking so the maintainers can compare against the original author's commit if they prefer that.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 11, 2026
@YossiYad
YossiYad force-pushed the carry/ampr-pad-launch branch from 901186e to 65c5d63 Compare October 11, 2026 22:20
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 11, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 12, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

Which title stops at one of the std::_Pad exports on main? #3361 names Deathloop and Minecraft Legends as importing them, but no run that reaches the throw. With the title ID and the log line this can go in.

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for carrying this. Before it can go in:

  • The PR conflicts with main (core/libs/prx/libSceAmpr/Export.cpp after #3814, and docs/dev/TechnicalDebt.md). Please rebase and rerun guest_ampr_threads.
  • #4164 is still open and also implements _ZNSt4_PadC2Ev, _ZNSt4_PadD2Ev, _ZNSt4_Pad7_Launch... and _ZNSt4_Pad8_Release... (see the pr-overlap comment). CONTRIBUTING allows only one PR per function: coordinate there so these four exports land in one PR only, and list the other under "Depends on" if this one goes second.
  • @oneandonlydean's question is unanswered: which title (PPSA id) stops at one of these exports, and the log line where it throws? #3361 only says the titles import them.

David and others added 3 commits October 13, 2026 15:51
Implement _ZNSt4_PadC2Ev, _ZNSt4_PadD2Ev, _ZNSt4_Pad7_LaunchEPP7pthread
and _ZNSt4_Pad8_ReleaseEv, which Deathloop (PPSA01670) and Minecraft
Legends (PPSA05510) import from libSceAmpr for the std::thread launch path.

The algorithm and object layout follow Dinkumware V6.00 thr/xthread and
thr/threadcall.cpp of Visual C++ 2013 (ganboing/crt.vc12 f1d47126): a
vtable pointer whose first slot is the pure virtual _Go(), then the
condition and mutex handles and bool _Started (0x8, 0x10, 0x18), with the
console's pointer-to-slot handles of libc Threads.cpp (boykopovar#3079). The pad
uses libc's _Cnd_*/_Mtx_* exports, starts the guest thread with
pthread_create and an entry that calls _Go() and returns its result as
the exit code, as _Call_func does. The unverified layout, thread
attributes and error reporting are recorded in TechnicalDebt.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@YossiYad
YossiYad force-pushed the carry/ampr-pad-launch branch from 65c5d63 to 8e3b2a0 Compare October 13, 2026 12:53
A failing _Pad primitive threw a host std::runtime_error, which no guest
catch can see. threadcall.cpp calls the checked wrappers of xthread
(_Mtx_lockX, _Cnd_waitX, _Thrd_startX), which pass a non-success code to
_Throw_C_error: _Thrd_nomem and _Thrd_timedout become
resource_unavailable_try_again, _Thrd_busy device_or_resource_busy and
_Thrd_error invalid_argument, raised through _Throw_Cpp_error, which main
now implements. A failing thread start is _Thrd_startX's
resource_unavailable_try_again.

_Release now wakes the launching thread with _Cnd_signal, as
threadcall.cpp does; libc has it since the pad was written.

guest_ampr_threads checks, in a forked child whose guest terminate
handler reports the thrown object, that _Release on the thread still
holding the pad's mutex throws std::system_error with EBUSY. It fails
with the previous host exception and with busy mapped to
invalid_argument.
@YossiYad
YossiYad force-pushed the carry/ampr-pad-launch branch from 2488e9d to dd1deb6 Compare October 13, 2026 12:59

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Rebased state checked: guest_ampr_threads and the rest of the libSceAmpr/libs ctest pass on current main, and the new test fails without the Export.cpp change. Layout, lock/wait order, error mapping to the guest std::system_error and the TechnicalDebt entry look consistent with the cited Dinkumware sources.

Note for #4164: it also implements the four std::_Pad exports; this PR came first, so that part should be dropped there.

Merging once the full Build is green.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 13, 2026
@adriadam10
adriadam10 merged commit 1e7f496 into boykopovar:main Oct 13, 2026
9 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.

libSceAmpr: the std::_Pad thread launch exports are stubs (Deathloop, Minecraft Legends); fix branch ready

4 participants