Skip to content

feat(libSceSystemService): implement GPU load emulation mode and suspend confirmation dialog flag - #12285

Merged
oneandonlydean merged 4 commits into
boykopovar:mainfrom
MarcZX10:feat/libscesystemservice-pending-exports
Nov 2, 2026
Merged

oneandonlydean merged 4 commits into
boykopovar:mainfrom
MarcZX10:feat/libscesystemservice-pending-exports

Conversation

@MarcZX10

Copy link
Copy Markdown
Contributor

What

Implements two groups of pending libSceSystemService exports that had no behaviour and threw NotImplemented_nid_no_patch:

  • GPU load emulation mode: sceSystemServiceSetGpuLoadEmulationMode, sceSystemServiceGetGpuLoadEmulationMode, sceShellCoreUtilSetGpuLoadEmulationMode, sceShellCoreUtilGetGpuLoadEmulationMode, sceShellCoreUtilSetGpuLoadEmulationModeByAppId, sceShellCoreUtilGetGpuLoadEmulationModeByAppId. One atomic mode (0 off, 1 normal, per SharpProspero); the getter returns the mode itself. Other modes and other app IDs throw.
  • Suspend confirmation dialog: sceSystemServiceEnableSuspendConfirmationDialog, sceSystemServiceDisableSuspendConfirmationDialog, sceShellCoreUtilGetSuspendConfirmationDialogFlag (atomic flag, starts enabled, running title only).

Both are listed under Silent stubs in docs/dev/debt/libSceSystemService.md (the host has no GPU throttling and no shell dialog), with the assumptions stated (initial values, shared mode) and the public sources cited (SharpProspero, OpenOrbis, shadPS4 for prototypes and behaviour only; no code copied).

Skipped on purpose: the other ~500 pending exports have no public prototype or documented behaviour (OpenOrbis and shadPS4 list them as argument-less stubs), so they stay untouched. Exports already covered by open PRs (screen saver, eye-to-eye adjusted, suspend notification, streaming/remote play queries, USB storage, splash/player dialog stubs) were not touched.

Two commits, one per group.

Tested

  • guest_system_service, guest_system_service_language, guest_system_service_time_zone and the three guest_system_service_app_title_id_* tests pass; GuestSystemService.cpp gains tests for both groups, including 4-thread concurrent set/get.
  • tools/check_conventions.py --base upstream/main, the public header audit and git diff --check pass.

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

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Progress report (88e804b → aefbe42)

📈 System libraries: 26.43% (+0.01%, +4 implemented functions)

✅ 4 implemented
Library Name
libSceSystemService sceShellCoreUtilGetGpuLoadEmulationMode
libSceSystemService sceSystemServiceDisableSuspendConfirmationDialog
libSceSystemService sceSystemServiceEnableSuspendConfirmationDialog
libSceSystemService sceSystemServiceGetGpuLoadEmulationMode

Changed libraries (implemented exports)

Library Before After Change
libSceSystemService 135/584 (23.12%) 139/584 (23.80%) +0.68%

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@MarcZX10 thanks, the two groups look right to me: none of the nine NIDs was implemented before, the mode and the flag are plain atomics, and the debt entries say what is assumed. One thing before it lands, from the rule that new tests do not assert that an unimplemented export throws:

  • In TestGpuLoadEmulationMode and TestSuspendConfirmationDialog (core/libs/tests/GuestSystemService.cpp), please drop the Throws assertions for modes other than 0 and 1 ({2u, 3u, 0xffffffffu}) and for an app ID other than the running title (runningAppId + 1 and -1). The code does not validate those inputs and return an error; it throws NotImplemented_nid_no_patch for any of them, and the console's result for them is not known, so the tests would pin a stub throw. The throws in Export.cpp can stay, and the rest of both tests (defaults, set/get, ByAppId with the running app, the four-thread loop) can stay too.

@github-actions

github-actions Bot commented Oct 28, 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 14877 core/libs/tests/GuestSystemService.cpp L12

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 8651 core/libs/prx/libSceSystemService/Export.cpp
core/libs/prx/libSceSystemService/PendingExports.cpp
core/libs/tests/GuestSystemService.cpp
docs/dev/debt/libSceSystemService.md
PR 14085 docs/dev/debt/libSceSystemService.md
PR 14126 core/libs/prx/libSceSystemService/PendingExports.cpp
PR 14212 docs/dev/debt/libSceSystemService.md

@JJenkx

JJenkx commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

A Windows run, since the description lists none. Head dc62fca840 was merged onto main b99bbebacd with no conflicts. Setup: Windows 11 Enterprise 10.0.22621, WinLibs GCC 15.2.0 UCRT r7, Ninja, Release, BUILD_TESTING=ON.

