mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-22 03:40:30 +00:00
CPU preemption control: bugfixes
This commit is contained in:
parent
9d1ec0b319
commit
cf4da5c4d1
@ -654,7 +654,7 @@ bool cpu_thread::check_state() noexcept
|
|||||||
{
|
{
|
||||||
// Process all flags in a single atomic op
|
// Process all flags in a single atomic op
|
||||||
bs_t<cpu_flag> state1;
|
bs_t<cpu_flag> state1;
|
||||||
const auto state0 = state.fetch_op([&](bs_t<cpu_flag>& flags)
|
auto state0 = state.fetch_op([&](bs_t<cpu_flag>& flags)
|
||||||
{
|
{
|
||||||
bool store = false;
|
bool store = false;
|
||||||
|
|
||||||
@ -784,7 +784,8 @@ bool cpu_thread::check_state() noexcept
|
|||||||
if (cpu_flag::wait - state0)
|
if (cpu_flag::wait - state0)
|
||||||
{
|
{
|
||||||
// Yield itself
|
// Yield itself
|
||||||
s_dummy_atomic.wait(0, 1u << 30, atomic_wait_timeout{80'000});
|
escape = false;
|
||||||
|
state0 += cpu_flag::yield;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const u128 bits = s_cpu_bits)
|
if (const u128 bits = s_cpu_bits)
|
||||||
|
@ -1668,14 +1668,42 @@ void lv2_obj::schedule_all(u64 current_time)
|
|||||||
|
|
||||||
if (const u64 freq = s_yield_frequency)
|
if (const u64 freq = s_yield_frequency)
|
||||||
{
|
{
|
||||||
if (auto cpu = cpu_thread::get_current())
|
const u64 tsc = utils::get_tsc();
|
||||||
{
|
const u64 last_tsc = s_last_yield_tsc;
|
||||||
const u64 tsc = utils::get_tsc();
|
|
||||||
const u64 last_tsc = s_last_yield_tsc;
|
|
||||||
|
|
||||||
if (tsc >= last_tsc && tsc <= s_max_allowed_yield_tsc && tsc - last_tsc >= freq)
|
if (tsc >= last_tsc && tsc <= s_max_allowed_yield_tsc && tsc - last_tsc >= freq)
|
||||||
|
{
|
||||||
|
auto target = +g_ppu;
|
||||||
|
cpu_thread* cpu = nullptr;
|
||||||
|
|
||||||
|
for (usz x = g_cfg.core.ppu_threads;; target = target->next_ppu, x--)
|
||||||
|
{
|
||||||
|
if (!target || !x)
|
||||||
|
{
|
||||||
|
if (g_ppu && cpu_flag::preempt - g_ppu->state)
|
||||||
|
{
|
||||||
|
// Don't be picky, pick up any running PPU thread even it has a wait flag
|
||||||
|
cpu = g_ppu;
|
||||||
|
}
|
||||||
|
// TODO: If this case is common enough it may be valuable to iterate over all CPU threads to find a perfect candidate (one without a wait or suspend flag)
|
||||||
|
else if (auto current = cpu_thread::get_current(); current && cpu_flag::suspend - current->state)
|
||||||
|
{
|
||||||
|
// May be an SPU or RSX thread, use them as a last resort
|
||||||
|
cpu = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target->state.none_of(cpu_flag::preempt + cpu_flag::wait))
|
||||||
|
{
|
||||||
|
cpu = target;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpu && cpu_flag::preempt - cpu->state && !cpu->state.test_and_set(cpu_flag::preempt))
|
||||||
{
|
{
|
||||||
cpu->state += cpu_flag::preempt;
|
|
||||||
s_last_yield_tsc = tsc;
|
s_last_yield_tsc = tsc;
|
||||||
g_lv2_preempts_taken.release(g_lv2_preempts_taken.load() + 1); // Has a minor race but performance is more important
|
g_lv2_preempts_taken.release(g_lv2_preempts_taken.load() + 1); // Has a minor race but performance is more important
|
||||||
rsx::set_rsx_yield_flag();
|
rsx::set_rsx_yield_flag();
|
||||||
|
@ -3558,7 +3558,7 @@ namespace rsx
|
|||||||
prev_preempt_count = frame_times[i].preempt_count;
|
prev_preempt_count = frame_times[i].preempt_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
preempt_count = frame_times.back().preempt_count;
|
preempt_count = std::min<u32>(frame_times.back().preempt_count, max_preempt_count);
|
||||||
|
|
||||||
u32 fails = 0;
|
u32 fails = 0;
|
||||||
u32 hard_fails = 0;
|
u32 hard_fails = 0;
|
||||||
@ -3630,9 +3630,9 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
prevent_preempt_increase_tickets--;
|
prevent_preempt_increase_tickets--;
|
||||||
}
|
}
|
||||||
else if (preempt_count < max_preempt_count)
|
else
|
||||||
{
|
{
|
||||||
preempt_count += 4;
|
preempt_count = std::min<u32>(preempt_count + 4, max_preempt_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3650,7 +3650,7 @@ namespace rsx
|
|||||||
|
|
||||||
if (hard_measures_taken)
|
if (hard_measures_taken)
|
||||||
{
|
{
|
||||||
preempt_fail_old_preempt_count = std::max<u32>(preempt_fail_old_preempt_count, frame_times.back().preempt_count);
|
preempt_fail_old_preempt_count = std::max<u32>(preempt_fail_old_preempt_count, std::min<u32>(frame_times.back().preempt_count, max_preempt_count));
|
||||||
}
|
}
|
||||||
else if (preempt_fail_old_preempt_count)
|
else if (preempt_fail_old_preempt_count)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user