Improve vm::reservation_update

Only respect unique lock.
This commit is contained in:
Nekotekina 2020-10-11 17:18:40 +03:00
parent 2f329cf7b5
commit 1885e4345c
4 changed files with 19 additions and 18 deletions

View File

@ -4487,7 +4487,7 @@ bool ppu_interpreter::STW(ppu_thread& ppu, ppu_opcode_t op)
//Insomniac engine v3 & v4 (newer R&C, Fuse, Resitance 3) //Insomniac engine v3 & v4 (newer R&C, Fuse, Resitance 3)
if (value == 0xAAAAAAAA) [[unlikely]] if (value == 0xAAAAAAAA) [[unlikely]]
{ {
vm::reservation_update(vm::cast(addr, HERE), 128); vm::reservation_update(vm::cast(addr, HERE));
} }
return true; return true;

View File

@ -80,15 +80,25 @@ namespace vm
// Memory pages // Memory pages
std::array<memory_page, 0x100000000 / 4096> g_pages{}; std::array<memory_page, 0x100000000 / 4096> g_pages{};
void reservation_update(u32 addr, u32 size, bool lsb) std::pair<bool, u64> try_reservation_update(u32 addr)
{
// Update reservation info with new timestamp
auto& res = reservation_acquire(addr, 1);
const u64 rtime = res;
return {!(rtime & vm::rsrv_unique_lock) && res.compare_and_swap_test(rtime, rtime + 128), rtime};
}
void reservation_update(u32 addr)
{ {
u64 old = UINT64_MAX; u64 old = UINT64_MAX;
const auto cpu = get_current_cpu_thread(); const auto cpu = get_current_cpu_thread();
while (true) while (true)
{ {
const auto [ok, rtime] = try_reservation_update(addr, size, lsb); const auto [ok, rtime] = try_reservation_update(addr);
if (ok || old / 128 < rtime / 128)
if (ok || (old & -128) < (rtime & -128))
{ {
return; return;
} }

View File

@ -25,16 +25,7 @@ namespace vm
} }
// Update reservation status // Update reservation status
inline std::pair<bool, u64> try_reservation_update(u32 addr, u32 size, bool lsb = false) void reservation_update(u32 addr);
{
// Update reservation info with new timestamp
auto& res = reservation_acquire(addr, size);
const u64 rtime = res;
return {!(rtime & 127) && res.compare_and_swap_test(rtime, rtime + 128), rtime};
}
void reservation_update(u32 addr, u32 size, bool lsb = false);
// Get reservation sync variable // Get reservation sync variable
inline atomic_t<u64>& reservation_notifier(u32 addr, u32 size) inline atomic_t<u64>& reservation_notifier(u32 addr, u32 size)

View File

@ -306,7 +306,7 @@ void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
} }
else if (reg == RESERVATION_LOST) else if (reg == RESERVATION_LOST)
{ {
if (u32 raddr = ppu.raddr) vm::reservation_update(raddr, 128); if (u32 raddr = ppu.raddr) vm::reservation_update(raddr);
return; return;
} }
} }
@ -357,7 +357,7 @@ void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
} }
else if (reg == RESERVATION_LOST) else if (reg == RESERVATION_LOST)
{ {
if (u32 raddr = spu.raddr) vm::reservation_update(raddr, 128); if (u32 raddr = spu.raddr) vm::reservation_update(raddr);
return; return;
} }
} }