DSPLLE: Put DSP thread in idle state if it's paused to prevent a deadlock

DSP thread is considered "idle" when it signals s_ppc_event and waits for s_dsp_event,
without putting it in this state when m_dsp_thread_mutex is locked it was possible to
create a deadlock between a DSP thread, emulation thread and Qt thread by accessing
Config menu immediately after booting up the game
This commit is contained in:
Silent 2019-08-25 18:00:43 +02:00
parent 28f7c5fb2a
commit e30ff7c327
No known key found for this signature in database
GPG Key ID: AE53149BB0C45AF1
1 changed files with 15 additions and 13 deletions

View File

@ -98,7 +98,9 @@ void DSPLLE::DSPThread(DSPLLE* dsp_lle)
const int cycles = static_cast<int>(dsp_lle->m_cycle_count.load()); const int cycles = static_cast<int>(dsp_lle->m_cycle_count.load());
if (cycles > 0) if (cycles > 0)
{ {
std::lock_guard<std::mutex> dsp_thread_lock(dsp_lle->m_dsp_thread_mutex); std::unique_lock dsp_thread_lock(dsp_lle->m_dsp_thread_mutex, std::try_to_lock);
if (dsp_thread_lock)
{
if (g_dsp_jit) if (g_dsp_jit)
{ {
DSPCore_RunCycles(cycles); DSPCore_RunCycles(cycles);
@ -108,14 +110,14 @@ void DSPLLE::DSPThread(DSPLLE* dsp_lle)
DSP::Interpreter::RunCyclesThread(cycles); DSP::Interpreter::RunCyclesThread(cycles);
} }
dsp_lle->m_cycle_count.store(0); dsp_lle->m_cycle_count.store(0);
continue;
} }
else }
{
s_ppc_event.Set(); s_ppc_event.Set();
s_dsp_event.Wait(); s_dsp_event.Wait();
} }
} }
}
static bool LoadDSPRom(u16* rom, const std::string& filename, u32 size_in_bytes) static bool LoadDSPRom(u16* rom, const std::string& filename, u32 size_in_bytes)
{ {