Process savestates during single stepping.
This way we can handle them on the same thread, without weird delays.
This commit is contained in:
parent
2d084ec747
commit
2ac5bcff1f
4 changed files with 34 additions and 22 deletions
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -83,15 +83,10 @@ namespace SaveState
|
|||
std::lock_guard<std::recursive_mutex> 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;
|
||||
}
|
||||
Core_UpdateSingleStep();
|
||||
}
|
||||
|
||||
void Load(const std::string &filename, Callback callback, void *cbUserData)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue