From 2ac5bcff1fd4d45ed8a807bf80bc73d147988e9f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 14 Sep 2013 18:43:23 -0700 Subject: [PATCH] Process savestates during single stepping. This way we can handle them on the same thread, without weird delays. --- Core/Core.cpp | 41 ++++++++++++++++++++++++++++------------- Core/Core.h | 1 + Core/SaveState.cpp | 11 +++-------- Core/System.cpp | 3 ++- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index c1ef112f69..a654001444 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -25,6 +25,7 @@ #include "Core/Core.h" #include "Core/Config.h" #include "Core/MemMap.h" +#include "Core/SaveState.h" #include "Core/System.h" #include "Core/MIPS/MIPS.h" #ifdef _WIN32 @@ -36,10 +37,11 @@ #include "Core/Debugger/Breakpoints.h" -event m_hStepEvent; -recursive_mutex m_hStepMutex; -event m_hInactiveEvent; -recursive_mutex m_hInactiveMutex; +static event m_hStepEvent; +static recursive_mutex m_hStepMutex; +static event m_hInactiveEvent; +static recursive_mutex m_hInactiveMutex; +static bool singleStepPending = false; #ifdef _WIN32 InputState input_state; @@ -151,6 +153,12 @@ void Core_RunLoop() } void Core_DoSingleStep() +{ + singleStepPending = true; + m_hStepEvent.notify_one(); +} + +void Core_UpdateSingleStep() { m_hStepEvent.notify_one(); } @@ -175,18 +183,22 @@ reswitch: switch (coreState) { case CORE_RUNNING: - //1: enter a fast runloop + // enter a fast runloop Core_RunLoop(); break; // We should never get here on Android. case CORE_STEPPING: + singleStepPending = false; if (coreStatePending) { coreStatePending = false; m_hInactiveEvent.notify_one(); } - //1: wait for step command.. + // Check if there's any pending savestate actions. + SaveState::Process(); + + // wait for step command.. #if defined(USING_QT_UI) || defined(_DEBUG) host->UpdateDisassembly(); host->UpdateMemView(); @@ -198,18 +210,21 @@ reswitch: #if defined(USING_QT_UI) || defined(_DEBUG) host->SendCoreWait(false); #endif - if (coreState == CORE_POWERDOWN) - return; - if (coreState != CORE_STEPPING) #if defined(USING_QT_UI) && !defined(USING_GLES2) + if (coreState != CORE_STEPPING) return; -#else - goto reswitch; #endif + // No step pending? Let's go back to the wait. + if (!singleStepPending || coreState != CORE_STEPPING) { + if (coreState == CORE_POWERDOWN) { + return; + } + goto reswitch; + } currentCPU = &mipsr4k; Core_SingleStep(); - //4: update disasm dialog + // update disasm dialog #if defined(USING_QT_UI) || defined(_DEBUG) host->UpdateDisassembly(); host->UpdateMemView(); @@ -218,7 +233,7 @@ reswitch: case CORE_POWERDOWN: case CORE_ERROR: - //1: Exit loop!! + // Exit loop!! if (coreStatePending) { coreStatePending = false; m_hInactiveEvent.notify_one(); diff --git a/Core/Core.h b/Core/Core.h index b26103b740..70d21945d0 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -28,6 +28,7 @@ void Core_ErrorPause(); // called from gui void Core_EnableStepping(bool step); void Core_DoSingleStep(); +void Core_UpdateSingleStep(); void Core_Halt(const char *msg); diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index c424434af6..83282f5e4e 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -83,15 +83,10 @@ namespace SaveState std::lock_guard guard(mutex); pending.push_back(op); - // Don't actually run it until next CoreTiming::Advance(). + // Don't actually run it until next frame. // It's possible there might be a duplicate but it won't hurt us. - if (Core_IsInactive() && __KernelIsRunning()) { - // Warning: this may run on a different thread. - needsProcess = true; - Process(); - } else { - needsProcess = true; - } + needsProcess = true; + Core_UpdateSingleStep(); } void Load(const std::string &filename, Callback callback, void *cbUserData) diff --git a/Core/System.cpp b/Core/System.cpp index f652ad960c..a7ff591c50 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -252,6 +252,7 @@ void Core_UpdateState(CoreState newState) { if ((coreState == CORE_RUNNING || coreState == CORE_NEXTFRAME) && newState != CORE_RUNNING) coreStatePending = true; coreState = newState; + Core_UpdateSingleStep(); } bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { @@ -286,7 +287,7 @@ bool PSP_IsInited() { void PSP_Shutdown() { if (coreState == CORE_RUNNING) - coreState = CORE_ERROR; + Core_UpdateState(CORE_ERROR); if (cpuThread != NULL) { CPU_SetState(CPU_THREAD_SHUTDOWN); CPU_WaitStatus(&CPU_IsShutdown);