mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Threads: sceKernelStartThread hands the CPU straight to a better thread
When the new thread outranks the caller, the firmware switches to it directly, even if a thread of still better priority is ready but hasn't been dispatched (one that a sceKernelTerminateThread woke, say). Verified against the new pspautotests threads/threads/termsuspended. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
23fc0cd422
commit
638da935ea
2 files changed
+23
-2
No files matched your search
@@ -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<PSPThread>(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.
|
||||
|
||||
+1
-1
Submodule pspautotests updated: fa87488fb7...c67239046d.
Reference in new issue
Block a user