Skip to content

Commit

Permalink
Debugger: Lock startup/shutdown for threadsafety.
Browse files Browse the repository at this point in the history
Otherwise things can get freed while we're trying to inspect them.
  • Loading branch information
unknownbrackets committed Jun 6, 2018
1 parent 77609bb commit e313a9b
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 23 deletions.
9 changes: 4 additions & 5 deletions Core/Core.cpp
Expand Up @@ -55,7 +55,7 @@ static std::condition_variable m_InactiveCond;
static std::mutex m_hInactiveMutex; static std::mutex m_hInactiveMutex;
static bool singleStepPending = false; static bool singleStepPending = false;
static int steppingCounter = 0; static int steppingCounter = 0;
static std::set<Core_ShutdownFunc> shutdownFuncs; static std::set<CoreLifecycleFunc> shutdownFuncs;
static bool windowHidden = false; static bool windowHidden = false;
static double lastActivity = 0.0; static double lastActivity = 0.0;
static double lastKeepAwake = 0.0; static double lastKeepAwake = 0.0;
Expand All @@ -76,13 +76,13 @@ void Core_NotifyActivity() {
lastActivity = time_now_d(); lastActivity = time_now_d();
} }


void Core_ListenShutdown(Core_ShutdownFunc func) { void Core_ListenLifecycle(CoreLifecycleFunc func) {
shutdownFuncs.insert(func); shutdownFuncs.insert(func);
} }


void Core_NotifyShutdown() { void Core_NotifyLifecycle(CoreLifecycle stage) {
for (auto it = shutdownFuncs.begin(); it != shutdownFuncs.end(); ++it) { for (auto it = shutdownFuncs.begin(); it != shutdownFuncs.end(); ++it) {
(*it)(); (*it)(stage);
} }
} }


Expand All @@ -98,7 +98,6 @@ void Core_Halt(const char *msg) {


void Core_Stop() { void Core_Stop() {
Core_UpdateState(CORE_POWERDOWN); Core_UpdateState(CORE_POWERDOWN);
Core_NotifyShutdown();
m_StepCond.notify_all(); m_StepCond.notify_all();
} }


Expand Down
15 changes: 12 additions & 3 deletions Core/Core.h
Expand Up @@ -38,9 +38,18 @@ void Core_UpdateSingleStep();
// Changes every time we enter stepping. // Changes every time we enter stepping.
int Core_GetSteppingCounter(); int Core_GetSteppingCounter();


typedef void (* Core_ShutdownFunc)(); enum class CoreLifecycle {
void Core_ListenShutdown(Core_ShutdownFunc func); STARTING,
void Core_NotifyShutdown(); // Note: includes failure cases. Guaranteed call after STARTING.
START_COMPLETE,
STOPPING,
// Guaranteed call after STOPPING.
STOPPED,
};

typedef void (* CoreLifecycleFunc)(CoreLifecycle stage);
void Core_ListenLifecycle(CoreLifecycleFunc func);
void Core_NotifyLifecycle(CoreLifecycle stage);
void Core_Halt(const char *msg); void Core_Halt(const char *msg);


bool Core_IsStepping(); bool Core_IsStepping();
Expand Down
10 changes: 6 additions & 4 deletions Core/HLE/sceIo.cpp
Expand Up @@ -496,10 +496,12 @@ static void __IoManagerThread() {
} }
} }


static void __IoWakeManager() { static void __IoWakeManager(CoreLifecycle stage) {
// Ping the thread so that it knows to check coreState. // Ping the thread so that it knows to check coreState.
ioManagerThreadEnabled = false; if (stage == CoreLifecycle::STOPPING) {
ioManager.FinishEventLoop(); ioManagerThreadEnabled = false;
ioManager.FinishEventLoop();
}
} }


