From 45a561aea5b3fad72dbedbe932fefb17b66f2d6d Mon Sep 17 00:00:00 2001 From: Lexroid Date: Sat, 10 Oct 2026 14:41:37 +0300 Subject: [PATCH] fix(libkernel): accept a zero count in sceKernelSignalSema sceKernelSignalSema threw invalid_argument for a count of 0. Marvel's Wolverine (PPSA03671) signals with a count computed as min(a, b) - c, which can be 0, and ignores the result, so the throw ended the title a few minutes in. A zero count now adds no tokens and returns SCE_OK, as in shadPS4 and Kyty. A null semaphore and a negative count still throw. guest_kernel_errors signals 0 on a full and on an empty semaphore and checks that the count is unchanged. Co-Authored-By: Claude Opus 5.5 (cherry picked from commit 7191d34c4d79622ba71087f0da2b75eb81ad2c23) --- core/libs/prx/libkernel/Semaphore/src/Semaphore.cpp | 2 +- core/libs/tests/GuestKernelErrors.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libkernel/Semaphore/src/Semaphore.cpp b/core/libs/prx/libkernel/Semaphore/src/Semaphore.cpp index 46490e9a7..8210cdb99 100644 --- a/core/libs/prx/libkernel/Semaphore/src/Semaphore.cpp +++ b/core/libs/prx/libkernel/Semaphore/src/Semaphore.cpp @@ -36,7 +36,7 @@ int APS5_VABI sceKernelPollSema(KernelSema sem, int need) { } int APS5_VABI sceKernelSignalSema(KernelSema sem, int count) { - if (sem == nullptr || count <= 0) { + if (sem == nullptr || count < 0) { APS5_INVALID_ARG_EX; } diff --git a/core/libs/tests/GuestKernelErrors.cpp b/core/libs/tests/GuestKernelErrors.cpp index ddb8828a5..5c14f7fca 100644 --- a/core/libs/tests/GuestKernelErrors.cpp +++ b/core/libs/tests/GuestKernelErrors.cpp @@ -62,7 +62,10 @@ int main() { Require(sceKernelCreateSema(&semaphore, "limit", 1, 1, 3, nullptr) == SCE_OK); Require(sceKernelSignalSema(semaphore, 3) == SCE_KERNEL_ERROR_EINVAL); Require(sceKernelSignalSema(semaphore, 2) == SCE_OK); + Require(sceKernelSignalSema(semaphore, 0) == SCE_OK); Require(sceKernelPollSema(semaphore, 3) == SCE_OK); + Require(sceKernelSignalSema(semaphore, 0) == SCE_OK); + Require(sceKernelPollSema(semaphore, 1) == SCE_KERNEL_ERROR_EBUSY); Require(sceKernelDeleteSema(semaphore) == SCE_OK); KernelEqueue eq = 0;