mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-22 08:44:51 +00:00
Remove threads from semaphores when they timeout.
This makes wait tests *almost* pass. There's some timing related issues left, though.
This commit is contained in:
parent
fd41851503
commit
619a9906de
@ -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 <algorithm>
|
||||
#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<Semaphore>(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<Semaphore>(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);
|
||||
|
||||
|
@ -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<Thread>(threadID, error);
|
||||
if (t)
|
||||
{
|
||||
return t->nt.waitID;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(HLE, "__KernelGetWaitID ERROR: thread %i", threadID);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
2
test.py
2
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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user