diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 514ca91f4d..e5da2ddb6a 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -244,7 +244,7 @@ const auto spu_putllc_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) +const auto spu_getll_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) { using namespace asmjit; @@ -258,7 +258,7 @@ const auto spu_getll_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) +const auto spu_putlluc_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) { using namespace asmjit; @@ -300,7 +302,7 @@ const auto spu_putlluc_tx = build_function_asm 5) { @@ -1018,11 +1028,19 @@ void SPUThread::do_putlluc(const spu_mfc_cmd& args) vm::_ref>(addr) += 0; - // Full lock (heavyweight) - // TODO: vm::check_addr - vm::writer_lock lock(1); - data = to_write; - vm::reservation_update(addr, 128); + if (g_cfg.core.spu_accurate_putlluc) + { + // Full lock (heavyweight) + // TODO: vm::check_addr + vm::writer_lock lock(1); + data = to_write; + vm::reservation_update(addr, 128); + } + else + { + data = to_write; + vm::reservation_update(addr, 128); + } } vm::reservation_notifier(addr, 128).notify_all(); @@ -1178,16 +1196,17 @@ bool SPUThread::process_mfc_cmd(spu_mfc_cmd args) if (LIKELY(g_use_rtm)) { - u64 count = 0; + u64 count = 1; - if (g_cfg.core.spu_accurate_getllar) + while (g_cfg.core.spu_accurate_getllar && !spu_getll_tx(raddr, rdata.data(), &rtime)) { - count = spu_getll_tx(raddr, rdata.data(), &rtime); + std::this_thread::yield(); + count += 2; } - if (count == 0) + if (!g_cfg.core.spu_accurate_getllar) { - for (++count;; count++, busy_wait(300)) + for (;; count++, busy_wait(300)) { rtime = vm::reservation_acquire(raddr, 128); rdata = data; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 70c06af533..f6b55a8149 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -323,6 +323,7 @@ struct cfg_root : cfg::node cfg::_bool spu_shared_runtime{this, "SPU Shared Runtime", true}; // Share compiled SPU functions between all threads cfg::_enum spu_block_size{this, "SPU Block Size"}; cfg::_bool spu_accurate_getllar{this, "Accurate GETLLAR", false}; + cfg::_bool spu_accurate_putlluc{this, "Accurate PUTLLUC", false}; cfg::_bool spu_verification{this, "SPU Verification", true}; // Should be enabled cfg::_bool spu_cache{this, "SPU Cache", true};