From cd6b6c8a4f19595ac339efbf86602ecf59b5a497 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Fri, 1 Nov 2019 12:47:29 +0100 Subject: [PATCH] Lightweight putllc() for non-TSX if no data changed This replaces the totally messed up PR #6728 Some games make heavy use of getllar() & putllc() without even changing data. In this case avoid unneccesary heavy locking of the PPU threads on non-TSX hosts. --- rpcs3/Emu/Cell/SPUThread.cpp | 44 +++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index b1f7c91d30..8fd7192d32 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1942,34 +1942,42 @@ bool spu_thread::process_mfc_cmd() } } } - else if (auto& data = vm::_ref(addr); rtime == (vm::reservation_acquire(raddr, 128) & -128) && cmp_rdata(rdata, data)) + else if (auto& data = vm::_ref(addr); rtime == (vm::reservation_acquire(raddr, 128) & -128)) { - auto& res = vm::reservation_lock(raddr, 128); - const u64 old_time = res.load() & -128; - - if (rtime == old_time) + if (cmp_rdata(rdata, to_write)) { - *reinterpret_cast*>(&data) += 0; + // Writeback of unchanged data. Only check memory change + result = cmp_rdata(rdata, data) && vm::reservation_acquire(raddr, 128).compare_and_swap_test(rtime, rtime + 128); + } + else + { + auto& res = vm::reservation_lock(raddr, 128); + const u64 old_time = res.load() & -128; - // Full lock (heavyweight) - // TODO: vm::check_addr - vm::writer_lock lock(addr); - - if (cmp_rdata(rdata, data)) + if (rtime == old_time) { - mov_rdata(data, to_write); - res.release(old_time + 128); - result = 1; + *reinterpret_cast*>(&data) += 0; + + // Full lock (heavyweight) + // TODO: vm::check_addr + vm::writer_lock lock(addr); + + if (cmp_rdata(rdata, data)) + { + mov_rdata(data, to_write); + res.release(old_time + 128); + result = 1; + } + else + { + res.release(old_time); + } } else { res.release(old_time); } } - else - { - res.release(old_time); - } } }