diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index d23861dd6..200343e6e 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "HLE.h" #include "../MIPS/MIPS.h" #include "../../Core/CoreTiming.h" @@ -279,6 +280,15 @@ void __KernelSemaTimeout(u64 userdata, int cycleslate) if (timeoutPtr != 0) Memory::Write_U32(0, timeoutPtr); + SceUID semaID = __KernelGetWaitID(threadID, error); + Semaphore *s = kernelObjects.Get(semaID, error); + if (s) + { + // This thread isn't waiting anymore. + s->waitingThreads.erase(std::remove(s->waitingThreads.begin(), s->waitingThreads.end(), threadID), s->waitingThreads.end()); + s->ns.numWaitThreads--; + } + __KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT); } @@ -301,6 +311,12 @@ void __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *ba Semaphore *s = kernelObjects.Get(id, error); if (s) { + if (wantedCount > s->ns.maxCount || wantedCount <= 0) + { + RETURN(SCE_KERNEL_ERROR_ILLEGAL_COUNT); + return; + } + // We need to set the return value BEFORE processing callbacks / etc. RETURN(0); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 49d645e25..5b35f8c05 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -402,7 +402,21 @@ u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error) } else { - ERROR_LOG(HLE, "__KernelGetWaitValue ERROR: thread %i", threadID); + ERROR_LOG(HLE, "__KernelGetWaitTimeoutPtr ERROR: thread %i", threadID); + return 0; + } +} + +SceUID __KernelGetWaitID(SceUID threadID, u32 &error) +{ + Thread *t = kernelObjects.Get(threadID, error); + if (t) + { + return t->nt.waitID; + } + else + { + ERROR_LOG(HLE, "__KernelGetWaitID ERROR: thread %i", threadID); return 0; } } diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 57f07b8e1..208ec838b 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -107,6 +107,7 @@ u32 __KernelResumeThreadFromWait(SceUID threadID, int retval); u32 __KernelGetWaitValue(SceUID threadID, u32 &error); u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error); +SceUID __KernelGetWaitID(SceUID threadID, u32 &error); void __KernelWaitCurThread(WaitType type, SceUID waitId, u32 waitValue, u32 timeoutPtr, bool processCallbacks); void __KernelReSchedule(const char *reason = "no reason"); void __KernelReSchedule(bool doCallbacks, const char *reason); diff --git a/test.py b/test.py index b6bbb1967..b91fa7957 100644 --- a/test.py +++ b/test.py @@ -34,7 +34,6 @@ tests_good = [ "threads/mutex/mutex", "threads/mutex/delete/delete", "threads/semaphores/semaphores", - "threads/semaphores/cancel/cancel", "threads/semaphores/delete/delete", "threads/semaphores/poll/poll", "threads/semaphores/refer/refer", @@ -56,6 +55,7 @@ tests_next = [ "threads/mutex/try/try", "threads/mutex/unlock/unlock", "threads/scheduling/scheduling", + "threads/semaphores/cancel/cancel", "threads/semaphores/create/create", "threads/semaphores/priority/priority", "threads/semaphores/wait/wait",