diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index 886394ac37..2fd7f1111e 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -16,7 +16,6 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include #include "Common/System/System.h" #include "Common/Log.h" @@ -69,7 +68,6 @@ BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc, const char return result; } -// Note: must lock while calling this. size_t BreakpointManager::FindBreakpoint(u32 addr, bool matchTemp, bool temp) { size_t found = INVALID_BREAKPOINT; for (size_t i = 0; i < breakPoints_.size(); ++i) { @@ -100,7 +98,6 @@ bool BreakpointManager::IsAddressBreakPoint(u32 addr) { if (!anyBreakPoints_) return false; - std::lock_guard guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); return bp != INVALID_BREAKPOINT && breakPoints_[bp].result != BREAK_ACTION_IGNORE; } @@ -109,7 +106,6 @@ bool BreakpointManager::IsAddressBreakPoint(u32 addr, bool* enabled) { if (!anyBreakPoints_) return false; - std::lock_guard guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); if (bp == INVALID_BREAKPOINT) return false; if (enabled != nullptr) @@ -119,7 +115,6 @@ bool BreakpointManager::IsAddressBreakPoint(u32 addr, bool* enabled) bool BreakpointManager::IsTempBreakPoint(u32 addr) { - std::lock_guard guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr, true, true); return bp != INVALID_BREAKPOINT; } @@ -128,7 +123,6 @@ bool BreakpointManager::RangeContainsBreakPoint(u32 addr, u32 size) { if (!anyBreakPoints_) return false; - std::lock_guard guard(breakPointsMutex_); const u32 end = addr + size; for (const auto &bp : breakPoints_) { @@ -140,7 +134,6 @@ bool BreakpointManager::RangeContainsBreakPoint(u32 addr, u32 size) } int BreakpointManager::AddBreakPoint(u32 addr, bool temp) { - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr, true, temp); if (bp == INVALID_BREAKPOINT) { BreakPoint pt; @@ -164,7 +157,6 @@ int BreakpointManager::AddBreakPoint(u32 addr, bool temp) { } void BreakpointManager::RemoveBreakPoint(u32 addr) { - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); if (bp != INVALID_BREAKPOINT) { breakPoints_.erase(breakPoints_.begin() + bp); @@ -180,7 +172,6 @@ void BreakpointManager::RemoveBreakPoint(u32 addr) { } void BreakpointManager::ChangeBreakPoint(u32 addr, bool status) { - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); if (bp != INVALID_BREAKPOINT) { if (status) @@ -192,7 +183,6 @@ void BreakpointManager::ChangeBreakPoint(u32 addr, bool status) { } void BreakpointManager::ChangeBreakPoint(u32 addr, BreakAction result) { - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); if (bp != INVALID_BREAKPOINT) { breakPoints_[bp].result = result; @@ -204,7 +194,6 @@ void BreakpointManager::ChangeBreakPoint(u32 addr, BreakAction result) { void BreakpointManager::ClearAllBreakPoints() { if (!anyBreakPoints_) return; - std::unique_lock guard(breakPointsMutex_); if (!breakPoints_.empty()) { // Same strategy as ClearTemporaryBreakPoints - if there's only one, we can update just that one. if (breakPoints_.size() == 1) { @@ -221,8 +210,6 @@ void BreakpointManager::ClearTemporaryBreakPoints() if (!anyBreakPoints_) return; - std::unique_lock guard(breakPointsMutex_); - std::vector addrsToUpdate; for (auto it = breakPoints_.begin(); it != breakPoints_.end(); ) { @@ -248,7 +235,6 @@ void BreakpointManager::ClearTemporaryBreakPoints() void BreakpointManager::ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond) { - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); if (bp != INVALID_BREAKPOINT) { @@ -259,7 +245,6 @@ void BreakpointManager::ChangeBreakPointAddCond(u32 addr, const BreakPointCond & } void BreakpointManager::ChangeBreakPointRemoveCond(u32 addr) { - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); if (bp != INVALID_BREAKPOINT) { breakPoints_[bp].hasCond = false; @@ -268,7 +253,6 @@ void BreakpointManager::ChangeBreakPointRemoveCond(u32 addr) { } BreakPointCond *BreakpointManager::GetBreakPointCondition(u32 addr) { - std::lock_guard guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr); if (bp != INVALID_BREAKPOINT && breakPoints_[bp].hasCond) return &breakPoints_[bp].cond; @@ -276,7 +260,6 @@ BreakPointCond *BreakpointManager::GetBreakPointCondition(u32 addr) { } void BreakpointManager::ChangeBreakPointLogFormat(u32 addr, const std::string &fmt) { - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr, true, false); if (bp != INVALID_BREAKPOINT) { breakPoints_[bp].logFormat = fmt; @@ -287,11 +270,9 @@ void BreakpointManager::ChangeBreakPointLogFormat(u32 addr, const std::string &f BreakAction BreakpointManager::ExecBreakPoint(u32 addr) { if (!anyBreakPoints_) return BREAK_ACTION_IGNORE; - std::unique_lock guard(breakPointsMutex_); size_t bp = FindBreakpoint(addr, false); if (bp != INVALID_BREAKPOINT) { const BreakPoint &info = breakPoints_[bp]; - guard.unlock(); if (info.hasCond) { // Evaluate the breakpoint and abort if necessary. @@ -320,8 +301,6 @@ BreakAction BreakpointManager::ExecBreakPoint(u32 addr) { } int BreakpointManager::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result) { - std::unique_lock guard(memCheckMutex_); - size_t mc = FindMemCheck(start, end); if (mc == INVALID_MEMCHECK) { MemCheck check; @@ -351,8 +330,6 @@ int BreakpointManager::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, B void BreakpointManager::RemoveMemCheck(u32 start, u32 end) { - std::unique_lock guard(memCheckMutex_); - size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { @@ -366,7 +343,6 @@ void BreakpointManager::RemoveMemCheck(u32 start, u32 end) void BreakpointManager::ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result) { - std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { @@ -378,8 +354,6 @@ void BreakpointManager::ChangeMemCheck(u32 start, u32 end, MemCheckCondition con void BreakpointManager::ClearAllMemChecks() { - std::unique_lock guard(memCheckMutex_); - if (!memChecks_.empty()) { memChecks_.clear(); @@ -392,7 +366,6 @@ void BreakpointManager::ClearAllMemChecks() void BreakpointManager::ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCond &cond) { - std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { memChecks_[mc].hasCondition = true; @@ -403,7 +376,6 @@ void BreakpointManager::ChangeMemCheckAddCond(u32 start, u32 end, const BreakPoi } void BreakpointManager::ChangeMemCheckRemoveCond(u32 start, u32 end) { - std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { memChecks_[mc].hasCondition = false; @@ -413,7 +385,6 @@ void BreakpointManager::ChangeMemCheckRemoveCond(u32 start, u32 end) { } BreakPointCond *BreakpointManager::GetMemCheckCondition(u32 start, u32 end) { - std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK && memChecks_[mc].hasCondition) return &memChecks_[mc].condition; @@ -421,7 +392,6 @@ BreakPointCond *BreakpointManager::GetMemCheckCondition(u32 start, u32 end) { } void BreakpointManager::ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt) { - std::unique_lock guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { memChecks_[mc].logFormat = fmt; @@ -430,7 +400,6 @@ void BreakpointManager::ChangeMemCheckLogFormat(u32 start, u32 end, const std::s } bool BreakpointManager::GetMemCheck(u32 start, u32 end, MemCheck *check) { - std::lock_guard guard(memCheckMutex_); size_t mc = FindMemCheck(start, end); if (mc != INVALID_MEMCHECK) { *check = memChecks_[mc]; @@ -447,14 +416,13 @@ static inline u32 NotCached(u32 val) { } bool BreakpointManager::GetMemCheckInRange(u32 address, int size, MemCheck *check) { - std::lock_guard guard(memCheckMutex_); - auto result = GetMemCheckLocked(address, size); + auto result = FindMemCheckInRange(address, size); if (result) *check = *result; return result != nullptr; } -MemCheck *BreakpointManager::GetMemCheckLocked(u32 address, int size) { +MemCheck *BreakpointManager::FindMemCheckInRange(u32 address, int size) { std::vector::iterator iter; for (iter = memChecks_.begin(); iter != memChecks_.end(); ++iter) { @@ -479,15 +447,13 @@ BreakAction BreakpointManager::ExecMemCheck(u32 address, bool write, int size, u { if (!anyMemChecks_) return BREAK_ACTION_IGNORE; - std::unique_lock guard(memCheckMutex_); - auto check = GetMemCheckLocked(address, size); + MemCheck *check = FindMemCheckInRange(address, size); if (check) { BreakAction applyAction = check->Apply(address, write, size, pc); if (applyAction == BREAK_ACTION_IGNORE) return applyAction; - auto copy = *check; - guard.unlock(); + MemCheck copy = *check; return copy.Action(address, write, size, pc, reason); } return BREAK_ACTION_IGNORE; @@ -504,8 +470,7 @@ BreakAction BreakpointManager::ExecOpMemCheck(u32 address, u32 pc) { } bool write = MIPSAnalyst::IsOpMemoryWrite(pc); - std::unique_lock guard(memCheckMutex_); - auto check = GetMemCheckLocked(address, size); + MemCheck *check = FindMemCheckInRange(address, size); if (check) { int mask = MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE; bool apply = false; @@ -521,9 +486,7 @@ BreakAction BreakpointManager::ExecOpMemCheck(u32 address, u32 pc) { if (applyAction == BREAK_ACTION_IGNORE) return applyAction; - // Make a copy so we can safely unlock. - auto copy = *check; - guard.unlock(); + MemCheck copy = *check; return copy.Action(address, write, size, pc, "CPU"); } } @@ -563,7 +526,6 @@ static MemCheck VRAMMirror(uint8_t mirror, MemCheck mc) { } void BreakpointManager::UpdateCachedMemCheckRanges() { - std::lock_guard guard(memCheckMutex_); memCheckRangesRead_.clear(); memCheckRangesWrite_.clear(); @@ -592,29 +554,24 @@ void BreakpointManager::UpdateCachedMemCheckRanges() { } std::vector BreakpointManager::GetMemCheckRanges(bool write) { - std::lock_guard guard(memCheckMutex_); if (write) return memCheckRangesWrite_; return memCheckRangesRead_; } std::vector BreakpointManager::GetMemChecks() { - std::lock_guard guard(memCheckMutex_); return memChecks_; } std::vector BreakpointManager::GetBreakpoints() { - std::lock_guard guard(breakPointsMutex_); return breakPoints_; } void BreakpointManager::Frame() { - // outside the lock here, should be ok. if (!needsUpdate_) { return; } - std::lock_guard guard(breakPointsMutex_); if (MIPSComp::jit && updateAddr_ != INVALID_ADDRESS) { // In case this is a delay slot, clear the previous instruction too. if (updateAddr_ != 0) diff --git a/Core/Debugger/Breakpoints.h b/Core/Debugger/Breakpoints.h index ebdcbcb440..c7fea9a0a0 100644 --- a/Core/Debugger/Breakpoints.h +++ b/Core/Debugger/Breakpoints.h @@ -19,7 +19,6 @@ #include #include -#include #include "Core/MIPS/MIPSDebugInterface.h" #include "Common/Math/expression_parser.h" @@ -190,7 +189,6 @@ public: bool EvaluateLogFormat(MIPSDebugInterface *cpu, const std::string &fmt, std::string &result); private: - // Should be called under lock. // 0 means to clear the whole jit cache, to apply some change that has been made. void Update(u32 addr) { needsUpdate_ = true; @@ -199,15 +197,13 @@ private: size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false); // Finds exactly, not using a range check. size_t FindMemCheck(u32 start, u32 end); - MemCheck *GetMemCheckLocked(u32 address, int size); + // Finds a memcheck covering (part of) a range, unlike FindMemCheck() above. + MemCheck *FindMemCheckInRange(u32 address, int size); void UpdateCachedMemCheckRanges(); std::atomic anyBreakPoints_; std::atomic anyMemChecks_; - std::mutex breakPointsMutex_; - std::mutex memCheckMutex_; - std::vector breakPoints_; u32 breakSkipFirstAt_ = 0; u64 breakSkipFirstTicks_ = 0;