From 0c41d4e9524363f3798e468bad72cc5889fd08da Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 8 Jun 2013 23:39:49 -0700 Subject: [PATCH] Don't allow release wait for HLE delays. Although, presumably the thread would stop waiting, I guess the HLE func in most cases probably checks and re-waits? Fixes breakage in Jeanne d' Arc, which constantly releases from wait the main thread, but calls things like sceMpegCreate which do block. --- Core/HLE/HLE.cpp | 6 +++--- Core/HLE/sceKernelThread.cpp | 5 +++++ Core/HLE/sceKernelThread.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index a8efcd4444..65f49d16d9 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -64,7 +64,7 @@ void hleDelayResultFinish(u64 userdata, int cycleslate) { u32 error; SceUID threadID = (SceUID) userdata; - SceUID verify = __KernelGetWaitID(threadID, WAITTYPE_DELAY, error); + SceUID verify = __KernelGetWaitID(threadID, WAITTYPE_HLEDELAY, error); // The top 32 bits of userdata are the top 32 bits of the 64 bit result. // We can't just put it all in userdata because we need to know the threadID... u64 result = (userdata & 0xFFFFFFFF00000000ULL) | __KernelGetWaitValue(threadID, error); @@ -335,7 +335,7 @@ u32 hleDelayResult(u32 result, const char *reason, int usec) if (__KernelIsDispatchEnabled()) { CoreTiming::ScheduleEvent(usToCycles(usec), delayedResultEvent, __KernelGetCurThread()); - __KernelWaitCurThread(WAITTYPE_DELAY, 1, result, 0, false, reason); + __KernelWaitCurThread(WAITTYPE_HLEDELAY, 1, result, 0, false, reason); } else WARN_LOG(HLE, "Dispatch disabled, not delaying HLE result (right thing to do?)"); @@ -348,7 +348,7 @@ u64 hleDelayResult(u64 result, const char *reason, int usec) { u64 param = (result & 0xFFFFFFFF00000000) | __KernelGetCurThread(); CoreTiming::ScheduleEvent(usToCycles(usec), delayedResultEvent, param); - __KernelWaitCurThread(WAITTYPE_DELAY, 1, (u32) result, 0, false, reason); + __KernelWaitCurThread(WAITTYPE_HLEDELAY, 1, (u32) result, 0, false, reason); } else WARN_LOG(HLE, "Dispatch disabled, not delaying HLE result (right thing to do?)"); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 0f978cf538..e187966f99 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2543,6 +2543,11 @@ int sceKernelReleaseWaitThread(SceUID threadID) { if (!t->isWaiting()) return SCE_KERNEL_ERROR_NOT_WAIT; + if (t->nt.waitType == WAITTYPE_HLEDELAY) + { + WARN_LOG_REPORT(HLE, "sceKernelReleaseWaitThread(): Refusing to wake HLE-delayed thread, right thing to do?"); + return SCE_KERNEL_ERROR_NOT_WAIT; + } __KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_RELEASE_WAIT); hleReSchedule("thread released from wait"); diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index cd08d1c743..52f2973ef5 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -90,6 +90,7 @@ enum WaitType WAITTYPE_GEDRAWSYNC = 17, WAITTYPE_GELISTSYNC = 18, WAITTYPE_MODULE = 19, + WAITTYPE_HLEDELAY = 20, NUM_WAITTYPES };