diff --git a/Core/Debugger/DisassemblyManager.cpp b/Core/Debugger/DisassemblyManager.cpp index 2b75d5dbce..0ba3cc1467 100644 --- a/Core/Debugger/DisassemblyManager.cpp +++ b/Core/Debugger/DisassemblyManager.cpp @@ -342,15 +342,20 @@ void DisassemblyManager::clear() DisassemblyFunction::DisassemblyFunction(u32 _address, u32 _size): address(_address), size(_size) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return; + hash = computeHash(address,size); load(); } void DisassemblyFunction::recheck() { - if (!PSP_IsInited()) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) return; - } + u32 newHash = computeHash(address,size); if (hash != newHash) { @@ -800,12 +805,20 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo& dest, bool DisassemblyData::DisassemblyData(u32 _address, u32 _size, DataType _type): address(_address), size(_size), type(_type) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return; + hash = computeHash(address,size); createLines(); } void DisassemblyData::recheck() { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return; + u32 newHash = computeHash(address,size); if (newHash != hash) { diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index ee9c9699fc..6a157fe716 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -17,6 +17,7 @@ #include +#include "base/mutex.h" #include "Common/Common.h" #include "Common/MemoryUtil.h" #ifndef __SYMBIAN32__ @@ -89,6 +90,8 @@ u32 g_MemorySize; // Used to store the PSP model on game startup. u32 g_PSPModel; +recursive_mutex g_shutdownLock; + // We don't declare the IO region in here since its handled by other means. static MemoryView views[] = { @@ -370,6 +373,7 @@ void DoState(PointerWrap &p) void Shutdown() { + lock_guard guard(g_shutdownLock); u32 flags = 0; MemoryMap_Shutdown(flags); @@ -387,6 +391,21 @@ void Clear() memset(m_pVRAM, 0, VRAM_SIZE); } +// Wanting to avoid include pollution, MemMap.h is included a lot. +MemoryInitedLock::MemoryInitedLock() +{ + g_shutdownLock.lock(); +} +MemoryInitedLock::~MemoryInitedLock() +{ + g_shutdownLock.unlock(); +} + +MemoryInitedLock Lock() +{ + return MemoryInitedLock(); +} + static Opcode Read_Instruction(u32 address, bool resolveReplacements, Opcode inst) { if (!MIPS_IS_EMUHACK(inst.encoding)) { diff --git a/Core/MemMap.h b/Core/MemMap.h index 07a829be53..d4cbf398b6 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -126,6 +126,17 @@ void Shutdown(); void DoState(PointerWrap &p); void Clear(); +class MemoryInitedLock +{ +public: + MemoryInitedLock(); + ~MemoryInitedLock(); +}; + +// This doesn't lock memory access or anything, it just makes sure memory isn't freed. +// Use it when accessing PSP memory from external threads. +MemoryInitedLock Lock(); + // used by JIT to read instructions. Does not resolve replacements. Opcode Read_Opcode_JIT(const u32 _Address); // used by JIT. Reads in the "Locked cache" mode diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 61dfd8e221..fc8de5a76d 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -203,6 +203,10 @@ COLORREF scaleColor(COLORREF color, float factor) bool CtrlDisAsmView::getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels, bool showData) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return false; + if (displaySymbols) { const std::string addressSymbol = symbolMap.GetLabelString(address); @@ -256,6 +260,7 @@ void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText) { u32 encoded; + auto memLock = Memory::Lock(); if (Core_IsStepping() == false) { MessageBox(wnd,L"Cannot change code while the core is running!",L"Error",MB_OK); return; @@ -1085,6 +1090,10 @@ void CtrlDisAsmView::onMouseMove(WPARAM wParam, LPARAM lParam, int button) void CtrlDisAsmView::updateStatusBarText() { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return; + char text[512]; DisassemblyLineInfo line; manager.getLine(curAddress,true,line); diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 8de363dc6d..d7e1ea5311 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -362,6 +362,10 @@ void CtrlMemView::onKeyDown(WPARAM wParam, LPARAM lParam) void CtrlMemView::onChar(WPARAM wParam, LPARAM lParam) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return; + if (KeyDownAsync(VK_CONTROL) || wParam == VK_TAB) return; if (!Memory::IsValidAddress(curAddress)) @@ -602,6 +606,10 @@ void CtrlMemView::scrollCursor(int bytes) void CtrlMemView::search(bool continueSearch) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return; + u32 searchAddress; if (continueSearch == false || searchQuery[0] == 0) { diff --git a/Windows/Debugger/DumpMemoryWindow.cpp b/Windows/Debugger/DumpMemoryWindow.cpp index c5b1035a05..58f6adbca1 100644 --- a/Windows/Debugger/DumpMemoryWindow.cpp +++ b/Windows/Debugger/DumpMemoryWindow.cpp @@ -69,6 +69,10 @@ INT_PTR CALLBACK DumpMemoryWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, case IDOK: if (bp->fetchDialogData(hwnd)) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + break; + FILE* output = fopen(bp->fileName,"wb"); if (output == NULL) { diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 828f32a297..662ac02b4f 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -152,6 +152,11 @@ void CGEDebugger::SetupPreviews() { } void CGEDebugger::UpdatePreviews() { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) { + return; + } + wchar_t desc[256]; const GPUDebugBuffer *primaryBuffer = NULL; bool bufferResult = false; diff --git a/Windows/GEDebugger/TabVertices.cpp b/Windows/GEDebugger/TabVertices.cpp index 38c14b68bd..7b66a2ecf6 100644 --- a/Windows/GEDebugger/TabVertices.cpp +++ b/Windows/GEDebugger/TabVertices.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "base/basictypes.h" +#include "Core/System.h" #include "Windows/resource.h" #include "Windows/GEDebugger/GEDebugger.h" #include "Windows/GEDebugger/TabVertices.h" @@ -175,6 +176,12 @@ void CtrlVertexList::FormatVertCol(wchar_t *dest, const GPUDebugVertex &vert, in } void CtrlVertexList::FormatVertColRaw(wchar_t *dest, int row, int col) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) { + wcscpy(dest, L"Invalid"); + return; + } + // We could use the vertex decoder and reader, but those already do some minor adjustments. // There's only a few values - let's just go after them directly. const u8 *vert = Memory::GetPointer(gpuDebug->GetVertexAddress()) + row * decoder->size; @@ -255,6 +262,11 @@ void CtrlVertexList::FormatVertColRawColor(wchar_t *dest, const void *data, int } int CtrlVertexList::GetRowCount() { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) { + return 0; + } + if (!gpuDebug || !Memory::IsValidAddress(gpuDebug->GetVertexAddress())) { rowCount_ = 0; return rowCount_;