mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-17 16:30:30 +02:00
Legacy Win32 debugger: fix the painting problem with a frame-scoped mutex
Debugger windows (register list, disassembly view, memory view, breakpoint/ thread/module/stack lists, watch list) read CPU-thread-owned state directly from the GUI thread's WM_PAINT/list-fill handlers, racing against the CPU thread. Routing every read through Core_RunOnCPUThread would be too slow for something invoked continuously on paint/list-refresh. Add g_frameMutex (Core.h/Core.cpp), held by NativeFrame() only across the span where it actually touches that state (running the CPU, processing breakpoints, running the ImGui debugger) - not across input handling or the present/frame-pacing waits. Debugger windows now hold the same mutex while reading, giving synchronized reads without the round-trip cost of queuing to the CPU thread. CtrlRegisterList::onPaint() goes back to always reading live values (now safe under the lock) and grays them out by color alone while the core is running, rather than the earlier snapshot-caching approach. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hqm11k99viLfbJm2MkH4BH
This commit is contained in:
1 parent
03dcfd3931
commit
f72709feb0
10 files changed
+129
-38
No files matched your search
@@ -60,6 +60,10 @@ void CtrlDisAsmView::deinit()
|
||||
|
||||
void CtrlDisAsmView::scanVisibleFunctions()
|
||||
{
|
||||
// Reads live memory/symbol state to detect function boundaries - hold g_frameMutex for the
|
||||
// duration, which NativeFrame() also holds while it's actually touching that state. See
|
||||
// g_frameMutex in Core.h.
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
g_disassemblyManager.analyze(windowStart, g_disassemblyManager.getNthNextAddress(windowStart,visibleRows)-windowStart);
|
||||
}
|
||||
|
||||
@@ -453,9 +457,14 @@ void CtrlDisAsmView::drawArguments(HDC hdc, const DisassemblyLineInfo &line, int
|
||||
|
||||
void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
auto memLock = Memory::Lock();
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
if (!debugger->isAlive() || Achievements::HardcoreModeActive()) return;
|
||||
|
||||
// Reading live disassembly/symbol/breakpoint state here on the GUI thread would otherwise race
|
||||
// with the CPU thread - hold g_frameMutex for the duration of the read, which NativeFrame()
|
||||
// also holds while it's actually touching that state. See g_frameMutex in Core.h.
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
HDC actualHdc = BeginPaint(wnd, &ps);
|
||||
HDC hdc = CreateCompatibleDC(actualHdc);
|
||||
|
||||
Reference in new issue
Block a user