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.
This commit is contained in:
Markus Stockhausen 2019-11-01 12:47:29 +01:00 committed by Ivan
parent 223d1473b0
commit cd6b6c8a4f

View file

@ -1942,34 +1942,42 @@ bool spu_thread::process_mfc_cmd()
} }
} }
} }
else if (auto& data = vm::_ref<decltype(rdata)>(addr); rtime == (vm::reservation_acquire(raddr, 128) & -128) && cmp_rdata(rdata, data)) else if (auto& data = vm::_ref<decltype(rdata)>(addr); rtime == (vm::reservation_acquire(raddr, 128) & -128))
{ {
auto& res = vm::reservation_lock(raddr, 128); if (cmp_rdata(rdata, to_write))
const u64 old_time = res.load() & -128;
if (rtime == old_time)
{ {
*reinterpret_cast<atomic_t<u32>*>(&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) if (rtime == old_time)
// TODO: vm::check_addr
vm::writer_lock lock(addr);
if (cmp_rdata(rdata, data))
{ {
mov_rdata(data, to_write); *reinterpret_cast<atomic_t<u32>*>(&data) += 0;
res.release(old_time + 128);
result = 1; // 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 else
{ {
res.release(old_time); res.release(old_time);
} }
} }
else
{
res.release(old_time);
}
} }
} }