summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2011-03-14 10:20:00 +0000
committerJordan Woyak <jordan.woyak@gmail.com>2011-03-14 10:20:00 +0000
commit5f0e073d1c6ec341f5c97040370465c6fa6fb3ff (patch)
treea5f7b01b8782d7b376129e6a16ac440af63c3c82 /Source/Core
parent580cd2539c53a134244a7fc259816c245e2495ff (diff)
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
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/CoreTiming.cpp14
-rw-r--r--Source/Core/Core/Src/DSP/DSPCore.cpp5
-rw-r--r--Source/Core/Core/Src/DSP/DSPCore.h7
-rw-r--r--Source/Core/Core/Src/DSP/DSPEmitter.cpp2
-rw-r--r--Source/Core/Core/Src/DSP/DSPHWInterface.cpp54
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<std::mutex> lk(externalEventSection);
+ std::lock_guard<std::recursive_mutex> lk(externalEventSection);
while(eventTsPool)
{
Event *ev = eventTsPool;
@@ -154,7 +154,7 @@ void Shutdown()
void DoState(PointerWrap &p)
{
- std::lock_guard<std::mutex> lk(externalEventSection);
+ std::lock_guard<std::recursive_mutex> 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<std::mutex> lk(externalEventSection);
+ std::lock_guard<std::recursive_mutex> 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<std::mutex> lk(externalEventSection);
+ std::lock_guard<std::recursive_mutex> 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<std::mutex> lk(externalEventSection);
+ std::lock_guard<std::recursive_mutex> lk(externalEventSection);
if (!tsFirst)
{
return;
@@ -431,7 +431,7 @@ void ProcessFifoWaitEvents()
void MoveEvents()
{
- std::lock_guard<std::mutex> lk(externalEventSection);
+ std::lock_guard<std::recursive_mutex> 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<std::mutex> 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<bool*>(&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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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)