static void __IoVblank() { static void __IoVblank() {
Expand Down Expand Up @@ -586,7 +588,7 @@ void __IoInit() {
ioManagerThreadEnabled = g_Config.bSeparateIOThread; ioManagerThreadEnabled = g_Config.bSeparateIOThread;
ioManager.SetThreadEnabled(ioManagerThreadEnabled); ioManager.SetThreadEnabled(ioManagerThreadEnabled);
if (ioManagerThreadEnabled) { if (ioManagerThreadEnabled) {
Core_ListenShutdown(&__IoWakeManager); Core_ListenLifecycle(&__IoWakeManager);
ioManagerThread = new std::thread(&__IoManagerThread); ioManagerThread = new std::thread(&__IoManagerThread);
ioManagerThread->detach(); ioManagerThread->detach();
} }
Expand Down
19 changes: 14 additions & 5 deletions Core/System.cpp
Expand Up @@ -317,6 +317,7 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
INFO_LOG(BOOT, "PPSSPP %s", PPSSPP_GIT_VERSION); INFO_LOG(BOOT, "PPSSPP %s", PPSSPP_GIT_VERSION);
#endif #endif


Core_NotifyLifecycle(CoreLifecycle::STARTING);
GraphicsContext *temp = coreParameter.graphicsContext; GraphicsContext *temp = coreParameter.graphicsContext;
coreParameter = coreParam; coreParameter = coreParam;
if (coreParameter.graphicsContext == nullptr) { if (coreParameter.graphicsContext == nullptr) {
Expand All @@ -331,6 +332,7 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
*error_string = coreParameter.errorString; *error_string = coreParameter.errorString;
bool success = coreParameter.fileToStart != ""; bool success = coreParameter.fileToStart != "";
if (!success) { if (!success) {
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
pspIsIniting = false; pspIsIniting = false;
} }
return success; return success;
Expand Down Expand Up @@ -361,6 +363,9 @@ bool PSP_InitUpdate(std::string *error_string) {


pspIsInited = GPU_IsReady(); pspIsInited = GPU_IsReady();
pspIsIniting = !pspIsInited; pspIsIniting = !pspIsInited;
if (pspIsInited) {
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
}
return pspIsInited; return pspIsInited;
} }


Expand All @@ -386,17 +391,20 @@ void PSP_Shutdown() {
return; return;
} }


// Make sure things know right away that PSP memory, etc. is going away.
pspIsQuitting = true;
if (coreState == CORE_RUNNING)
Core_UpdateState(CORE_ERROR);

#ifndef MOBILE_DEVICE #ifndef MOBILE_DEVICE
if (g_Config.bFuncHashMap) { if (g_Config.bFuncHashMap) {
MIPSAnalyst::StoreHashMap(); MIPSAnalyst::StoreHashMap();
} }
#endif #endif


// Make sure things know right away that PSP memory, etc. is going away. if (pspIsIniting)
pspIsQuitting = true; Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
if (coreState == CORE_RUNNING) Core_NotifyLifecycle(CoreLifecycle::STOPPING);
Core_UpdateState(CORE_ERROR);
Core_NotifyShutdown();
CPU_Shutdown(); CPU_Shutdown();
GPU_Shutdown(); GPU_Shutdown();
g_paramSFO.Clear(); g_paramSFO.Clear();
Expand All @@ -406,6 +414,7 @@ void PSP_Shutdown() {
pspIsIniting = false; pspIsIniting = false;
pspIsQuitting = false; pspIsQuitting = false;
g_Config.unloadGameConfig(); g_Config.unloadGameConfig();
Core_NotifyLifecycle(CoreLifecycle::STOPPED);
} }


void PSP_BeginHostFrame() { void PSP_BeginHostFrame() {
Expand Down
10 changes: 6 additions & 4 deletions GPU/Debugger/Stepping.cpp
Expand Up @@ -197,10 +197,12 @@ void ResumeFromStepping() {
SetPauseAction(PAUSE_CONTINUE, false); SetPauseAction(PAUSE_CONTINUE, false);
} }


void ForceUnpause() { void ForceUnpause(CoreLifecycle stage) {
SetPauseAction(PAUSE_CONTINUE, false); if (stage == CoreLifecycle::STOPPING) {
actionComplete = true; SetPauseAction(PAUSE_CONTINUE, false);
actionWait.notify_all(); actionComplete = true;
actionWait.notify_all();
}
} }


} // namespace } // namespace
3 changes: 2 additions & 1 deletion GPU/Debugger/Stepping.h
Expand Up @@ -20,6 +20,7 @@
#include <functional> #include <functional>


#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/Core.h"
#include "GPU/Common/GPUDebugInterface.h" #include "GPU/Common/GPUDebugInterface.h"


namespace GPUStepping { namespace GPUStepping {
Expand All @@ -37,5 +38,5 @@ namespace GPUStepping {
bool GPU_SetCmdValue(u32 op); bool GPU_SetCmdValue(u32 op);


void ResumeFromStepping(); void ResumeFromStepping();
void ForceUnpause(); void ForceUnpause(CoreLifecycle stage);
}; };
2 changes: 1 addition & 1 deletion Windows/GEDebugger/GEDebugger.cpp
Expand Up @@ -67,7 +67,7 @@ void CGEDebugger::Init() {
CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent) { : Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent) {
GPUBreakpoints::Init(); GPUBreakpoints::Init();
Core_ListenShutdown(ForceUnpause); Core_ListenLifecycle(ForceUnpause);


// minimum size = a little more than the default // minimum size = a little more than the default
RECT windowRect; RECT windowRect;
Expand Down

0 comments on commit e313a9b

Please sign in to comment.