diff --git a/rpcs3/Emu/Cell/Modules/cellSysutil.cpp b/rpcs3/Emu/Cell/Modules/cellSysutil.cpp index 73207530f4..7cb9d370bf 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutil.cpp @@ -6,43 +6,27 @@ #include "cellSysutil.h" #include "Utilities/StrUtil.h" - -#include -#include +#include "Utilities/lockless.h" LOG_CHANNEL(cellSysutil); struct sysutil_cb_manager { - std::mutex mutex; - - std::array, vm::ptr>, 4> callbacks; - - std::queue> registered; - - std::function get_cb() + struct alignas(8) registered_cb { - std::lock_guard lock(mutex); + vm::ptr first; + vm::ptr second; + }; - if (registered.empty()) - { - return nullptr; - } + atomic_t callbacks[4]{}; - auto func = std::move(registered.front()); - - registered.pop(); - - return func; - } + lf_queue> registered; }; extern void sysutil_register_cb(std::function&& cb) { const auto cbm = fxm::get_always(); - std::lock_guard lock(cbm->mutex); - cbm->registered.push(std::move(cb)); } @@ -50,12 +34,10 @@ extern void sysutil_send_system_cmd(u64 status, u64 param) { if (const auto cbm = fxm::get()) { - for (auto& cb : cbm->callbacks) + for (sysutil_cb_manager::registered_cb cb : cbm->callbacks) { if (cb.first) { - std::lock_guard lock(cbm->mutex); - cbm->registered.push([=](ppu_thread& ppu) -> s32 { // TODO: check it and find the source of the return value (void isn't equal to CELL_OK) @@ -244,10 +226,11 @@ error_code cellSysutilCheckCallback(ppu_thread& ppu) const auto cbm = fxm::get_always(); - while (auto func = cbm->get_cb()) + for (auto list = cbm->registered.pop_all(); list; list = list->pop_all()) { - if (s32 res = func(ppu)) + if (s32 res = list->get()(ppu)) { + // Currently impossible return not_an_error(res); } @@ -271,7 +254,7 @@ s32 cellSysutilRegisterCallback(s32 slot, vm::ptr func, vm: const auto cbm = fxm::get_always(); - cbm->callbacks[slot] = std::make_pair(func, userdata); + cbm->callbacks[slot].store({func, userdata}); return CELL_OK; } @@ -287,7 +270,7 @@ s32 cellSysutilUnregisterCallback(u32 slot) const auto cbm = fxm::get_always(); - cbm->callbacks[slot] = std::make_pair(vm::null, vm::null); + cbm->callbacks[slot].store({}); return CELL_OK; }