Repository navigation
fix(libkernel): report the current CPU within the thread's guest affinity - #1477
Conversation
…nity sceKernelGetCurrentCpu returned the raw host CPU index. Guest affinities are bookkeeping only and sceKernelGetAvailableCpumask advertises CPUs 0 to 12, so on a host with more than 13 logical CPUs a title could get 13 or higher, and a thread pinned to one CPU could get another one. The host index now selects a CPU of the calling thread's affinity clipped to the available mask, so the result is always an advertised CPU and a thread pinned to one CPU reports that CPU. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HeC9bA3n74TzJRYv9AgBE8
|
Tested on Windows 10 (19045), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release, Intel Core i7-12700H (20 logical CPUs). I merged it onto
Tested with AI assistance (Claude Code). |
|
Windows run, since the description says the Windows branch wasn't compiled: Windows 11 Pro (26200), MinGW-w64 GCC 15.2.0 (WinLibs r7, the CI build), Release, configured like CI, AMD Ryzen 9 5900X (12 cores / 24 threads, so host CPU numbers run past the 13-CPU guest mask). This commit merged onto
The Windows branch compiles, the processor-group index feeds AI-assisted: yes (Claude Code). |
|
Could you rebase onto current main? The full build checks out this branch with main's workflow, and it stops at |
|
Windows validation of PR head Environment: Windows 11 Pro build 26300, Intel i7-13700K (24 logical CPUs), AMD Radeon RX 6900 XT, WinLibs GCC 15.2.0 r7 (
The full suite is not clean on this GPU. Its failures were This confirms the Windows CPU-reporting contract covered by the PR, including the advertised mask and single-CPU guest affinity. It does not establish a retail-game compatibility result. Validation performed with Codex assistance. |
What
sceKernelGetCurrentCpureturned the raw host CPU index (sched_getcpu, or the Windows group-adjusted processor number). Guest thread affinities are only recorded, not applied to host threads, andsceKernelGetAvailableCpumaskadvertises CPUs 0 to 12 (0x1FFF). So on a host with more than 13 logical CPUs (a 16-thread Ryzen, for example) a title could be told it runs on CPU 13, 14, 15 or higher, outside the mask it was given, and index per-CPU data sized from that mask out of bounds. On any host, a thread the title pinned withscePthreadSetaffinityto one CPU could be told it runs on another one, which the console's FreeBSDcpusetnever allows.The host index now selects a CPU of the calling thread's guest affinity clipped to the available mask (the available mask when they do not overlap): host CPU n reports the (n modulo the number of CPUs in that mask)-th CPU of the mask. The result is always an advertised CPU, it stays within the thread's affinity, and a thread pinned to one CPU reports that CPU. Which CPU the console reports for a thread allowed on several is not known; this is recorded in TechnicalDebt. For comparison, shadPS4 returns 0 and fpPS4's older kernel returns the raw host processor number.
This PR was investigated and written by Claude Code (AI), and posted by me after review.
Tested
Linux (Arch), Intel 6-core / 12-thread laptop CPU, GTX 1050 Ti (NVIDIA 580.178.04), GCC, Release,
APS5_WRITE_WATCH_IMPORTS=watch.New
guest_current_cputest:sceKernelGetCurrentCpufrom the main thread is withinsceKernelGetAvailableCpumask;scePthreadSetaffinityto each available CPU in turn reports exactly that CPU, 64 calls each.Without the change to
sceKernelGetCurrentCputhe test fails on this 12-thread machine (a thread pinned to CPU 12, or to a CPU it is not running on, reports the host CPU).ctest -j4: 424/424 passed, 0 failed, 0 skipped (unmodified main: 423/423, 0 failed, 0 skipped; the only difference is the new test).VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ctest -j2 -V: 424/424 passed, 27Validation Errorlines with the same VUIDs and counts as unmodified main (27).Not tested on Windows; the Windows path only changes where the group-adjusted index is returned.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code
https://claude.ai/code/session_01HeC9bA3n74TzJRYv9AgBE8