From b6d3fa8c66999e351cd961f7dd4a57d35973c974 Mon Sep 17 00:00:00 2001 From: Eladash Date: Wed, 14 Sep 2022 19:45:11 +0300 Subject: [PATCH] CPU preemption control: avoidance in reservation operations --- rpcs3/Emu/CPU/CPUThread.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index c01b4b9eb2..96c80a8cdf 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -898,6 +898,23 @@ bool cpu_thread::check_state() noexcept if (state0 & cpu_flag::yield && cpu_flag::wait - state0) { + if (auto spu = try_get()) + { + if (spu->raddr && spu->rtime == vm::reservation_acquire(spu->raddr) && spu->getllar_spin_count < 10) + { + // Reservation operation is a critical section (but this may result in false positives) + continue; + } + } + else if (auto ppu = try_get()) + { + if (ppu->raddr && ppu->rtime == vm::reservation_acquire(ppu->raddr)) + { + // Same + continue; + } + } + // Short sleep when yield flag is present alone (makes no sense when other methods which can stop thread execution have been done) // Pass a mask of a single bit which is often unused to avoid notifications s_dummy_atomic.wait(0, 1u << 30, atomic_wait_timeout{80'000});