From a2ee73679353dc9d97eb61a7e1624a0f7ca76bec Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 30 Nov 2012 23:06:27 -0800 Subject: [PATCH] Process events when idle or switching threads. Fixes hrydgard/ppsspp#104, so things execute more accurately. --- Core/CoreTiming.cpp | 16 +++++++++++++++- Core/HLE/sceKernelThread.cpp | 8 ++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index d5b71ec23..57a79e581 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -500,6 +500,20 @@ void Idle(int maxIdle) if (maxIdle != 0 && cyclesDown > maxIdle) cyclesDown = maxIdle; + if (first && cyclesDown > 0) + { + int cyclesExecuted = slicelength - downcount; + int cyclesNextEvent = (int) (first->time - globalTimer); + + if (cyclesNextEvent < cyclesExecuted + cyclesDown) + { + cyclesDown = cyclesNextEvent - cyclesExecuted; + // Now, now... no time machines, please. + if (cyclesDown < 0) + cyclesDown = 0; + } + } + DEBUG_LOG(CPU, "Idle for %i cycles! (%f ms)", cyclesDown, cyclesDown / (float)(CPU_HZ * 0.001f)); idledCycles += cyclesDown; @@ -520,7 +534,7 @@ std::string GetScheduledEventsSummary() if (!name) name = "[unknown]"; char temp[512]; - sprintf(temp, "%s : %i %08x%08x\n", event_types[ptr->type].name, (int)ptr->time, (u32)(ptr->userdata >> 32), (u32)(ptr->userdata)); + sprintf(temp, "%s : %i %08x%08x\n", name, (int)ptr->time, (u32)(ptr->userdata >> 32), (u32)(ptr->userdata)); text += temp; ptr = ptr->next; } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index c20a70c95..3d15e657b 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -730,6 +730,14 @@ void __KernelReSchedule(const char *reason) return; } + // Execute any pending events while we're doing scheduling. + CoreTiming::Advance(); + if (__IsInInterrupt() || __KernelInCallback()) + { + reason = "In Interrupt Or Callback"; + return; + } + retry: Thread *nextThread = __KernelNextThread();