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_can_stop = true;
bool escape, retval;
u64 susp_ctr = -1;
@ -551,6 +552,14 @@ bool cpu_thread::check_state() noexcept
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)
{
flags -= cpu_flag::signal;
@ -580,7 +589,7 @@ bool cpu_thread::check_state() noexcept
store = true;
}
retval = false;
retval = !cpu_can_stop;
}
else
{
@ -593,8 +602,9 @@ bool cpu_thread::check_state() noexcept
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_step;
store = true;

View File

@ -11,6 +11,7 @@ enum class cpu_flag : u32
stop, // Thread not running (HLE, initial state)
exit, // Irreversible exit
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
suspend, // Thread suspended
ret, // Callback return requested

View File

@ -1219,7 +1219,7 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr)
}
else
{
ppu.state += cpu_flag::wait;
ppu.state += cpu_flag::wait + cpu_flag::temp;
std::this_thread::yield();
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)
{
spu.state += cpu_flag::wait;
spu.state += cpu_flag::wait + cpu_flag::temp;
if (timeout_ms > 0)
{
@ -271,10 +271,7 @@ namespace spu
busy_wait(count);
}
if (spu.test_stopped())
{
spu_runtime::g_escape(&spu);
}
spu.check_state();
}
atomic_instruction_table[pc_offset]++;
@ -2516,13 +2513,14 @@ bool spu_thread::process_mfc_cmd()
{
if (g_use_rtm)
{
state += cpu_flag::wait;
state += cpu_flag::wait + cpu_flag::temp;
}
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)
{
state += cpu_flag::wait;
state += cpu_flag::wait + cpu_flag::temp;
}
for (int i = 0; i < 10 && channel.get_count() == 0; i++)