mirror of https://github.com/RPCS3/rpcs3.git
cellSysutil: drain callback queue at single step
This way if a new callback is registered in a process, it will not be executed immediately in the same loop. Remove mutex, use lock-free queue.
This commit is contained in:
parent
3b83e223d8
commit
7a4282b4c0
|
@ -6,43 +6,27 @@
|
||||||
#include "cellSysutil.h"
|
#include "cellSysutil.h"
|
||||||
|
|
||||||
#include "Utilities/StrUtil.h"
|
#include "Utilities/StrUtil.h"
|
||||||
|
#include "Utilities/lockless.h"
|
||||||
#include <mutex>
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
LOG_CHANNEL(cellSysutil);
|
LOG_CHANNEL(cellSysutil);
|
||||||
|
|
||||||
struct sysutil_cb_manager
|
struct sysutil_cb_manager
|
||||||
{
|
{
|
||||||
std::mutex mutex;
|
struct alignas(8) registered_cb
|
||||||
|
|
||||||
std::array<std::pair<vm::ptr<CellSysutilCallback>, vm::ptr<void>>, 4> callbacks;
|
|
||||||
|
|
||||||
std::queue<std::function<s32(ppu_thread&)>> registered;
|
|
||||||
|
|
||||||
std::function<s32(ppu_thread&)> get_cb()
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(mutex);
|
vm::ptr<CellSysutilCallback> first;
|
||||||
|
vm::ptr<void> second;
|
||||||
|
};
|
||||||
|
|
||||||
if (registered.empty())
|
atomic_t<registered_cb> callbacks[4]{};
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto func = std::move(registered.front());
|
lf_queue<std::function<s32(ppu_thread&)>> registered;
|
||||||
|
|
||||||
registered.pop();
|
|
||||||
|
|
||||||
return func;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&& cb)
|
extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&& cb)
|
||||||
{
|
{
|
||||||
const auto cbm = fxm::get_always<sysutil_cb_manager>();
|
const auto cbm = fxm::get_always<sysutil_cb_manager>();
|
||||||
|
|
||||||
std::lock_guard lock(cbm->mutex);
|
|
||||||
|
|
||||||
cbm->registered.push(std::move(cb));
|
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<sysutil_cb_manager>())
|
if (const auto cbm = fxm::get<sysutil_cb_manager>())
|
||||||
{
|
{
|
||||||
for (auto& cb : cbm->callbacks)
|
for (sysutil_cb_manager::registered_cb cb : cbm->callbacks)
|
||||||
{
|
{
|
||||||
if (cb.first)
|
if (cb.first)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(cbm->mutex);
|
|
||||||
|
|
||||||
cbm->registered.push([=](ppu_thread& ppu) -> s32
|
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)
|
// 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<sysutil_cb_manager>();
|
const auto cbm = fxm::get_always<sysutil_cb_manager>();
|
||||||
|
|
||||||
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);
|
return not_an_error(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +254,7 @@ s32 cellSysutilRegisterCallback(s32 slot, vm::ptr<CellSysutilCallback> func, vm:
|
||||||
|
|
||||||
const auto cbm = fxm::get_always<sysutil_cb_manager>();
|
const auto cbm = fxm::get_always<sysutil_cb_manager>();
|
||||||
|
|
||||||
cbm->callbacks[slot] = std::make_pair(func, userdata);
|
cbm->callbacks[slot].store({func, userdata});
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +270,7 @@ s32 cellSysutilUnregisterCallback(u32 slot)
|
||||||
|
|
||||||
const auto cbm = fxm::get_always<sysutil_cb_manager>();
|
const auto cbm = fxm::get_always<sysutil_cb_manager>();
|
||||||
|
|
||||||
cbm->callbacks[slot] = std::make_pair(vm::null, vm::null);
|
cbm->callbacks[slot].store({});
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue