mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 05:51:27 +12:00
Savestates: Fix deadlock on savestate load
This commit is contained in:
parent
a41d2e43fd
commit
0beda6fa89
3 changed files with 12 additions and 3 deletions
|
@ -1218,7 +1218,7 @@ static std::deque<std::pair<u64, class cpu_thread*>> g_waiting;
|
||||||
|
|
||||||
// Threads which must call lv2_obj::sleep before the scheduler starts
|
// Threads which must call lv2_obj::sleep before the scheduler starts
|
||||||
static std::deque<class cpu_thread*> g_to_sleep;
|
static std::deque<class cpu_thread*> g_to_sleep;
|
||||||
|
static atomic_t<bool> g_scheduler_ready = false;
|
||||||
static atomic_t<u64> s_yield_frequency = 0;
|
static atomic_t<u64> s_yield_frequency = 0;
|
||||||
static atomic_t<u64> s_max_allowed_yield_tsc = 0;
|
static atomic_t<u64> s_max_allowed_yield_tsc = 0;
|
||||||
static u64 s_last_yield_tsc = 0;
|
static u64 s_last_yield_tsc = 0;
|
||||||
|
@ -1596,6 +1596,7 @@ bool lv2_obj::awake_unlocked(cpu_thread* cpu, s32 prio)
|
||||||
void lv2_obj::cleanup()
|
void lv2_obj::cleanup()
|
||||||
{
|
{
|
||||||
g_ppu = nullptr;
|
g_ppu = nullptr;
|
||||||
|
g_scheduler_ready = false;
|
||||||
g_to_sleep.clear();
|
g_to_sleep.clear();
|
||||||
g_waiting.clear();
|
g_waiting.clear();
|
||||||
g_pending = 0;
|
g_pending = 0;
|
||||||
|
@ -1606,7 +1607,7 @@ void lv2_obj::schedule_all(u64 current_time)
|
||||||
{
|
{
|
||||||
usz notify_later_idx = 0;
|
usz notify_later_idx = 0;
|
||||||
|
|
||||||
if (!g_pending && g_to_sleep.empty())
|
if (!g_pending && g_scheduler_ready)
|
||||||
{
|
{
|
||||||
auto target = +g_ppu;
|
auto target = +g_ppu;
|
||||||
|
|
||||||
|
@ -1727,6 +1728,12 @@ void lv2_obj::schedule_all(u64 current_time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lv2_obj::make_scheduler_ready()
|
||||||
|
{
|
||||||
|
g_scheduler_ready.release(true);
|
||||||
|
lv2_obj::awake_all();
|
||||||
|
}
|
||||||
|
|
||||||
ppu_thread_status lv2_obj::ppu_state(ppu_thread* ppu, bool lock_idm, bool lock_lv2)
|
ppu_thread_status lv2_obj::ppu_state(ppu_thread* ppu, bool lock_idm, bool lock_lv2)
|
||||||
{
|
{
|
||||||
std::optional<reader_lock> opt_lock[2];
|
std::optional<reader_lock> opt_lock[2];
|
||||||
|
|
|
@ -242,6 +242,8 @@ public:
|
||||||
g_to_awake.clear();
|
g_to_awake.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void make_scheduler_ready();
|
||||||
|
|
||||||
static ppu_thread_status ppu_state(ppu_thread* ppu, bool lock_idm = true, bool lock_lv2 = true);
|
static ppu_thread_status ppu_state(ppu_thread* ppu, bool lock_idm = true, bool lock_lv2 = true);
|
||||||
|
|
||||||
static inline void append(cpu_thread* const thread)
|
static inline void append(cpu_thread* const thread)
|
||||||
|
|
|
@ -2249,7 +2249,7 @@ void Emulator::FinalizeRunRequest()
|
||||||
|
|
||||||
idm::select<named_thread<spu_thread>>(on_select);
|
idm::select<named_thread<spu_thread>>(on_select);
|
||||||
|
|
||||||
lv2_obj::awake_all();
|
lv2_obj::make_scheduler_ready();
|
||||||
|
|
||||||
m_state.compare_and_swap_test(system_state::starting, system_state::running);
|
m_state.compare_and_swap_test(system_state::starting, system_state::running);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue