Merge pull request #4077 from hugodearaujo/fix/sched-priority-range

fix(libkernel): report the console's scheduling priority range
This commit is contained in:
Dean 2026-10-12 21:38:56 +13:00 committed by GitHub
commit 10aff1c663
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 22 additions and 13 deletions

View File

@ -107,9 +107,8 @@ ProcessArguments& getProcessArguments() {
return arguments;
}
void validateSchedulingPolicy(int policy) {
if (policy < 1 || policy > 3)
throw std::invalid_argument("Unsupported guest scheduling policy");
bool hasPriorityRange(int policy) {
return policy == 1 || policy == 3;
}
constexpr int guestFault = 14;
@ -363,13 +362,19 @@ void APS5_VABI sync_nid_postfix(void) {
}
int APS5_VABI sched_get_priority_max_nid_postfix(int policy) {
validateSchedulingPolicy(policy);
return 256;
if (!hasPriorityRange(policy)) {
*__error_nid_postfix() = guestInvalid;
return -1;
}
return 767;
}
int APS5_VABI sched_get_priority_min_nid_postfix(int policy) {
validateSchedulingPolicy(policy);
return 767;
if (!hasPriorityRange(policy)) {
*__error_nid_postfix() = guestInvalid;
return -1;
}
return 256;
}
int APS5_VABI getrusage_nid_postfix(int who, GuestResourceUsage* usage) {

View File

@ -1,19 +1,23 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdlib>
#include <stdexcept>
extern "C" int* APS5_VABI __error_nid_postfix();
extern "C" {
int APS5_VABI sched_get_priority_max_nid_postfix(int policy);
int APS5_VABI sched_get_priority_min_nid_postfix(int policy);
}
static void Require(bool value) { if (!value) std::abort(); }
static bool Rejects(int policy) {
try { sched_get_priority_max_nid_postfix(policy); } catch (const std::invalid_argument&) { return true; }
return false;
*__error_nid_postfix() = 0;
const bool max = sched_get_priority_max_nid_postfix(policy) == -1 && *__error_nid_postfix() == 22;
*__error_nid_postfix() = 0;
return max && sched_get_priority_min_nid_postfix(policy) == -1 && *__error_nid_postfix() == 22;
}
int main() {
for (int policy : {1, 2, 3}) {
Require(sched_get_priority_max_nid_postfix(policy) == 256);
Require(sched_get_priority_min_nid_postfix(policy) == 767);
Require(Rejects(-1) && Rejects(2) && Rejects(5));
for (int policy : {1, 3}) {
Require(sched_get_priority_max_nid_postfix(policy) == 767);
Require(sched_get_priority_min_nid_postfix(policy) == 256);
}
Require(Rejects(0) && Rejects(4));
}

View File

@ -372,7 +372,7 @@ Throughout the project, every function at every stage either **does exactly what
- [scePlayerReviewDialogOpen, scePlayerReviewDialogGetResult](../../core/libs/prx/libSceCdlgPlayerReview/Export.cpp) (libSceCdlgPlayerReview) - the PS5-only dialog has no public reference: the parameter is not read and the result is assumed to start with the 32-bit common dialog result, as `sceWebBrowserDialogGetResult` assumes
- [sceHttpWaitRequest](../../core/libs/prx/libSceHttp/Export.cpp) (libSceHttp) - the timeout is assumed to be in microseconds and a negative timeout to wait without limit; the invalid-value error for a null handle or event array or a non-positive event count is assumed, not measured. No request is ever pending, so a wait returns 0 events when its timeout passes
- [sceVideoOutAddPreVblankStartEvent](../../core/libs/prx/libSceVideoOut/src/Event.cpp) (libSceVideoOut) - how long before the vblank the console signals pre-vblank start is unknown. The event is triggered on each emulated vblank tick immediately before the vblank event, with its own count as the event data
- [sched_get_priority_max, sched_get_priority_min](../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) - `SCHED_OTHER` (2) reports the same 256 to 767 range as `SCHED_FIFO` and `SCHED_RR`; the console's answer is unverified. FreeBSD accepts `SCHED_OTHER` with its own range, and shadPS4 rejects it with `EINVAL`. `pthread_setschedparam` ignores the policy, so a priority taken from this range applies
- [sched_get_priority_max, sched_get_priority_min](../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) - measured on a PS5 (firmware 13.60): `SCHED_FIFO` (1) and `SCHED_RR` (3) report a maximum of 767 and a minimum of 256, and every other policy, `SCHED_OTHER` (2) included, returns -1 with `EINVAL`. `pthread_setschedparam` ignores the policy and does not check the priority, where the console rejects `SCHED_OTHER` and priorities below 256 with `EINVAL`
- [inet_pton, inet_ntop](../../core/libs/prx/libkernel/Socket/src/AddressConversion.cpp) (libkernel) - the text forms are assumed to be those of FreeBSD 11.4 and are unverified on a console: `inet_pton` accepts only four decimal parts without leading zeros for `AF_INET` and the RFC 4291 forms for `AF_INET6` (one `::` standing for at least one group, a dotted-quad tail only as the last 32 bits, no zone id), and `inet_ntop` prints lowercase hex with the first longest run of two or more zero groups compressed, and a dotted tail only for `::a.b.c.d` and `::ffff:a.b.c.d`. They no longer depend on the host resolver library
- [gethostbyname](../../core/libs/prx/libScePosixForWebKit/Resolver.cpp) (libScePosixForWebKit) - numeric IPv4 forms, trailing whitespace and 64-bit accumulation follow FreeBSD 11.4 [inet_aton](https://github.com/freebsd/freebsd-src/blob/releng/11.4/lib/libc/inet/inet_addr.c); clearing the resolver error on numeric success follows [fakeaddr](https://github.com/freebsd/freebsd-src/blob/releng/11.4/lib/libc/net/gethostnamadr.c). Exact PS5 behavior is unverified; hostname lookup still uses the host resolver