diff --git a/Source/Core/Core/DSP/DSPCore.cpp b/Source/Core/Core/DSP/DSPCore.cpp index ca5eff4269..80436dd100 100644 --- a/Source/Core/Core/DSP/DSPCore.cpp +++ b/Source/Core/Core/DSP/DSPCore.cpp @@ -195,7 +195,7 @@ void SDSP::SetException(ExceptionType exception) void SDSP::SetExternalInterrupt(bool val) { - external_interrupt_waiting = val; + external_interrupt_waiting.store(val, std::memory_order_release); } void SDSP::CheckExternalInterrupt() diff --git a/Source/Core/Core/DSP/DSPCore.h b/Source/Core/Core/DSP/DSPCore.h index 298019aceb..7e8738026d 100644 --- a/Source/Core/Core/DSP/DSPCore.h +++ b/Source/Core/Core/DSP/DSPCore.h @@ -420,7 +420,7 @@ struct SDSP u8 reg_stack_ptrs[4]{}; u8 exceptions = 0; // pending exceptions - volatile bool external_interrupt_waiting = false; + std::atomic external_interrupt_waiting = false; bool reset_dspjit_codespace = false; // DSP hardware stacks. They're mapped to a bunch of registers, such that writes diff --git a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp index c142123fdc..d6bfc092e4 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp @@ -69,10 +69,9 @@ int Interpreter::RunCyclesThread(int cycles) if ((state.cr & CR_HALT) != 0) return 0; - if (state.external_interrupt_waiting) + if (state.external_interrupt_waiting.exchange(false, std::memory_order_acquire)) { m_dsp_core.CheckExternalInterrupt(); - m_dsp_core.SetExternalInterrupt(false); } Step(); diff --git a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp index b83b6f6297..0b1e07db7c 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp @@ -51,11 +51,10 @@ DSPEmitter::~DSPEmitter() u16 DSPEmitter::RunCycles(u16 cycles) { - if (m_dsp_core.DSPState().external_interrupt_waiting) + if (m_dsp_core.DSPState().external_interrupt_waiting.exchange(false, std::memory_order_acquire)) { m_dsp_core.CheckExternalInterrupt(); m_dsp_core.CheckExceptions(); - m_dsp_core.SetExternalInterrupt(false); } m_cycles_left = cycles; @@ -489,6 +488,9 @@ Gen::OpArg DSPEmitter::M_SDSP_cr() Gen::OpArg DSPEmitter::M_SDSP_external_interrupt_waiting() { + static_assert(decltype(SDSP::external_interrupt_waiting)::is_always_lock_free && + sizeof(SDSP::external_interrupt_waiting) == sizeof(u8)); + return MDisp(R15, static_cast(offsetof(SDSP, external_interrupt_waiting))); }