diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index b4132b0f9a..8cd668313b 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1629,8 +1629,17 @@ static PSPThread *__KernelNextThread() { return 0; } +// Set by sceKernelStartThread when the new thread outranks the caller, for the reschedule right +// after it. The firmware hands the CPU straight to the new thread, even when a thread of better +// priority is ready but hasn't been dispatched (say, one that a sceKernelTerminateThread woke.) +// See tests/threads/threads/termsuspended. +static SceUID g_startThreadHandoff = 0; + void __KernelReSchedule(const char *reason) { + const SceUID handoff = g_startThreadHandoff; + g_startThreadHandoff = 0; + // First, let's check if there are any pending callbacks to trigger. // TODO: Could probably take this out of __KernelReSchedule() which is a bit hot. __KernelCheckCallbacks(); @@ -1643,6 +1652,16 @@ void __KernelReSchedule(const char *reason) return; } + if (handoff != 0) { + u32 error; + PSPThread *started = kernelObjects.Get(handoff, error); + if (started && started->nt.status == THREADSTATUS_READY) { + threadReadyQueue.remove(started->nt.currentPriority, handoff); + __KernelSwitchContext(started, reason); + return; + } + } + PSPThread *nextThread = __KernelNextThread(); if (nextThread) { __KernelSwitchContext(nextThread, reason); @@ -1971,8 +1990,10 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo if (cur && cur->nt.currentPriority > startThread->nt.currentPriority) { KernelValidateThreadTarget(startThread->context.pc); __KernelChangeReadyState(cur, currentThread, true); - if (__InterruptsEnabled()) + if (__InterruptsEnabled()) { + g_startThreadHandoff = threadToStartID; hleReSchedule("thread started"); + } } // Starting a thread automatically resumes the dispatch thread if the new thread has worse priority. diff --git a/pspautotests b/pspautotests index fa87488fb7..c67239046d 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit fa87488fb7f034ce006490285297ca290d8d23b7 +Subproject commit c67239046db47d83351ced09e4e66d0cf3382f9c