diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index dc6e6f364a..bd474d8122 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -4047,6 +4047,22 @@ void do_cell_atomic_128_store(u32 addr, const void* to_write) auto& sdata = *vm::get_super_ptr(addr); auto& res = *utils::bless>(vm::g_reservations + (addr & 0xff80) / 2); + if (std::memcmp(static_cast(to_write), &sdata, 16) == 0 && std::memcmp(static_cast(to_write) + 64, &sdata[64], 16) == 0) + { + const auto& write_data = *static_cast(to_write); + const u64 at_read_time = vm::reservation_acquire(addr); + + if (!(at_read_time & 127)) + { + if (cmp_rdata(sdata, write_data) && at_read_time == vm::reservation_acquire(addr) && cmp_rdata(sdata, write_data)) + { + // Write of the same data (verified atomically) + vm::try_reservation_update(addr); + return; + } + } + } + for (u64 j = 0;; j++) { auto [_oldd, _ok] = res.fetch_op([&](u128& r) diff --git a/rpcs3/Emu/Memory/vm_reservation.h b/rpcs3/Emu/Memory/vm_reservation.h index af402249bf..15e6c51320 100644 --- a/rpcs3/Emu/Memory/vm_reservation.h +++ b/rpcs3/Emu/Memory/vm_reservation.h @@ -35,6 +35,7 @@ namespace vm // Update reservation status void reservation_update(u32 addr); + std::pair try_reservation_update(u32 addr); struct reservation_waiter_t {