From f63daf818543f04876a9fb0aa0c35cf1a2363b57 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 20 Oct 2019 10:26:37 -0700 Subject: [PATCH] Io: Change async thread priority if running. Really thought I'd already done this, must've made a mistake... Fixes #12400. --- Core/HLE/HLEHelperThread.cpp | 4 ++++ Core/HLE/HLEHelperThread.h | 1 + Core/HLE/sceIo.cpp | 4 ++++ Core/HLE/sceKernelThread.cpp | 34 +++++++++++++++++++++++----------- Core/HLE/sceKernelThread.h | 1 + 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Core/HLE/HLEHelperThread.cpp b/Core/HLE/HLEHelperThread.cpp index 21c258dfed..7f932c4a9c 100644 --- a/Core/HLE/HLEHelperThread.cpp +++ b/Core/HLE/HLEHelperThread.cpp @@ -87,6 +87,10 @@ bool HLEHelperThread::Stopped() { return KernelIsThreadDormant(id_); } +void HLEHelperThread::ChangePriority(u32 prio) { + KernelChangeThreadPriority(id_, prio); +} + void HLEHelperThread::Forget() { id_ = 0; entry_ = 0; diff --git a/Core/HLE/HLEHelperThread.h b/Core/HLE/HLEHelperThread.h index d7820bc20e..1868d309b0 100644 --- a/Core/HLE/HLEHelperThread.h +++ b/Core/HLE/HLEHelperThread.h @@ -32,6 +32,7 @@ public: void Start(u32 a0, u32 a1); void Terminate(); bool Stopped(); + void ChangePriority(u32 prio); // For savestates. void Forget(); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index da898f8d91..3ea23171c5 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1973,6 +1973,10 @@ static int sceIoChangeAsyncPriority(int id, int priority) { return hleLogError(SCEIO, error, "bad file descriptor"); } + if (asyncThreads[id] && !asyncThreads[id]->Stopped()) { + asyncThreads[id]->ChangePriority(priority); + } + asyncParams[id].priority = priority; return hleLogSuccessI(SCEIO, 0); } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 6bcccaf92e..5d9dd685fd 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2418,6 +2418,28 @@ int sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr) { return hleLogSuccessI(SCEKERNEL, 0); } +// Assumes validated parameters. +bool KernelChangeThreadPriority(SceUID threadID, int priority) { + u32 error; + Thread *thread = kernelObjects.Get(threadID, error); + if (thread) { + int old = thread->nt.currentPriority; + threadReadyQueue.remove(old, threadID); + + thread->nt.currentPriority = priority; + threadReadyQueue.prepare(thread->nt.currentPriority); + if (thread->isRunning()) { + thread->nt.status = (thread->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY; + } + if (thread->isReady()) { + threadReadyQueue.push_back(thread->nt.currentPriority, threadID); + } + return true; + } else { + return false; + } +} + int sceKernelChangeThreadPriority(SceUID threadID, int priority) { if (threadID == 0) { threadID = __KernelGetCurThread(); @@ -2444,17 +2466,7 @@ int sceKernelChangeThreadPriority(SceUID threadID, int priority) { return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "bogus priority"); } - int old = thread->nt.currentPriority; - threadReadyQueue.remove(old, threadID); - - thread->nt.currentPriority = priority; - threadReadyQueue.prepare(thread->nt.currentPriority); - if (thread->isRunning()) { - thread->nt.status = (thread->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY; - } - if (thread->isReady()) { - threadReadyQueue.push_back(thread->nt.currentPriority, threadID); - } + KernelChangeThreadPriority(threadID, priority); hleEatCycles(450); hleReSchedule("change thread priority"); diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 45b9387628..c89a373ee9 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -162,6 +162,7 @@ KernelObject *__KernelCallbackObject(); void __KernelScheduleWakeup(int threadnumber, s64 usFromNow); SceUID __KernelGetCurThread(); int KernelCurThreadPriority(); +bool KernelChangeThreadPriority(SceUID threadID, int priority); u32 __KernelGetCurThreadStack(); u32 __KernelGetCurThreadStackStart(); const char *__KernelGetThreadName(SceUID threadID);