From f1b62983b5b9299059178d19a5101ce2029d9fac Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 8 Sep 2013 12:14:07 -0700 Subject: [PATCH] Add callback wait handlers for threadend as well. --- Core/HLE/sceKernelEventFlag.cpp | 2 +- Core/HLE/sceKernelThread.cpp | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 46751f26b9..32072cc8f5 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -206,7 +206,7 @@ void __KernelEventFlagEndCallback(SceUID threadID, SceUID prevCallbackId) { auto result = HLEKernel::WaitEndCallback(threadID, prevCallbackId, eventFlagWaitTimer, __KernelUnlockEventFlagForThread); if (result == HLEKernel::WAIT_CB_RESUMED_WAIT) - DEBUG_LOG(SCEKERNEL, "sceKernelWaitEventFlagCB: Resuming lock wait for callback"); + DEBUG_LOG(SCEKERNEL, "sceKernelWaitEventFlagCB: Resuming lock wait from callback"); } //SceUID sceKernelCreateEventFlag(const char *name, int attr, int bits, SceKernelEventFlagOptParam *opt); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 4192a03bb0..2a26309494 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -991,6 +991,42 @@ void __KernelSleepEndCallback(SceUID threadID, SceUID prevCallbackId) { } } +void __KernelThreadEndBeginCallback(SceUID threadID, SceUID prevCallbackId) +{ + auto result = HLEKernel::WaitBeginCallback(threadID, prevCallbackId, eventThreadEndTimeout); + if (result == HLEKernel::WAIT_CB_SUCCESS) + DEBUG_LOG(SCEKERNEL, "sceKernelWaitThreadEndCB: Suspending wait for callback") + else if (result == HLEKernel::WAIT_CB_BAD_WAIT_DATA) + ERROR_LOG_REPORT(SCEKERNEL, "sceKernelWaitThreadEndCB: wait not found to pause for callback") + else + WARN_LOG_REPORT(SCEKERNEL, "sceKernelWaitThreadEndCB: beginning callback with bad wait id?"); +} + +bool __KernelCheckResumeThreadEnd(Thread *t, SceUID waitingThreadID, u32 &error, int result, bool &wokeThreads) +{ + if (!HLEKernel::VerifyWait(waitingThreadID, WAITTYPE_THREADEND, t->GetUID())) + return true; + + if (t->nt.status == THREADSTATUS_DORMANT) + { + u32 timeoutPtr = __KernelGetWaitTimeoutPtr(waitingThreadID, error); + s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventThreadEndTimeout, waitingThreadID); + if (timeoutPtr != 0) + Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + __KernelResumeThreadFromWait(waitingThreadID, t->nt.exitStatus); + return true; + } + + return false; +} + +void __KernelThreadEndEndCallback(SceUID threadID, SceUID prevCallbackId) +{ + auto result = HLEKernel::WaitEndCallback(threadID, prevCallbackId, eventThreadEndTimeout, __KernelCheckResumeThreadEnd); + if (result == HLEKernel::WAIT_CB_RESUMED_WAIT) + DEBUG_LOG(SCEKERNEL, "sceKernelWaitThreadEndCB: Resuming wait from callback"); +} + u32 __KernelSetThreadRA(SceUID threadID, u32 nid) { u32 newRA; @@ -1090,6 +1126,7 @@ void __KernelThreadingInit() __KernelRegisterWaitTypeFuncs(WAITTYPE_DELAY, __KernelDelayBeginCallback, __KernelDelayEndCallback); __KernelRegisterWaitTypeFuncs(WAITTYPE_SLEEP, __KernelSleepBeginCallback, __KernelSleepEndCallback); + __KernelRegisterWaitTypeFuncs(WAITTYPE_THREADEND, __KernelThreadEndBeginCallback, __KernelThreadEndEndCallback); } void __KernelThreadingDoState(PointerWrap &p)