From f530be096982fed5d76eb7f59c886f3089bcf1fa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 14 Aug 2021 20:15:34 -0700 Subject: [PATCH] Dialog: Prevent reschedule on shutdown start. This is a bit strange, but tests seem to suggest this is correct. A worse priority thread won't run before savedata shutdown hits 0, but the thread that initiated shutdown runs before shutdown completes. Fixes Freakout Extreme Freeride loading savedata. --- Core/Dialog/PSPDialog.cpp | 2 +- Core/HLE/sceKernelInterrupt.cpp | 4 ---- Core/HLE/sceKernelInterrupt.h | 2 ++ Core/HLE/sceKernelThread.cpp | 3 ++- Core/HLE/sceUtility.cpp | 5 +++++ 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index 2783d291dd..3670d15ac8 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -122,7 +122,7 @@ void PSPDialog::ChangeStatusInit(int delayUs) { void PSPDialog::ChangeStatusShutdown(int delayUs) { // If we're doing shutdown right away and skipped start, we don't run the dialog thread. - bool skipDialogShutdown = status == SCE_UTILITY_STATUS_NONE; + bool skipDialogShutdown = status == SCE_UTILITY_STATUS_NONE && pendingStatus == SCE_UTILITY_STATUS_NONE; ChangeStatus(SCE_UTILITY_STATUS_SHUTDOWN, 0); auto params = GetCommonParam(); diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 88a3848be5..cfad674c51 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -40,10 +40,6 @@ #include "GPU/GPUCommon.h" #include "GPU/GPUState.h" -void __DisableInterrupts(); -void __EnableInterrupts(); -bool __InterruptsEnabled(); - // Seems like some > 16 are taken but not available. Probably kernel only? static const u32 PSP_NUMBER_SUBINTERRUPTS = 32; diff --git a/Core/HLE/sceKernelInterrupt.h b/Core/HLE/sceKernelInterrupt.h index 013b46585c..3f32e3049b 100644 --- a/Core/HLE/sceKernelInterrupt.h +++ b/Core/HLE/sceKernelInterrupt.h @@ -128,6 +128,8 @@ private: std::map subIntrHandlers; }; +void __DisableInterrupts(); +void __EnableInterrupts(); bool __InterruptsEnabled(); bool __IsInInterrupt(); void __InterruptsInit(); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 58a9582b7f..b1abcfb08c 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2063,7 +2063,8 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo Core_ExecException(startThread->context.pc, currentMIPS->pc, ExecExceptionType::THREAD); } __KernelChangeReadyState(cur, currentThread, true); - hleReSchedule("thread started"); + if (__InterruptsEnabled()) + hleReSchedule("thread started"); } // Starting a thread automatically resumes the dispatch thread if the new thread has worse priority. diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index f33bbe4a72..51eaa18a91 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -35,6 +35,7 @@ #include "Core/System.h" #include "Core/HLE/sceKernel.h" +#include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/scePower.h" @@ -325,8 +326,12 @@ void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int priority) { CleanupDialogThreads(); _assert_(accessThread == nullptr); + bool prevInterrupts = __InterruptsEnabled(); + __DisableInterrupts(); accessThread = new HLEHelperThread("ScePafJob", insts, (uint32_t)ARRAY_SIZE(insts), priority, 0x200); accessThread->Start(partDelay, 0); + if (prevInterrupts) + __EnableInterrupts(); } static int UtilityWorkUs(int us) {