From 5f0e073d1c6ec341f5c97040370465c6fa6fb3ff Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 14 Mar 2011 10:20:00 +0000 Subject: [PATCH] It seems like CoreTiming's "external event" mutex is being used recursively. This fixes dsp lle jit on thread for me. YMMV git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7342 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/CoreTiming.cpp | 14 +++--- Source/Core/Core/Src/DSP/DSPCore.cpp | 5 +- Source/Core/Core/Src/DSP/DSPCore.h | 7 +-- Source/Core/Core/Src/DSP/DSPEmitter.cpp | 2 +- Source/Core/Core/Src/DSP/DSPHWInterface.cpp | 54 +++++---------------- 5 files changed, 24 insertions(+), 58 deletions(-) diff --git a/Source/Core/Core/Src/CoreTiming.cpp b/Source/Core/Core/Src/CoreTiming.cpp index 8095b56bde..9aacea5847 100644 --- a/Source/Core/Core/Src/CoreTiming.cpp +++ b/Source/Core/Core/Src/CoreTiming.cpp @@ -68,7 +68,7 @@ u64 fakeDecStartTicks; u64 fakeTBStartValue; u64 fakeTBStartTicks; -static std::mutex externalEventSection; +static std::recursive_mutex externalEventSection; void (*advanceCallback)(int cyclesExecuted) = NULL; @@ -143,7 +143,7 @@ void Shutdown() delete ev; } - std::lock_guard lk(externalEventSection); + std::lock_guard lk(externalEventSection); while(eventTsPool) { Event *ev = eventTsPool; @@ -154,7 +154,7 @@ void Shutdown() void DoState(PointerWrap &p) { - std::lock_guard lk(externalEventSection); + std::lock_guard lk(externalEventSection); p.Do(downcount); p.Do(slicelength); p.Do(globalTimer); @@ -225,7 +225,7 @@ u64 GetIdleTicks() // schedule things to be executed on the main thread. void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata) { - std::lock_guard lk(externalEventSection); + std::lock_guard lk(externalEventSection); Event *ne = GetNewTsEvent(); ne->time = globalTimer + cyclesIntoFuture; ne->type = event_type; @@ -244,7 +244,7 @@ void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata) { if(Core::IsCPUThread()) { - std::lock_guard lk(externalEventSection); + std::lock_guard lk(externalEventSection); event_types[event_type].callback(userdata, 0); } else @@ -348,7 +348,7 @@ void RemoveEvent(int event_type) void RemoveThreadsafeEvent(int event_type) { - std::lock_guard lk(externalEventSection); + std::lock_guard lk(externalEventSection); if (!tsFirst) { return; @@ -431,7 +431,7 @@ void ProcessFifoWaitEvents() void MoveEvents() { - std::lock_guard lk(externalEventSection); + std::lock_guard lk(externalEventSection); // Move events from async queue into main queue while (tsFirst) { diff --git a/Source/Core/Core/Src/DSP/DSPCore.cpp b/Source/Core/Core/Src/DSP/DSPCore.cpp index bf115019fd..5085fb5f37 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.cpp +++ b/Source/Core/Core/Src/DSP/DSPCore.cpp @@ -42,7 +42,6 @@ DSPCoreState core_state = DSPCORE_STOP; u16 cyclesLeft = 0; DSPEmitter *dspjit = NULL; Common::Event step_event; -static std::mutex ExtIntCriticalSection; static bool LoadRom(const char *fname, int size_in_words, u16 *rom) { @@ -204,7 +203,6 @@ void DSPCore_SetException(u8 level) // Notify that an external interrupt is pending (used by thread mode) void DSPCore_SetExternalInterrupt(bool val) { - std::lock_guard lk(ExtIntCriticalSection); g_dsp.external_interrupt_waiting = val; } @@ -274,7 +272,6 @@ int DSPCore_RunCycles(int cycles) while (cycles > 0) { - reswitch: switch (core_state) { case DSPCORE_RUNNING: @@ -289,7 +286,7 @@ int DSPCore_RunCycles(int cycles) case DSPCORE_STEPPING: step_event.Wait(); if (core_state != DSPCORE_STEPPING) - goto reswitch; + continue; DSPInterpreter::Step(); cycles--; diff --git a/Source/Core/Core/Src/DSP/DSPCore.h b/Source/Core/Core/Src/DSP/DSPCore.h index d15da70687..17b692b840 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.h +++ b/Source/Core/Core/Src/DSP/DSPCore.h @@ -231,7 +231,7 @@ struct SDSP u8 reg_stack_ptr[4]; u8 exceptions; // pending exceptions - bool external_interrupt_waiting; + volatile bool external_interrupt_waiting; // DSP hardware stacks. They're mapped to a bunch of registers, such that writes // to them push and reads pop. @@ -246,10 +246,7 @@ struct SDSP u64 step_counter; // Mailbox. - volatile u16 mbox[2][2]; - - // Mutex protecting the mailbox. - //std::mutex g_CriticalSection; + volatile u32 mbox[2]; // Accelerator / DMA / other hardware registers. Not GPRs. u16 ifx_regs[256]; diff --git a/Source/Core/Core/Src/DSP/DSPEmitter.cpp b/Source/Core/Core/Src/DSP/DSPEmitter.cpp index 8fc2a94923..b6fa5bb5a9 100644 --- a/Source/Core/Core/Src/DSP/DSPEmitter.cpp +++ b/Source/Core/Core/Src/DSP/DSPEmitter.cpp @@ -368,7 +368,7 @@ void DSPEmitter::CompileDispatcher() FixupBranch exceptionExit; if (DSPHost_OnThread()) { - CMP(8, M(&g_dsp.external_interrupt_waiting), Imm8(0)); + CMP(8, M(const_cast(&g_dsp.external_interrupt_waiting)), Imm8(0)); exceptionExit = J_CC(CC_NE); } diff --git a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp index f3106df45c..17ec10e724 100644 --- a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp +++ b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp @@ -23,6 +23,7 @@ ====================================================================*/ +#include "Atomic.h" #include "Thread.h" #include "MemoryUtil.h" @@ -41,8 +42,6 @@ static void gdsp_do_dma(); -static std::mutex g_CriticalSection; - void gdsp_ifx_init() { for (int i = 0; i < 256; i++) @@ -50,40 +49,25 @@ void gdsp_ifx_init() g_dsp.ifx_regs[i] = 0; } - g_dsp.mbox[0][0] = 0; - g_dsp.mbox[0][1] = 0; - g_dsp.mbox[1][0] = 0; - g_dsp.mbox[1][1] = 0; + g_dsp.mbox[0] = 0; + g_dsp.mbox[1] = 0; } u32 gdsp_mbox_peek(u8 mbx) { - std::unique_lock lk(g_CriticalSection, std::defer_lock); - if (DSPHost_OnThread()) - lk.lock(); - - return ((g_dsp.mbox[mbx][0] << 16) | g_dsp.mbox[mbx][1]); + return Common::AtomicLoad(g_dsp.mbox[mbx]); } void gdsp_mbox_write_h(u8 mbx, u16 val) { - std::unique_lock lk(g_CriticalSection, std::defer_lock); - if (DSPHost_OnThread()) - lk.lock(); - - g_dsp.mbox[mbx][0] = val & 0x7fff; + const u32 new_value = (Common::AtomicLoadAcquire(g_dsp.mbox[mbx]) & 0xffff) | (val << 16); + Common::AtomicStoreRelease(g_dsp.mbox[mbx], new_value & ~0x80000000); } void gdsp_mbox_write_l(u8 mbx, u16 val) { - { - std::unique_lock lk(g_CriticalSection, std::defer_lock); - if (DSPHost_OnThread()) - lk.lock(); - - g_dsp.mbox[mbx][1] = val; - g_dsp.mbox[mbx][0] |= 0x8000; - } + const u32 new_value = (Common::AtomicLoadAcquire(g_dsp.mbox[mbx]) & ~0xffff) | val; + Common::AtomicStoreRelease(g_dsp.mbox[mbx], new_value | 0x80000000); #if defined(_DEBUG) || defined(DEBUGFAST) if (mbx == GDSP_MBOX_DSP) @@ -97,25 +81,13 @@ void gdsp_mbox_write_l(u8 mbx, u16 val) u16 gdsp_mbox_read_h(u8 mbx) { - std::unique_lock lk(g_CriticalSection, std::defer_lock); - if (DSPHost_OnThread()) - lk.lock(); - - return g_dsp.mbox[mbx][0]; // TODO: mask away the top bit? + return (u16)(Common::AtomicLoad(g_dsp.mbox[mbx]) >> 16); // TODO: mask away the top bit? } - u16 gdsp_mbox_read_l(u8 mbx) { - u16 val; - { - std::unique_lock lk(g_CriticalSection, std::defer_lock); - if (DSPHost_OnThread()) - lk.lock(); - - val = g_dsp.mbox[mbx][1]; - g_dsp.mbox[mbx][0] &= ~0x8000; - } + const u32 value = Common::AtomicLoadAcquire(g_dsp.mbox[mbx]); + Common::AtomicStoreRelease(g_dsp.mbox[mbx], value & ~0x80000000); #if defined(_DEBUG) || defined(DEBUGFAST) if (mbx == GDSP_MBOX_DSP) @@ -124,9 +96,9 @@ u16 gdsp_mbox_read_l(u8 mbx) } else { NOTICE_LOG(DSP_MAIL, "CPU(RM) B:%i M:0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_CPU), g_dsp.pc); } -#endif +#endif - return val; + return (u16)value; } void gdsp_ifx_write(u32 addr, u32 val)