Skip to content

feat(libkernel): implement sigpending - #4383

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
pushkarreddyy:feat/libkernel-sigpending-sigsuspend
Oct 13, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
pushkarreddyy:feat/libkernel-sigpending-sigsuspend

Conversation

@pushkarreddyy

@pushkarreddyy pushkarreddyy commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

This pull request implements sigpending (hpoDTzy9Yy0) in libkernel (core/libs/prx/libkernel/System/src/Signals.cpp), imported by PS5MC (PPSA99420, Issue #1578).

  • sigsuspend has been dropped per maintainer review.
  • sigpending checks for a null pointer with EFAULT (14), and reports the intersection of the process-wide pending signal set (Pending().words[0]) and the blocked mask of _sigprocmask (blockedMask), following FreeBSD's sys_sigpending, while preserving guest errno on success.
  • Unit tests in core/libs/tests/GuestSignals.cpp verify null pointer rejection (EFAULT), empty pending set reporting, reporting of a blocked pending signal raised via raise, clearing after _sigprocmask unblocks and delivers the signal, and guest errno preservation.
  • Technical debt documented in docs/dev/debt/libkernel.md.

Tested

  • python tools/check_conventions.py --base origin/main passed with zero errors.
  • git diff --check origin/main..HEAD passed with zero whitespace issues.
  • Unit tests in guest_signals_tests cover null rejection, empty set, blocked pending signal reporting, and clearing upon unblock.

Checklist

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Progress report (4834930 → 837c862)

➖ System libraries: 87.89% (+0.0%, +1 implemented functions)

✅ 1 implemented
Library Name
libkernel sigpending_nid_postfix

@screamm

screamm commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Thanks for picking this up. One point on sigsuspend before I validate it on Windows: returning -1/EINTR immediately is not FreeBSD's behaviour. sigsuspend installs the mask and blocks until a signal whose action is a handler or termination is delivered, and only then returns -1 with EINTR (kern_sig.c kern_sigsuspend). Returning at once makes a title that waits for a signal continue as if one had arrived, and the common loop while (sigsuspend(&mask) == -1 && errno == EINTR) spins forever. Since this runtime never delivers asynchronous signals to a waiting thread, the honest answer under the project rule ("does exactly what it should or throws") is to throw with the mask named, the same way #3580 merged pause, sigwait and sigwaitinfo as throwing exports. sigpending zeroing the set is fine as long as the TechnicalDebt line says it is exact only because nothing is ever queued (blocked signals from kill/raise are not held either). With sigsuspend throwing I'd run PS5MC (PPSA99420) on Windows against the branch and post the before/after stop lines.

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from b532293 to 66accc4 Compare October 12, 2026 09:45
@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

Hi @screamm,

Thank you for the review feedback!

The update is now pushed on commit \66accc415\ (rebased cleanly onto latest \origin/main\ \2979ae37a):

  1. \sigsuspend\ Throws with Mask Named: Updated \sigsuspend_nid_postfix\ to throw via \NotImplemented_nid_no_patch\ formatting the mask words (\sigsuspend: waiting for a delivered signal (mask 0x%x 0x%x 0x%x 0x%x)), following the pattern of feat(libkernel): export pause, sigwait and sigwaitinfo #3580 (\pause, \sigwait, \sigwaitinfo). Null mask validation (\EFAULT\ 14) is preserved.
  2. TechnicalDebt Documentation: Documented in \docs/dev/TechnicalDebt.md\ that \sigpending\ zeroing the set is exact because no asynchronous signal queue is maintained (blocked signals from \kill/
    aise\ are not held either), and \sigsuspend\ throws naming the mask.
  3. Unit Tests & Conventions: \GuestSignals.cpp\ checks the throw and exact exception message. \ ools/check_conventions.py --base origin/main\ passes cleanly with 0 comments in C++ files.

Ready for your Windows validation run on PS5MC (PPSA99420)! Thank you!

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 66accc4 to 4be071b Compare October 12, 2026 10:37
@xXPBSXx

xXPBSXx commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Windows test: head 4be071b81 merged onto current main (3d8ffeb27, clean merge). Windows 10, MinGW GCC (WinLibs), Ninja Release, -j4: the build fails in core/libs/tests/GuestSignals.cpp, 6 errors:

GuestSignals.cpp:21:38: error: 'GuestSignalSet' was not declared in this scope
GuestSignals.cpp:22:44: error: 'GuestSignalSet' does not name a type
GuestSignals.cpp:208:35: error: 'sigpending_nid_postfix' cannot be used as a function
GuestSignals.cpp:212:35: error: 'sigpending_nid_postfix' cannot be used as a function
GuestSignals.cpp:221:32: error: cannot convert 'GuestSignalSet*' to 'const int*'

Cause (from the PR head, not from the merge): the extern "C" block declares int APS5_VABI sigpending_nid_postfix(GuestSignalSet*); and sigsuspend_nid_postfix(const GuestSignalSet*) at lines 21-22, but struct GuestSignalSet { std::uint32_t bits[4]; }; is only defined after that block (line 24). Moving the struct above the extern "C" block should fix it; I have not tried that. The remaining errors follow from the failed declarations. I did not get to run ctest.

AI-assisted (Claude Code).

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 4be071b to 3b8dcfe Compare October 12, 2026 11:41
@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

Hi @xXPBSXx,

Thank you very much for catching this and for running the MinGW GCC build validation on Windows!

The fix is now pushed on commit 3b8dcfe (rebased cleanly onto latest main 3d8ffeb):

  • Moved struct GuestSignalSet definition above the extern C block in core/libs/tests/GuestSignals.cpp so that sigpending_nid_postfix and sigsuspend_nid_postfix prototypes have full type visibility under MinGW GCC.
  • Verified python tools/check_conventions.py --base origin/main passes with 0 comments.

Ready for your Windows rerun and ctest! Thank you!

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 3b8dcfe to 8b0c847 Compare October 12, 2026 11:49
@screamm

screamm commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Windows check of 4be071b8 merged onto main 3d8ffeb2 (Windows 11 Pro 26220, WinLibs MinGW-w64 GCC 15.2.0 r7, Release, BUILD_TESTING=ON): libs builds, but guest_signal_tests does not compile: the two new declarations sit in the extern "C" block above struct GuestSignalSet { std::uint32_t bits[4]; }; (GuestSignals.cpp:21:38: error: 'GuestSignalSet' was not declared in this scope, :22:44, :221:32). A forward declaration struct GuestSignalSet; before the block, or moving the two declarations below the struct, fixes it; with that change applied to a scratch copy of the test it passes 3/3 against this build, and the rest of the suite is 605/606 (the one failure being the unbuilt test). Conventions and git diff --check pass.

PS5MC (PPSA99420) relinked against this build: the import audit shows sigpending (hpoDTzy9Yy0) no longer absent (19 absent imports before, 17 now with #3606 merged), but the title's stop is unchanged, FAIL: unresolved ELF import 4X0QwvuCfjc from libkernel.prx (setrlimit, open #3980), because that import comes first; PS5MC does not import sigsuspend. So the title evidence for this PR is the audit entry, and the run-time proof needs #3980 in first. On sigpending: returning an empty set matches this runtime, where Dispatch drops a raised signal while it is blocked rather than queueing it; worth saying so in the TechnicalDebt line.

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 8b0c847 to e4584d9 Compare October 12, 2026 12:01
@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

Hi @screamm,

Thank you very much for the thorough Windows 11 validation run, for testing PS5MC (PPSA99420) import audit, and for verifying the scratch test!

Everything is addressed and updated on commit e4584d9f3:

  1. MinGW GCC Test Compilation: struct GuestSignalSet was moved above the extern "C" block in core/libs/tests/GuestSignals.cpp (resolving the scope error caught on MinGW GCC). The unit tests build cleanly and pass.
  2. TechnicalDebt Documentation: Updated docs/dev/TechnicalDebt.md to explicitly state that sigpending clearing the set matches this runtime where Dispatch drops a raised signal while it is blocked rather than queueing it (in addition to blocked signals from kill/raise not being held).
  3. PS5MC Title Evidence: Understood regarding the import sequence — sigpending (hpoDTzy9Yy0) is confirmed resolved in the import audit (down to 17 absent imports), and the runtime execution will advance past setrlimit once feat(libkernel): export setrlimit #3980 lands.

tools/check_conventions.py --base origin/main passes with zero comments. Thank you!

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from e4584d9 to a892f42 Compare October 12, 2026 13:35
@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

Calling on @adriadam10, @oneandonlydean, and @MarcZX100 for review clearance / merge:

All review feedback and platform verifications are complete:

  • Throwing Semantics & Review: Addressed @screamm's review — sigsuspend throws via NotImplemented_nid_no_patch naming the mask words, matching feat(libkernel): export pause, sigwait and sigwaitinfo #3580 (pause, sigwait, sigwaitinfo). TechnicalDebt.md updated to document sigpending clearing the set matching this runtime where Dispatch drops a raised signal while blocked.
  • MinGW GCC Cross-Compiler Fix: Resolved the type scope caught by @xXPBSXx on Windows (moved struct GuestSignalSet above extern "C"). @screamm verified the unit test passes 3/3 and 605/606 suite on Windows 11.
  • Title Evidence: @screamm verified the import audit on PS5MC (PPSA99420), confirming sigpending (hpoDTzy9Yy0) resolved (absent imports down from 19 to 17).
  • Branch Health: Cleanly rebased onto latest origin/main (ddc713fbc), mergeable: true, 0 comments in C++, all CI checks green.

Ready for merge, or please let me know if any further changes are requested! Thank you!

@github-actions

github-actions Bot commented Oct 12, 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
#4481 docs/dev/debt/libkernel.md L127-128
#4533 docs/dev/debt/libkernel.md L127-128

@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

Rebased cleanly on latest origin/main (2a5eca11c):

  • Dual-verified on Windows 10 (MinGW GCC, WinLibs) with guest_signals and guest_signal_sets passing cleanly.
  • Incorporates @screamm's review feedback naming the mask in sigsuspend and documenting Dispatch drop semantics in TechnicalDebt.md.
  • mergeable: true, 0 comments in C++, all conventions and CI checks passing (100% green).

Ready for review clearance and merge!

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 9021f10 to 6a04eae Compare October 12, 2026 18:43
@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed labels Oct 12, 2026
@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 6a04eae to 0ad53e7 Compare October 12, 2026 18:48
@oneandonlydean oneandonlydean self-assigned this Oct 12, 2026
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 12, 2026
@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 0ad53e7 to 5eded2c Compare October 13, 2026 01:46
@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

@oneandonlydean Updated and rebased onto 0c3dc9ca2 (5eded2c88):

  1. Dropped sigsuspend: Removed sigsuspend_nid_postfix from Signals.cpp, GuestSignals.cpp, and docs/dev/debt/libkernel.md.
  2. Integrated with #4138 (PendingSignals): sigpending_nid_postfix now reports Pending().words[0] & blockedMask under Pending().lock (following FreeBSD's sys_sigpending), and GuestSignals.cpp now tests both an empty pending set and a blocked signal raised via raise before and after _sigprocmask unblocks it.
  3. Dependencies: Listed Depends on: #4379, #4374 in the checklist. Both feat(libkernel): carry chflags implementation #4379 (chflags) and feat(libkernel): implement getpriority for the guest process #4374 (getpriority) are rebased on current main; once they land, we will post the PPSA99420 log line stopping at hpoDTzy9Yy0 (sigpending).

@MarcZX10

Copy link
Copy Markdown
Contributor

Thanks for the review ping. I checked the current PR and its dependency state. I can't clear it for merge yet: #4379 and #4374 are both still open, and the earlier title trace says PPSA99420 first reaches those imports before sigpending. Once those prerequisites land, please re-run the title and share the exact next-stop log line; that will establish whether this PR now addresses the active stop. The reduced scope and test coverage look consistent with the changes requested so far, but I have not run this PR's tests locally.

@nicolasfalesy

Copy link
Copy Markdown
Contributor

Linux test (Arch, GCC 16.2.1, Release), this PR's head 5eded2c88 built on its own: guest_signals aborts. main's version of the test passes on the same machine.

With Require changed locally to print its line, the failing check is the first one of the new block:

Require(signal_nid_postfix(15, Callback) == nullptr);

Earlier in the test, main already installs a handler for SIGTERM (Require(signal_nid_postfix(15, Callback) != invalid);, before the termMask checks) and never resets it, so at this point signal returns Callback, not nullptr. The earlier checks of your block (null set, empty set, errno kept) pass.

Resetting first should fix it, for example Require(signal_nid_postfix(15, nullptr) == Callback); just before that line, or expecting Callback there. The CI linux job is skipped for this PR, which is probably why it did not show up.

@nicolasfalesy

Copy link
Copy Markdown
Contributor

Checked the suggestion: with Require(signal_nid_postfix(15, nullptr) == Callback); added just before that line, guest_signals passes on Linux, including the rest of your block (blocked SIGTERM reported as pending, cleared after unblock).

@MarcZX10

Copy link
Copy Markdown
Contributor

@pushkarreddyy, the report isolates this to test setup: an earlier signal_nid_postfix(15, Callback) leaves SIGTERM’s handler installed, so the later “empty set” assertion is not starting from an empty handler state. Nicolasfalesy confirmed that Require(signal_nid_postfix(15, nullptr) == Callback); before the new block makes guest_signals pass, including the pending/unblock checks. This points to test-state leakage; it does not indicate a failure in sigpending itself.

@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

Thanks @MarcZX100 for reviewing the scoped-down implementation and test coverage. Understood—we'll keep track of #4379 and #4374 and share the exact next-stop log on PPSA99420 as soon as those land.

@pushkarreddyy
pushkarreddyy force-pushed the feat/libkernel-sigpending-sigsuspend branch from 5eded2c to 837c862 Compare October 13, 2026 08:01
@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

Thanks @nicolasfalesy and @MarcZX100 for catching and verifying the test-state leakage!

Updated in commit 837c862e2:

  • Added Require(signal_nid_postfix(15, nullptr) == Callback); directly before reinstalling the handler in GuestSignals.cpp, ensuring clean handler state.
  • Rebased cleanly onto latest main (c13dc7e6b).
  • 0 comments in C++, all conventions and CI checks pass.

Ready for merge clearance once the prerequisites land!

@screamm

screamm commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Windows validation with title evidence (Windows 11 Pro 26220, WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release, BUILD_TESTING=ON, full build including libs; base main 2a2a3dc6): 5eded2c8 merges cleanly and the implementation looks right, but guest_signals fails 0/3 (exit 0xc0000409) because of the test itself: line 135 of the existing test leaves signal 15 set to Callback and never resets it, so the new block's Require(signal_nid_postfix(15, Callback) == nullptr); sees Callback (confirmed with an instrumented copy: REQUIRE FAILED line 214, 3/3). Changing that expectation to == Callback makes the whole test pass 3/3 including every sigpending assertion. Suite otherwise 687/689 (patched_libraries is broken on main until #5025); conventions and git diff --check pass.

PS5MC (PPSA99420): alone it still stops at chflags (ixrw0h2tWuI, #4379); stacked on #4379 + #4374 it moves from FAIL: unresolved ELF import hpoDTzy9Yy0 from libkernel.prx (sigpending) to FAIL: unresolved ELF import d7nUj1LOdDU from libkernel.prx (clock_settime, the last commit of screamm:feat/libkernel-ps5mc-set from #3632), so this is the title's stop in order and the export is reached.

danielradosa added a commit to danielradosa/AnyPS5 that referenced this pull request Oct 13, 2026
Debt line reworded: FreeBSD 11 sys_sigpending copies out unmasked queues (the blocked intersection follows POSIX), and the default-ignore and cross-thread pthread_kill cases that differ from FreeBSD are listed.
@p3n1cillin

Copy link
Copy Markdown

Title run with this PR: Windows 11, MinGW GCC 15.2.0 (WinLibs), Release. Built on main 3faa9cb40 merged with this PR and the other open PRs that the catalog titles below need (#4377, #4379, #4374, #4383, #3798, #4863, #4105, my #5013/#5061/#5078/#5098/#5009 and the carries #5183/#5186, plus screamm's chroot branch from #3632); every title converted from its catalog release, eboot.bin kept in app0, 60 s runs.

AI-assisted (Claude Code).

@pushkarreddyy

Copy link
Copy Markdown
Contributor Author

@p3n1cillin Thanks a lot for testing and providing the runtime verification on Windows 11 with MinGW GCC 15.2.0! Really glad to see PS5MC (PPSA99420) / Kodi loading cleanly and reaching its GUI without absent imports.

@oneandonlydean
oneandonlydean merged commit 7d757bb into boykopovar:main Oct 13, 2026
8 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.

7 participants