libs builds, and guest_system_service, including this PR's GuestSystemService.cpp checks, passes in each of 3 runs. This checks the library behaviour only; I didn't run a title in GPU load emulation mode.

AI-assisted: yes (Claude Code).

@maskym

maskym commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Windows result for head dc62fca840, merged into main 87b810a1db (the PR's Tested section names no Windows run).

Host: Windows 11 26300, Intel i7-12700K, WinLibs GCC 15.2.0 (x86_64-ucrt-posix-seh, r6), Release, BUILD_TESTING=ON, Ninja. Build clean.

The tree also carried the open PRs #12290, #12288, #12269, #12265, #12232, #12206, #12201, #12199, #12197, #12165, #12146, all merged cleanly, so the run is a joint one; the tests of this PR are guest_system_service (0.03 s), guest_system_service_app_title_id_ (? s), guest_system_service_language (0.03 s), guest_system_service_path_boundary (0.05 s), guest_system_service_time_zone (0.03 s), guest_system_service_usb_storage (0.04 s), all passed (every test registered from the tree's changed test files: 38/38). Not run on a PS5.

AI-assisted: yes (Claude Code), the runs and the numbers above are from this machine.

sceSystemServiceSetGpuLoadEmulationMode and
sceSystemServiceGetGpuLoadEmulationMode, with the sceShellCoreUtil
Set/Get pair and their ByAppId variants, now share one atomic mode
instead of throwing. Modes 0 (off) and 1 (normal) are accepted; the
getter returns the mode itself rather than a result code. The initial
mode is 1. Any other mode, and any app ID other than the running
title, still throws NotImplemented_nid_no_patch because the console's
errors for them are unknown. The host GPU is not throttled, which the
debt document lists under Silent stubs.
sceSystemServiceEnableSuspendConfirmationDialog and
sceSystemServiceDisableSuspendConfirmationDialog set an atomic flag
that sceShellCoreUtilGetSuspendConfirmationDialogFlag reads back for
the running title. The flag starts enabled. Another app ID still
throws NotImplemented_nid_no_patch because the console's answer is
unknown. AnyPS5 has no shell to suspend the title and show the
dialog, so the debt document lists the flag under Silent stubs.
@MarcZX10
MarcZX10 force-pushed the feat/libscesystemservice-pending-exports branch from dc62fca to eb385ab Compare October 28, 2026 13:07
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 28, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

@MarcZX10 The prior throw-assert request is still present at eb385ab: please remove the new Throws assertions for unsupported modes and non-running app IDs in GuestSystemService.cpp:122-123,152-154,157-159. Keep the implementation throws and supported mode/dialog tests. This is the same outstanding request, not a new behavior change.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Fix-up to your PR: removed only the unsupported-mode and foreign-app-ID throw assertions requested by our review; implementation throws and supported behavior tests are unchanged.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reviewed — requested test cleanup is in the head, no open point

The throw assertions oneandonlydean asked to drop are gone from the test file at this head, and the implementation throws they pointed at are still in Export.cpp.

What I ran

Live head: d9ca4b6 (OPEN, same as the batch file). Read the issue comments, review comments and reviews with gh api (repos/boykopovar/AnyPS5/issues|pulls/12285/...). Read files with git -C /marc/AnyPS5 show d9ca4b6b…:<path> and grep for Throws and NotImplemented. Read the hosted check rollup with gh pr view. Nothing was built or run.

Results

Check Result Note
windows SUCCESS hosted, at this head
conventions SUCCESS hosted, at this head
linux, relinker SKIPPED hosted workflow skipped them; not read further

Findings

  • oneandonlydean, 2026-10-28 07:25 UTC, and again 2026-10-29 05:51 UTC: drop the Throws checks for modes 2, 3 and 0xffffffff and for app IDs other than the running title. At this head TestSuspendConfirmationDialog (GuestSystemService.cpp:113-134) and TestGpuLoadEmulationMode (L136-162) contain no Throws check. The remaining Throws uses (L194-208) are the launch and PSM tests and were not part of the request. Done.
  • The throws stay in Export.cpp, as the reviewer said: L299 (mode other than 0 and 1), L306 (application other than the running title), L327 (suspend flag for another application).
  • TestRunningAppAnswer (L64-73) still queries other app IDs, but it expects a result code, not a throw.
  • oneandonlydean, 2026-10-29 11:51 UTC: "Fix-up" comment saying the removal was pushed. It matches the head. I did not tie it to a commit.

Sources

  • void TestSuspendConfirmationDialog() {
    const int runningAppId = sceSystemServiceGetAppIdOfRunningBigApp();
    Require(sceShellCoreUtilGetSuspendConfirmationDialogFlag(runningAppId));
    Require(sceSystemServiceDisableSuspendConfirmationDialog() == SYSTEM_SERVICE_OK);
    Require(!sceShellCoreUtilGetSuspendConfirmationDialogFlag(runningAppId));
    Require(sceSystemServiceDisableSuspendConfirmationDialog() == SYSTEM_SERVICE_OK);
    Require(!sceShellCoreUtilGetSuspendConfirmationDialogFlag(runningAppId));
    Require(sceSystemServiceEnableSuspendConfirmationDialog() == SYSTEM_SERVICE_OK);
    Require(sceShellCoreUtilGetSuspendConfirmationDialogFlag(runningAppId));
    std::vector<std::thread> threads;
    for (unsigned index = 0; index < 4; ++index) {
    threads.emplace_back([index] {
    for (unsigned round = 0; round < 1000; ++round) {
    const int result = ((index + round) & 1u) ? sceSystemServiceEnableSuspendConfirmationDialog() : sceSystemServiceDisableSuspendConfirmationDialog();
    Require(result == SYSTEM_SERVICE_OK);
    }
    });
    }
    for (std::thread& thread : threads) thread.join();
    Require(sceSystemServiceEnableSuspendConfirmationDialog() == SYSTEM_SERVICE_OK);
    Require(sceShellCoreUtilGetSuspendConfirmationDialogFlag(runningAppId));
    }
    void TestGpuLoadEmulationMode() {
    const int runningAppId = sceSystemServiceGetAppIdOfRunningBigApp();
    Require(sceSystemServiceGetGpuLoadEmulationMode() == 1);
    Require(sceShellCoreUtilGetGpuLoadEmulationMode() == 1);
    Require(sceSystemServiceSetGpuLoadEmulationMode(0) == SYSTEM_SERVICE_OK);
    Require(sceSystemServiceGetGpuLoadEmulationMode() == 0);
    Require(sceShellCoreUtilGetGpuLoadEmulationMode() == 0);
    Require(sceShellCoreUtilGetGpuLoadEmulationModeByAppId(runningAppId) == 0);
    Require(sceShellCoreUtilSetGpuLoadEmulationMode(1) == SYSTEM_SERVICE_OK);
    Require(sceSystemServiceGetGpuLoadEmulationMode() == 1);
    Require(sceShellCoreUtilSetGpuLoadEmulationModeByAppId(runningAppId, 0) == SYSTEM_SERVICE_OK);
    Require(sceSystemServiceGetGpuLoadEmulationMode() == 0);
    Require(sceShellCoreUtilGetGpuLoadEmulationModeByAppId(runningAppId) == 0);
    Require(sceSystemServiceGetGpuLoadEmulationMode() == 0);
    std::vector<std::thread> threads;
    for (unsigned index = 0; index < 4; ++index) {
    threads.emplace_back([index] {
    for (unsigned round = 0; round < 1000; ++round) {
    Require(sceSystemServiceSetGpuLoadEmulationMode((index + round) & 1u) == SYSTEM_SERVICE_OK);
    const int mode = sceSystemServiceGetGpuLoadEmulationMode();
    Require(mode == 0 || mode == 1);
    }
    });
    }
    for (std::thread& thread : threads) thread.join();
    Require(sceSystemServiceSetGpuLoadEmulationMode(1) == SYSTEM_SERVICE_OK);
    }
  • template<typename TValue, typename TQuery>
    void TestRunningAppAnswer(TQuery query, TValue expected, TValue sentinel, int nullOutputResult) {
    const std::int32_t runningAppId = sceSystemServiceGetAppIdOfRunningBigApp();
    TValue value = sentinel;
    Require(query(runningAppId, &value) == SYSTEM_SERVICE_OK && value == expected);
    Require(query(runningAppId, nullptr) == nullOutputResult);
    for (const std::int32_t other : {runningAppId + 1, runningAppId - 1, -1, std::numeric_limits<std::int32_t>::min(), std::numeric_limits<std::int32_t>::max()}) {
    Require(query(other, nullptr) == nullOutputResult);
    }
    }
  • NotImplemented_nid_no_patch((std::string(caller) + ": a mode other than 0 and 1").c_str());
  • if (appId != SYSTEM_SERVICE_RUNNING_APP_ID) NotImplemented_nid_no_patch((std::string(caller) + ": application other than the running title").c_str());
  • if (appId != SYSTEM_SERVICE_RUNNING_APP_ID) NotImplemented_nid_no_patch("sceShellCoreUtilGetSuspendConfirmationDialogFlag: application other than the running title");

Not verified

  • The tests were not built or run here.
  • Whether the Throws removal happened in a commit after the reviewer's 10-29 comment: I only compared content at the head.

# Conflicts:
#	core/libs/prx/libSceSystemService/PendingExports.cpp
@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Nov 2, 2026
@oneandonlydean
oneandonlydean merged commit eb5537b into boykopovar:main Nov 2, 2026
11 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.

4 participants