diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index ec45306220..1784b58b6a 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1137,14 +1137,9 @@ extern bool ppu_stwcx(ppu_thread& ppu, u32 addr, u32 reg_value) auto& res = vm::reservation_acquire(addr, sizeof(u32)); - const auto [_, ok] = res.fetch_op([&](u64& reserv) - { - return (++reserv & -128) == ppu.rtime; - }); - ppu.raddr = 0; - if (ok) + if (res == ppu.rtime && res.compare_and_swap_test(ppu.rtime, ppu.rtime | 1)) { if (data.compare_and_swap_test(old_data, reg_value)) { @@ -1258,14 +1253,9 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) auto& res = vm::reservation_acquire(addr, sizeof(u64)); - const auto [_, ok] = res.fetch_op([&](u64& reserv) - { - return (++reserv & -128) == ppu.rtime; - }); - ppu.raddr = 0; - if (ok) + if (res == ppu.rtime && res.compare_and_swap_test(ppu.rtime, ppu.rtime | 1)) { if (data.compare_and_swap_test(old_data, reg_value)) { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index de3a01261d..50963f9ecd 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -349,7 +349,6 @@ const auto spu_putllc_tx = build_function_asm(cpu_flag::wait)); // Touch memory if transaction failed without RETRY flag on the first attempt @@ -364,6 +363,13 @@ const auto spu_putllc_tx = build_function_asm(cpu_flag::wait)); // Touch memory if transaction failed without RETRY flag on the first attempt @@ -859,9 +864,15 @@ const auto spu_putlluc_tx = build_function_asm(addr); - mov_rdata(data, to_write); - - // Keep checking written data against a rogue transaction sneak in - while (std::atomic_thread_fence(std::memory_order_seq_cst), !cmp_rdata(data, to_write)) + // Wait for PUTLLC to complete + while (vm::reservation_acquire(addr, 128) & 1) { - mov_rdata(data, to_write); + busy_wait(100); } - vm::reservation_acquire(addr, 128) += 63; - } - else - { - // Give up if another PUTLLUC command took precedence - vm::reservation_acquire(addr, 128) -= 1; + mov_rdata(vm::_ref(addr), to_write); + vm::reservation_acquire(addr, 128) += 64; } } } @@ -1921,8 +1928,8 @@ bool spu_thread::process_mfc_cmd() cpu_thread::suspend_all cpu_lock(this); - // Give up if other PUTLLC/PUTLLUC commands are in progress - if (!vm::reservation_acquire(addr, 128).try_dec(rtime + 1)) + // Give up if PUTLLUC happened + if (vm::reservation_acquire(addr, 128) == (rtime | 1)) { auto& data = vm::_ref(addr); @@ -1937,6 +1944,10 @@ bool spu_thread::process_mfc_cmd() vm::reservation_acquire(addr, 128) -= 1; } } + else + { + vm::reservation_acquire(addr, 128) -= 1; + } } } else if (auto& data = vm::_ref(addr); rtime == (vm::reservation_acquire(raddr, 128) & -128) && cmp_rdata(rdata, data))