mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-26 15:49:50 -06:00
Merge pull request #13446 from JosJuice/breakpoints-delayed-update
PowerPC: Add RAII handling for breakpoint updates
This commit is contained in:
@ -252,6 +252,7 @@ MemChecks::TMemChecksStr MemChecks::GetStrings() const
|
||||
void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
||||
{
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
DelayedMemCheckUpdate delayed_update(this);
|
||||
|
||||
for (const std::string& mc_string : mc_strings)
|
||||
{
|
||||
@ -279,13 +280,11 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
||||
mc.condition = Expression::TryParse(condition);
|
||||
}
|
||||
|
||||
Add(std::move(mc), false);
|
||||
delayed_update |= Add(std::move(mc));
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
void MemChecks::Add(TMemCheck memory_check, bool update)
|
||||
DelayedMemCheckUpdate MemChecks::Add(TMemCheck memory_check)
|
||||
{
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
@ -304,8 +303,7 @@ void MemChecks::Add(TMemCheck memory_check, bool update)
|
||||
m_mem_checks.emplace_back(std::move(memory_check));
|
||||
}
|
||||
|
||||
if (update)
|
||||
Update();
|
||||
return DelayedMemCheckUpdate(this, true);
|
||||
}
|
||||
|
||||
bool MemChecks::ToggleEnable(u32 address)
|
||||
@ -319,20 +317,17 @@ bool MemChecks::ToggleEnable(u32 address)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemChecks::Remove(u32 address, bool update)
|
||||
DelayedMemCheckUpdate MemChecks::Remove(u32 address)
|
||||
{
|
||||
const auto iter = std::ranges::find(m_mem_checks, address, &TMemCheck::start_address);
|
||||
|
||||
if (iter == m_mem_checks.cend())
|
||||
return false;
|
||||
return DelayedMemCheckUpdate(this, false);
|
||||
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
m_mem_checks.erase(iter);
|
||||
|
||||
if (update)
|
||||
Update();
|
||||
|
||||
return true;
|
||||
return DelayedMemCheckUpdate(this, true);
|
||||
}
|
||||
|
||||
void MemChecks::Clear()
|
||||
|
@ -97,6 +97,8 @@ private:
|
||||
Core::System& m_system;
|
||||
};
|
||||
|
||||
class DelayedMemCheckUpdate;
|
||||
|
||||
// Memory breakpoints
|
||||
class MemChecks
|
||||
{
|
||||
@ -115,13 +117,13 @@ public:
|
||||
TMemChecksStr GetStrings() const;
|
||||
void AddFromStrings(const TMemChecksStr& mc_strings);
|
||||
|
||||
void Add(TMemCheck memory_check, bool update = true);
|
||||
DelayedMemCheckUpdate Add(TMemCheck memory_check);
|
||||
|
||||
bool ToggleEnable(u32 address);
|
||||
|
||||
TMemCheck* GetMemCheck(u32 address, size_t size = 1);
|
||||
bool OverlapsMemcheck(u32 address, u32 length) const;
|
||||
bool Remove(u32 address, bool update = true);
|
||||
DelayedMemCheckUpdate Remove(u32 address);
|
||||
|
||||
void Update();
|
||||
void Clear();
|
||||
@ -132,3 +134,39 @@ private:
|
||||
Core::System& m_system;
|
||||
bool m_mem_breakpoints_set = false;
|
||||
};
|
||||
|
||||
class DelayedMemCheckUpdate final
|
||||
{
|
||||
public:
|
||||
DelayedMemCheckUpdate(MemChecks* memchecks, bool update_needed = false)
|
||||
: m_memchecks(memchecks), m_update_needed(update_needed)
|
||||
{
|
||||
}
|
||||
|
||||
DelayedMemCheckUpdate(const DelayedMemCheckUpdate&) = delete;
|
||||
DelayedMemCheckUpdate(DelayedMemCheckUpdate&& other) = delete;
|
||||
DelayedMemCheckUpdate& operator=(const DelayedMemCheckUpdate&) = delete;
|
||||
DelayedMemCheckUpdate& operator=(DelayedMemCheckUpdate&& other) = delete;
|
||||
|
||||
~DelayedMemCheckUpdate()
|
||||
{
|
||||
if (m_update_needed)
|
||||
m_memchecks->Update();
|
||||
}
|
||||
|
||||
DelayedMemCheckUpdate& operator|=(DelayedMemCheckUpdate&& other)
|
||||
{
|
||||
if (m_memchecks == other.m_memchecks)
|
||||
{
|
||||
m_update_needed |= other.m_update_needed;
|
||||
other.m_update_needed = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const { return m_update_needed; }
|
||||
|
||||
private:
|
||||
MemChecks* m_memchecks;
|
||||
bool m_update_needed;
|
||||
};
|
||||
|
@ -172,12 +172,12 @@ static void RemoveBreakpoint(BreakpointType type, u32 addr, u32 len)
|
||||
else
|
||||
{
|
||||
auto& memchecks = Core::System::GetInstance().GetPowerPC().GetMemChecks();
|
||||
DelayedMemCheckUpdate delayed_update(&memchecks);
|
||||
while (memchecks.GetMemCheck(addr, len) != nullptr)
|
||||
{
|
||||
memchecks.Remove(addr, false);
|
||||
delayed_update |= memchecks.Remove(addr);
|
||||
INFO_LOG_FMT(GDB_STUB, "gdb: removed a memcheck: {:08x} bytes at {:08x}", len, addr);
|
||||
}
|
||||
memchecks.Update();
|
||||
}
|
||||
Host_PPCBreakpointsChanged();
|
||||
}
|
||||
|
@ -1010,6 +1010,7 @@ void MemoryViewWidget::ToggleBreakpoint(u32 addr, bool row)
|
||||
|
||||
{
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
DelayedMemCheckUpdate delayed_update(&memchecks);
|
||||
|
||||
for (int i = 0; i < breaks; i++)
|
||||
{
|
||||
@ -1028,16 +1029,14 @@ void MemoryViewWidget::ToggleBreakpoint(u32 addr, bool row)
|
||||
check.log_on_hit = m_do_log;
|
||||
check.break_on_hit = true;
|
||||
|
||||
memchecks.Add(std::move(check), false);
|
||||
delayed_update |= memchecks.Add(std::move(check));
|
||||
}
|
||||
else if (check_ptr != nullptr)
|
||||
{
|
||||
// Using the pointer fixes misaligned breakpoints (0x11 breakpoint in 0x10 aligned view).
|
||||
memchecks.Remove(check_ptr->start_address, false);
|
||||
delayed_update |= memchecks.Remove(check_ptr->start_address);
|
||||
}
|
||||
}
|
||||
|
||||
memchecks.Update();
|
||||
}
|
||||
|
||||
emit Host::GetInstance()->PPCBreakpointsChanged();
|
||||
|
Reference in New Issue
Block a user