From 4065fae262f473b61e867dda93e4073cb2d8a378 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 20 Oct 2019 10:25:57 -0700 Subject: [PATCH 1/2] Io: Destroy async threads on reset. Oops, this left us in a different state on exit. --- Core/HLE/sceIo.cpp | 9 +++++++++ Core/HLE/sceKernelThread.cpp | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index f933d88b04..da898f8d91 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -737,6 +737,15 @@ void __IoShutdown() { ioManager.Shutdown(); } + for (int i = 0; i < PSP_COUNT_FDS; ++i) { + asyncParams[i].op = IoAsyncOp::NONE; + asyncParams[i].priority = -1; + if (asyncThreads[i]) + asyncThreads[i]->Forget(); + delete asyncThreads[i]; + asyncThreads[i] = nullptr; + } + pspFileSystem.Unmount("ms0:", memstickSystem); pspFileSystem.Unmount("fatms0:", memstickSystem); pspFileSystem.Unmount("fatms:", memstickSystem); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index a56f7fa67e..6bcccaf92e 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1641,9 +1641,9 @@ void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason) // Stopped threads are never waiting. t->nt.waitType = WAITTYPE_NONE; t->nt.waitID = 0; - } - else + } else { ERROR_LOG_REPORT(SCEKERNEL, "__KernelStopThread: thread %d does not exist", threadID); + } } u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason) From f63daf818543f04876a9fb0aa0c35cf1a2363b57 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 20 Oct 2019 10:26:37 -0700 Subject: [PATCH 2/2] 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);