Implement cpu_flag::temp flag

Accompanies wait flag, indicating that it was set in limited conditions.
Such condition don't allow thread to terminate after its removal.
This commit is contained in:
Nekotekina 2020-10-25 20:06:34 +03:00
parent 18ca3ed449
commit 130a0ef20e
4 changed files with 20 additions and 11 deletions

View file

@ -531,6 +531,7 @@ bool cpu_thread::check_state() noexcept
} }
bool cpu_sleep_called = false; bool cpu_sleep_called = false;
bool cpu_can_stop = true;
bool escape, retval; bool escape, retval;
u64 susp_ctr = -1; u64 susp_ctr = -1;
@ -551,6 +552,14 @@ bool cpu_thread::check_state() noexcept
susp_ctr = -1; susp_ctr = -1;
} }
if (flags & cpu_flag::temp)
{
// Sticky flag, indicates check_state() is not allowed to return true
flags -= cpu_flag::temp;
cpu_can_stop = false;
store = true;
}
if (flags & cpu_flag::signal) if (flags & cpu_flag::signal)
{ {
flags -= cpu_flag::signal; flags -= cpu_flag::signal;
@ -580,7 +589,7 @@ bool cpu_thread::check_state() noexcept
store = true; store = true;
} }
retval = false; retval = !cpu_can_stop;
} }
else else
{ {
@ -593,8 +602,9 @@ bool cpu_thread::check_state() noexcept
retval = true; retval = true;
} }
if (flags & cpu_flag::dbg_step) if (cpu_can_stop && flags & cpu_flag::dbg_step)
{ {
// Can't process dbg_step if we only paused temporarily
flags += cpu_flag::dbg_pause; flags += cpu_flag::dbg_pause;
flags -= cpu_flag::dbg_step; flags -= cpu_flag::dbg_step;
store = true; store = true;

View file

@ -11,6 +11,7 @@ enum class cpu_flag : u32
stop, // Thread not running (HLE, initial state) stop, // Thread not running (HLE, initial state)
exit, // Irreversible exit exit, // Irreversible exit
wait, // Indicates waiting state, set by the thread itself wait, // Indicates waiting state, set by the thread itself
temp, // Indicates that the thread cannot properly return after next check_state()
pause, // Thread suspended by suspend_all technique pause, // Thread suspended by suspend_all technique
suspend, // Thread suspended suspend, // Thread suspended
ret, // Callback return requested ret, // Callback return requested

View file

@ -1219,7 +1219,7 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr)
} }
else else
{ {
ppu.state += cpu_flag::wait; ppu.state += cpu_flag::wait + cpu_flag::temp;
std::this_thread::yield(); std::this_thread::yield();
ppu.check_state(); ppu.check_state();
} }

View file

@ -242,7 +242,7 @@ namespace spu
if (atomic_instruction_table[pc_offset].load(std::memory_order_consume) >= max_concurrent_instructions) if (atomic_instruction_table[pc_offset].load(std::memory_order_consume) >= max_concurrent_instructions)
{ {
spu.state += cpu_flag::wait; spu.state += cpu_flag::wait + cpu_flag::temp;
if (timeout_ms > 0) if (timeout_ms > 0)
{ {
@ -271,10 +271,7 @@ namespace spu
busy_wait(count); busy_wait(count);
} }
if (spu.test_stopped()) spu.check_state();
{
spu_runtime::g_escape(&spu);
}
} }
atomic_instruction_table[pc_offset]++; atomic_instruction_table[pc_offset]++;
@ -2516,13 +2513,14 @@ bool spu_thread::process_mfc_cmd()
{ {
if (g_use_rtm) if (g_use_rtm)
{ {
state += cpu_flag::wait; state += cpu_flag::wait + cpu_flag::temp;
} }
std::this_thread::yield(); std::this_thread::yield();
if (test_stopped()) if (g_use_rtm)
{ {
verify(HERE), !check_state();
} }
} }
}()) }())
@ -2888,7 +2886,7 @@ s64 spu_thread::get_ch_value(u32 ch)
{ {
if (channel.get_count() == 0) if (channel.get_count() == 0)
{ {
state += cpu_flag::wait; state += cpu_flag::wait + cpu_flag::temp;
} }
for (int i = 0; i < 10 && channel.get_count() == 0; i++) for (int i = 0; i < 10 && channel.get_count() == 0; i++)