Permalink
Browse files

Debugger: Lock startup/shutdown for threadsafety.

Otherwise things can get freed while we're trying to inspect them.
  • Loading branch information...
unknownbrackets committed Apr 22, 2018
1 parent 77609bb commit e313a9bf6ce4f08a4dc68645d784df6bfafff780
Showing with 45 additions and 23 deletions.
  1. +4 −5 Core/Core.cpp
  2. +12 −3 Core/Core.h
  3. +6 −4 Core/HLE/sceIo.cpp
  4. +14 −5 Core/System.cpp
  5. +6 −4 GPU/Debugger/Stepping.cpp
  6. +2 −1 GPU/Debugger/Stepping.h
  7. +1 −1 Windows/GEDebugger/GEDebugger.cpp
View
@@ -55,7 +55,7 @@ static std::condition_variable m_InactiveCond;
static std::mutex m_hInactiveMutex;
static bool singleStepPending = false;
static int steppingCounter = 0;
static std::set<Core_ShutdownFunc> shutdownFuncs;
static std::set<CoreLifecycleFunc> shutdownFuncs;
static bool windowHidden = false;
static double lastActivity = 0.0;
static double lastKeepAwake = 0.0;
@@ -76,13 +76,13 @@ void Core_NotifyActivity() {
lastActivity = time_now_d();
}
void Core_ListenShutdown(Core_ShutdownFunc func) {
void Core_ListenLifecycle(CoreLifecycleFunc func) {
shutdownFuncs.insert(func);
}
void Core_NotifyShutdown() {
void Core_NotifyLifecycle(CoreLifecycle stage) {
for (auto it = shutdownFuncs.begin(); it != shutdownFuncs.end(); ++it) {
(*it)();
(*it)(stage);
}
}
@@ -98,7 +98,6 @@ void Core_Halt(const char *msg) {
void Core_Stop() {
Core_UpdateState(CORE_POWERDOWN);
Core_NotifyShutdown();
m_StepCond.notify_all();
}
View
@@ -38,9 +38,18 @@ void Core_UpdateSingleStep();
// Changes every time we enter stepping.
int Core_GetSteppingCounter();
typedef void (* Core_ShutdownFunc)();
void Core_ListenShutdown(Core_ShutdownFunc func);
void Core_NotifyShutdown();
enum class CoreLifecycle {
STARTING,
// 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);
bool Core_IsStepping();
View
@@ -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.
ioManagerThreadEnabled = false;
ioManager.FinishEventLoop();
if (stage == CoreLifecycle::STOPPING) {
ioManagerThreadEnabled = false;
ioManager.FinishEventLoop();
}
}
static void __IoVblank() {
@@ -586,7 +588,7 @@ void __IoInit() {
ioManagerThreadEnabled = g_Config.bSeparateIOThread;
ioManager.SetThreadEnabled(ioManagerThreadEnabled);
if (ioManagerThreadEnabled) {
Core_ListenShutdown(&__IoWakeManager);
Core_ListenLifecycle(&__IoWakeManager);
ioManagerThread = new std::thread(&__IoManagerThread);
ioManagerThread->detach();
}
View
@@ -317,6 +317,7 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
INFO_LOG(BOOT, "PPSSPP %s", PPSSPP_GIT_VERSION);
#endif
Core_NotifyLifecycle(CoreLifecycle::STARTING);
GraphicsContext *temp = coreParameter.graphicsContext;
coreParameter = coreParam;
if (coreParameter.graphicsContext == nullptr) {
@@ -331,6 +332,7 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
*error_string = coreParameter.errorString;
bool success = coreParameter.fileToStart != "";
if (!success) {
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
pspIsIniting = false;
}
return success;
@@ -361,6 +363,9 @@ bool PSP_InitUpdate(std::string *error_string) {
pspIsInited = GPU_IsReady();
pspIsIniting = !pspIsInited;
if (pspIsInited) {
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
}
return pspIsInited;
}
@@ -386,17 +391,20 @@ void PSP_Shutdown() {
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
if (g_Config.bFuncHashMap) {
MIPSAnalyst::StoreHashMap();
}
#endif
// Make sure things know right away that PSP memory, etc. is going away.
pspIsQuitting = true;
if (coreState == CORE_RUNNING)
Core_UpdateState(CORE_ERROR);
Core_NotifyShutdown();
if (pspIsIniting)
Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE);
Core_NotifyLifecycle(CoreLifecycle::STOPPING);
CPU_Shutdown();
GPU_Shutdown();
g_paramSFO.Clear();
@@ -406,6 +414,7 @@ void PSP_Shutdown() {
pspIsIniting = false;
pspIsQuitting = false;
g_Config.unloadGameConfig();
Core_NotifyLifecycle(CoreLifecycle::STOPPED);
}
void PSP_BeginHostFrame() {
View
@@ -197,10 +197,12 @@ void ResumeFromStepping() {
SetPauseAction(PAUSE_CONTINUE, false);
}
void ForceUnpause() {
SetPauseAction(PAUSE_CONTINUE, false);
actionComplete = true;
actionWait.notify_all();
void ForceUnpause(CoreLifecycle stage) {
if (stage == CoreLifecycle::STOPPING) {
SetPauseAction(PAUSE_CONTINUE, false);
actionComplete = true;
actionWait.notify_all();
}
}
} // namespace
View
@@ -20,6 +20,7 @@
#include <functional>
#include "Common/CommonTypes.h"
#include "Core/Core.h"
#include "GPU/Common/GPUDebugInterface.h"
namespace GPUStepping {
@@ -37,5 +38,5 @@ namespace GPUStepping {
bool GPU_SetCmdValue(u32 op);
void ResumeFromStepping();
void ForceUnpause();
void ForceUnpause(CoreLifecycle stage);
};
@@ -67,7 +67,7 @@ void CGEDebugger::Init() {
CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent) {
GPUBreakpoints::Init();
Core_ListenShutdown(ForceUnpause);
Core_ListenLifecycle(ForceUnpause);
// minimum size = a little more than the default
RECT windowRect;

0 comments on commit e313a9b

Please sign in to comment.