Skip to content

Commit ec16aa6

Browse files
authored
Merge pull request #20072 from hrydgard/debugger-threading-improvements
UI threading improvements
2 parents 6a81164 + 2b2d239 commit ec16aa6

19 files changed

+135
-140
lines changed

Common/System/System.h

+3
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ enum class SystemRequestType {
100100
RUN_CALLBACK_IN_WNDPROC,
101101
};
102102

103+
// Run a closure on the main thread. Used to safely implement UI that runs on another thread.
104+
void System_RunOnMainThread(std::function<void()> func);
105+
103106
// Implementations are supposed to process the request, and post the response to the g_RequestManager (see Message.h).
104107
// This is not to be used directly by applications, instead use the g_RequestManager to make the requests.
105108
// This can return false if it's known that the platform doesn't support the request, the app is supposed to handle

Core/Config.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2015,7 +2015,7 @@ void Config::ResetControlLayout() {
20152015
g_Config.fRightStickHeadScale = 1.0f;
20162016
}
20172017

2018-
void Config::GetReportingInfo(UrlEncoder &data) {
2018+
void Config::GetReportingInfo(UrlEncoder &data) const {
20192019
for (size_t i = 0; i < numSections; ++i) {
20202020
const std::string prefix = std::string("config.") + sections[i].section;
20212021
for (size_t j = 0; j < sections[i].settingsCount; j++) {

Core/Config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ struct Config {
632632

633633
void ResetControlLayout();
634634

635-
void GetReportingInfo(UrlEncoder &data);
635+
void GetReportingInfo(UrlEncoder &data) const;
636636

637637
bool IsPortrait() const;
638638
int NextValidBackend();

Core/Core.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ const char *BreakReasonToString(BreakReason reason) {
108108
case BreakReason::SavestateCrash: return "savestate.crash";
109109
case BreakReason::MemoryBreakpoint: return "memory.breakpoint";
110110
case BreakReason::CpuBreakpoint: return "cpu.breakpoint";
111-
case BreakReason::BreakpointUpdate: return "cpu.breakpoint.update";
112111
case BreakReason::MemoryAccess: return "memory.access"; // ???
113112
case BreakReason::JitBranchDebug: return "jit.branchdebug";
114113
case BreakReason::RABreak: return "ra.break";

Core/Core.h

-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ enum class BreakReason {
6161
SavestateCrash,
6262
MemoryBreakpoint,
6363
CpuBreakpoint,
64-
BreakpointUpdate,
6564
MemoryAccess, // ???
6665
JitBranchDebug,
6766
BreakOnBoot,

Core/Debugger/Breakpoints.cpp

+25-58
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
BreakpointManager g_breakpoints;
3434

35-
void MemCheck::Log(u32 addr, bool write, int size, u32 pc, const char *reason) {
35+
void MemCheck::Log(u32 addr, bool write, int size, u32 pc, const char *reason) const {
3636
if (result & BREAK_ACTION_LOG) {
3737
const char *type = write ? "Write" : "Read";
3838
if (logFormat.empty()) {
@@ -71,11 +71,9 @@ BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc, const char
7171
}
7272

7373
// Note: must lock while calling this.
74-
size_t BreakpointManager::FindBreakpoint(u32 addr, bool matchTemp, bool temp)
75-
{
74+
size_t BreakpointManager::FindBreakpoint(u32 addr, bool matchTemp, bool temp) {
7675
size_t found = INVALID_BREAKPOINT;
77-
for (size_t i = 0; i < breakPoints_.size(); ++i)
78-
{
76+
for (size_t i = 0; i < breakPoints_.size(); ++i) {
7977
const auto &bp = breakPoints_[i];
8078
if (bp.addr == addr && (!matchTemp || bp.temporary == temp))
8179
{
@@ -90,10 +88,8 @@ size_t BreakpointManager::FindBreakpoint(u32 addr, bool matchTemp, bool temp)
9088
return found;
9189
}
9290

93-
size_t BreakpointManager::FindMemCheck(u32 start, u32 end)
94-
{
95-
for (size_t i = 0; i < memChecks_.size(); ++i)
96-
{
91+
size_t BreakpointManager::FindMemCheck(u32 start, u32 end) {
92+
for (size_t i = 0; i < memChecks_.size(); ++i) {
9793
if (memChecks_[i].start == start && memChecks_[i].end == end)
9894
return i;
9995
}
@@ -155,14 +151,11 @@ int BreakpointManager::AddBreakPoint(u32 addr, bool temp) {
155151

156152
breakPoints_.push_back(pt);
157153
anyBreakPoints_ = true;
158-
guard.unlock();
159154
Update(addr);
160-
161155
return (int)breakPoints_.size() - 1;
162156
} else if (!breakPoints_[bp].IsEnabled()) {
163157
breakPoints_[bp].result |= BREAK_ACTION_PAUSE;
164158
breakPoints_[bp].hasCond = false;
165-
guard.unlock();
166159
Update(addr);
167160
return (int)bp;
168161
} else {
@@ -183,7 +176,6 @@ void BreakpointManager::RemoveBreakPoint(u32 addr) {
183176
breakPoints_.erase(breakPoints_.begin() + bp);
184177

185178
anyBreakPoints_ = !breakPoints_.empty();
186-
guard.unlock();
187179
Update(addr);
188180
}
189181
}
@@ -196,8 +188,6 @@ void BreakpointManager::ChangeBreakPoint(u32 addr, bool status) {
196188
breakPoints_[bp].result |= BREAK_ACTION_PAUSE;
197189
else
198190
breakPoints_[bp].result = BreakAction(breakPoints_[bp].result & ~BREAK_ACTION_PAUSE);
199-
200-
guard.unlock();
201191
Update(addr);
202192
}
203193
}
@@ -207,7 +197,6 @@ void BreakpointManager::ChangeBreakPoint(u32 addr, BreakAction result) {
207197
size_t bp = FindBreakpoint(addr);
208198
if (bp != INVALID_BREAKPOINT) {
209199
breakPoints_[bp].result = result;
210-
guard.unlock();
211200
Update(addr);
212201
}
213202
}
@@ -220,7 +209,6 @@ void BreakpointManager::ClearAllBreakPoints()
220209
if (!breakPoints_.empty())
221210
{
222211
breakPoints_.clear();
223-
guard.unlock();
224212
Update();
225213
}
226214
}
@@ -230,20 +218,14 @@ void BreakpointManager::ClearTemporaryBreakPoints()
230218
if (!anyBreakPoints_)
231219
return;
232220
std::unique_lock<std::mutex> guard(breakPointsMutex_);
233-
234-
bool update = false;
235221
for (int i = (int)breakPoints_.size()-1; i >= 0; --i)
236222
{
237223
if (breakPoints_[i].temporary)
238224
{
239225
breakPoints_.erase(breakPoints_.begin() + i);
240-
update = true;
226+
Update();
241227
}
242228
}
243-
244-
guard.unlock();
245-
if (update)
246-
Update();
247229
}
248230

249231
void BreakpointManager::ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond)
@@ -254,38 +236,32 @@ void BreakpointManager::ChangeBreakPointAddCond(u32 addr, const BreakPointCond &
254236
{
255237
breakPoints_[bp].hasCond = true;
256238
breakPoints_[bp].cond = cond;
257-
guard.unlock();
258239
Update(addr);
259240
}
260241
}
261242

262-
void BreakpointManager::ChangeBreakPointRemoveCond(u32 addr)
263-
{
243+
void BreakpointManager::ChangeBreakPointRemoveCond(u32 addr) {
264244
std::unique_lock<std::mutex> guard(breakPointsMutex_);
265245
size_t bp = FindBreakpoint(addr);
266-
if (bp != INVALID_BREAKPOINT)
267-
{
246+
if (bp != INVALID_BREAKPOINT) {
268247
breakPoints_[bp].hasCond = false;
269-
guard.unlock();
270248
Update(addr);
271249
}
272250
}
273251

274-
BreakPointCond *BreakpointManager::GetBreakPointCondition(u32 addr)
275-
{
252+
BreakPointCond *BreakpointManager::GetBreakPointCondition(u32 addr) {
276253
std::lock_guard<std::mutex> guard(breakPointsMutex_);
277254
size_t bp = FindBreakpoint(addr);
278255
if (bp != INVALID_BREAKPOINT && breakPoints_[bp].hasCond)
279256
return &breakPoints_[bp].cond;
280-
return NULL;
257+
return nullptr;
281258
}
282259

283260
void BreakpointManager::ChangeBreakPointLogFormat(u32 addr, const std::string &fmt) {
284261
std::unique_lock<std::mutex> guard(breakPointsMutex_);
285262
size_t bp = FindBreakpoint(addr, true, false);
286263
if (bp != INVALID_BREAKPOINT) {
287264
breakPoints_[bp].logFormat = fmt;
288-
guard.unlock();
289265
Update(addr);
290266
}
291267
}
@@ -338,18 +314,18 @@ int BreakpointManager::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, B
338314

339315
memChecks_.push_back(check);
340316
bool hadAny = anyMemChecks_.exchange(true);
341-
if (!hadAny)
317+
if (!hadAny) {
342318
MemBlockOverrideDetailed();
343-
guard.unlock();
319+
}
344320
Update();
345321
return (int)memChecks_.size() - 1;
346322
} else {
347323
memChecks_[mc].cond = (MemCheckCondition)(memChecks_[mc].cond | cond);
348324
memChecks_[mc].result = (BreakAction)(memChecks_[mc].result | result);
349325
bool hadAny = anyMemChecks_.exchange(true);
350-
if (!hadAny)
326+
if (!hadAny) {
351327
MemBlockOverrideDetailed();
352-
guard.unlock();
328+
}
353329
Update();
354330
return (int)mc;
355331
}
@@ -366,7 +342,6 @@ void BreakpointManager::RemoveMemCheck(u32 start, u32 end)
366342
bool hadAny = anyMemChecks_.exchange(!memChecks_.empty());
367343
if (hadAny)
368344
MemBlockReleaseDetailed();
369-
guard.unlock();
370345
Update();
371346
}
372347
}
@@ -379,7 +354,6 @@ void BreakpointManager::ChangeMemCheck(u32 start, u32 end, MemCheckCondition con
379354
{
380355
memChecks_[mc].cond = cond;
381356
memChecks_[mc].result = result;
382-
guard.unlock();
383357
Update();
384358
}
385359
}
@@ -394,7 +368,6 @@ void BreakpointManager::ClearAllMemChecks()
394368
bool hadAny = anyMemChecks_.exchange(false);
395369
if (hadAny)
396370
MemBlockReleaseDetailed();
397-
guard.unlock();
398371
Update();
399372
}
400373
}
@@ -406,7 +379,6 @@ void BreakpointManager::ChangeMemCheckAddCond(u32 start, u32 end, const BreakPoi
406379
if (mc != INVALID_MEMCHECK) {
407380
memChecks_[mc].hasCondition = true;
408381
memChecks_[mc].condition = cond;
409-
guard.unlock();
410382
// No need to update jit for a condition add/remove, they're not baked in.
411383
Update(-1);
412384
}
@@ -417,7 +389,6 @@ void BreakpointManager::ChangeMemCheckRemoveCond(u32 start, u32 end) {
417389
size_t mc = FindMemCheck(start, end);
418390
if (mc != INVALID_MEMCHECK) {
419391
memChecks_[mc].hasCondition = false;
420-
guard.unlock();
421392
// No need to update jit for a condition add/remove, they're not baked in.
422393
Update(-1);
423394
}
@@ -436,7 +407,6 @@ void BreakpointManager::ChangeMemCheckLogFormat(u32 start, u32 end, const std::s
436407
size_t mc = FindMemCheck(start, end);
437408
if (mc != INVALID_MEMCHECK) {
438409
memChecks_[mc].logFormat = fmt;
439-
guard.unlock();
440410
Update();
441411
}
442412
}
@@ -620,30 +590,27 @@ std::vector<BreakPoint> BreakpointManager::GetBreakpoints() {
620590
return breakPoints_;
621591
}
622592

623-
void BreakpointManager::Update(u32 addr) {
624-
if (MIPSComp::jit && addr != -1) {
625-
bool resume = false;
626-
if (Core_IsStepping() == false) {
627-
Core_Break(BreakReason::BreakpointUpdate, addr);
628-
Core_WaitInactive();
629-
resume = true;
630-
}
593+
void BreakpointManager::Frame() {
594+
// outside the lock here, should be ok.
595+
if (!needsUpdate_) {
596+
return;
597+
}
631598

599+
std::lock_guard<std::mutex> guard(breakPointsMutex_);
600+
if (MIPSComp::jit && updateAddr_ != -1) {
632601
// In case this is a delay slot, clear the previous instruction too.
633-
if (addr != 0)
634-
mipsr4k.InvalidateICache(addr - 4, 8);
602+
if (updateAddr_ != 0)
603+
mipsr4k.InvalidateICache(updateAddr_ - 4, 8);
635604
else
636605
mipsr4k.ClearJitCache();
637-
638-
if (resume)
639-
Core_Resume();
640606
}
641607

642-
if (anyMemChecks_ && addr != -1)
608+
if (anyMemChecks_ && updateAddr_ != -1)
643609
UpdateCachedMemCheckRanges();
644610

645611
// Redraw in order to show the breakpoint.
646612
System_Notify(SystemNotification::DISASSEMBLY);
613+
needsUpdate_ = false;
647614
}
648615

649616
bool BreakpointManager::ValidateLogFormat(MIPSDebugInterface *cpu, const std::string &fmt) {

Core/Debugger/Breakpoints.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ struct MemCheck {
103103
// Called on a copy.
104104
BreakAction Action(u32 addr, bool write, int size, u32 pc, const char *reason);
105105

106-
void Log(u32 addr, bool write, int size, u32 pc, const char *reason);
106+
void Log(u32 addr, bool write, int size, u32 pc, const char *reason) const;
107107

108108
bool IsEnabled() const {
109109
return (result & BREAK_ACTION_PAUSE) != 0;
@@ -183,12 +183,17 @@ class BreakpointManager {
183183
return anyMemChecks_;
184184
}
185185

186-
void Update(u32 addr = 0);
186+
void Frame();
187187

188188
bool ValidateLogFormat(MIPSDebugInterface *cpu, const std::string &fmt);
189189
bool EvaluateLogFormat(MIPSDebugInterface *cpu, const std::string &fmt, std::string &result);
190190

191191
private:
192+
// Should be called under lock.
193+
void Update(u32 addr = 0) {
194+
needsUpdate_ = true;
195+
updateAddr_ = addr;
196+
}
192197
size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false);
193198
// Finds exactly, not using a range check.
194199
size_t FindMemCheck(u32 start, u32 end);
@@ -208,6 +213,9 @@ class BreakpointManager {
208213
std::vector<MemCheck> memChecks_;
209214
std::vector<MemCheck> memCheckRangesRead_;
210215
std::vector<MemCheck> memCheckRangesWrite_;
216+
217+
bool needsUpdate_ = true;
218+
u32 updateAddr_ = 0;
211219
};
212220

213221
extern BreakpointManager g_breakpoints;

GPU/Common/GPUDebugInterface.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ struct GPUDebugVertex {
205205

206206
class GPUDebugInterface {
207207
public:
208-
virtual ~GPUDebugInterface() {}
208+
virtual ~GPUDebugInterface() = default;
209209
virtual bool GetCurrentDisplayList(DisplayList &list) = 0;
210210
virtual int GetCurrentPrimCount() = 0;
211211
virtual std::vector<DisplayList> ActiveDisplayLists() = 0;

GPU/Debugger/Breakpoints.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const static u8 textureRelatedCmds[] = {
4242
GE_CMD_TEXFLUSH, GE_CMD_TEXSYNC,
4343
};
4444

45-
void GPUBreakpoints::Init() {
45+
GPUBreakpoints::GPUBreakpoints() {
4646
ClearAllBreakpoints();
4747

4848
nonTextureCmds.clear();
@@ -268,20 +268,20 @@ bool GPUBreakpoints::IsRenderTargetBreakpoint(u32 addr) {
268268
return breakRenderTargets.find(addr) != breakRenderTargets.end();
269269
}
270270

271-
bool GPUBreakpoints::IsOpBreakpoint(u32 op, bool &temp) {
271+
bool GPUBreakpoints::IsOpBreakpoint(u32 op, bool &temp) const {
272272
return IsCmdBreakpoint(op >> 24, temp);
273273
}
274274

275-
bool GPUBreakpoints::IsOpBreakpoint(u32 op) {
275+
bool GPUBreakpoints::IsOpBreakpoint(u32 op) const {
276276
return IsCmdBreakpoint(op >> 24);
277277
}
278278

279-
bool GPUBreakpoints::IsCmdBreakpoint(u8 cmd, bool &temp) {
279+
bool GPUBreakpoints::IsCmdBreakpoint(u8 cmd, bool &temp) const {
280280
temp = breakCmdsTemp[cmd];
281281
return breakCmds[cmd];
282282
}
283283

284-
bool GPUBreakpoints::IsCmdBreakpoint(u8 cmd) {
284+
bool GPUBreakpoints::IsCmdBreakpoint(u8 cmd) const {
285285
return breakCmds[cmd];
286286
}
287287

0 commit comments

Comments
 (0)