From 5227e6580870af36a682bb36b1e6860b090c2230 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 30 Dec 2020 17:06:44 +0300 Subject: [PATCH] vm: implement vm::atomic_op, fetch_op helpers Can help to reduce lambda depth hell a little. --- rpcs3/Emu/Cell/Modules/cellSpurs.cpp | 55 +++++++++++----------------- rpcs3/Emu/Memory/vm_reservation.h | 18 +++++++++ 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp index 39f70f4efa..cebe8c7e8e 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp @@ -1751,7 +1751,7 @@ s32 cellSpursSetMaxContention(vm::ptr spurs, u32 wid, u32 maxContenti maxContention = CELL_SPURS_MAX_SPU; } - vm::light_op(spurs->wklMaxContention[wid % CELL_SPURS_MAX_WORKLOAD], [&](atomic_t& value) + vm::atomic_op(spurs->wklMaxContention[wid % CELL_SPURS_MAX_WORKLOAD], [&](u8& value) { value &= wid < CELL_SPURS_MAX_WORKLOAD ? 0xF0 : 0x0F; value |= wid < CELL_SPURS_MAX_WORKLOAD ? maxContention : maxContention << 4; @@ -2321,9 +2321,11 @@ s32 _spurs::add_workload(ppu_thread& ppu, vm::ptr spurs, vm::ptr u32 wnum; const u32 wmax = spurs->flags1 & SF1_32_WORKLOADS ? CELL_SPURS_MAX_WORKLOAD2 : CELL_SPURS_MAX_WORKLOAD; // TODO: check if can be changed - vm::light_op(spurs->wklEnabled, [&](atomic_be_t& value) + + vm::fetch_op(spurs->wklEnabled, [&](be_t& value) { wnum = std::countl_one(value); // found empty position + if (wnum < wmax) { value |= (0x80000000 >> wnum); // set workload bit @@ -2404,16 +2406,13 @@ s32 _spurs::add_workload(ppu_thread& ppu, vm::ptr spurs, vm::ptr spurs->wklIdleSpuCountOrReadyCount2[wnum] = 0; } - vm::light_op(spurs->wklMaxContention[index], [&](atomic_t& data) + vm::atomic_op(spurs->wklMaxContention[index], [&](u8& v) { - data.atomic_op([&](u8& v) - { - v &= (wnum <= 15 ? ~0xf : ~0xf0); - v |= (maxContention > 8 ? 8 : maxContention) << 4; - }); + v &= (wnum <= 15 ? ~0xf : ~0xf0); + v |= (maxContention > 8 ? 8 : maxContention) << 4; }); - vm::light_op((wnum <= 15 ? spurs->wklSignal1 : spurs->wklSignal2), [&](atomic_be_t& data) + vm::atomic_op((wnum <= 15 ? spurs->wklSignal1 : spurs->wklSignal2), [&](be_t& data) { data &= ~(0x8000 >> index); }); @@ -2581,18 +2580,15 @@ s32 cellSpursWaitForWorkloadShutdown(ppu_thread& ppu, vm::ptr spurs, auto& info = spurs->wklSyncInfo(wid); - const bool ok = vm::light_op(info.x28, [](atomic_be_t& state) + const auto [_old0, ok] = vm::fetch_op(info.x28, [](be_t& val) { - return state.fetch_op([](be_t& val) + if (val) { - if (val) - { - return false; - } + return false; + } - val = 2; - return true; - }).second; + val = 2; + return true; }); if (!ok) @@ -2600,18 +2596,15 @@ s32 cellSpursWaitForWorkloadShutdown(ppu_thread& ppu, vm::ptr spurs, return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } - const bool wait_sema = vm::light_op(spurs->wklEvent(wid), [](atomic_t& event) + const auto [_old1, wait_sema] = vm::fetch_op(spurs->wklEvent(wid), [](u8& event) { - return event.fetch_op([](u8& event) + if ((event & 1) == 0 || (event & 0x22) == 0x2) { - if ((event & 1) == 0 || (event & 0x22) == 0x2) - { - event |= 0x10; - return true; - } + event |= 0x10; + return true; + } - return false; - }).second; + return false; }); if (wait_sema) @@ -2926,13 +2919,9 @@ s32 cellSpursReadyCountAdd(ppu_thread& ppu, vm::ptr spurs, u32 wid, v return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } - *old = vm::light_op(spurs->readyCount(wid), [&](atomic_t& v) + *old = vm::fetch_op(spurs->readyCount(wid), [&](u8& val) { - return v.fetch_op([&](u8& val) - { - const s32 _new = val + value; - val = static_cast(std::clamp(_new, 0, 255)); - }); + val = static_cast(std::clamp(val + static_cast(value), 0, 255)); }); return CELL_OK; diff --git a/rpcs3/Emu/Memory/vm_reservation.h b/rpcs3/Emu/Memory/vm_reservation.h index 7e37e5dcae..c486a7b4ef 100644 --- a/rpcs3/Emu/Memory/vm_reservation.h +++ b/rpcs3/Emu/Memory/vm_reservation.h @@ -426,4 +426,22 @@ namespace vm return result; } } + + template + SAFE_BUFFERS inline auto atomic_op(T& data, F op) + { + return light_op(data, [&](T& data) + { + return data.atomic_op(op); + }); + } + + template + SAFE_BUFFERS inline auto fetch_op(T& data, F op) + { + return light_op(data, [&](T& data) + { + return data.fetch_op(op); + }); + } } // namespace vm