Callback syntax changed

call() became overloaded () operator
This commit is contained in:
Nekotekina 2015-01-11 13:43:40 +03:00
parent c36e692411
commit da09477be8
16 changed files with 69 additions and 58 deletions

View file

@ -141,7 +141,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
{ {
// calling Exec() directly in SIGSEGV handler may cause problems // calling Exec() directly in SIGSEGV handler may cause problems
// (probably because Exec() creates new thread, faults of this thread aren't handled by this handler anymore) // (probably because Exec() creates new thread, faults of this thread aren't handled by this handler anymore)
Emu.GetCallbackManager().Async([this]() Emu.GetCallbackManager().Async([this](PPUThread& PPU)
{ {
SPU.Status.SetValue(SPU_STATUS_RUNNING); SPU.Status.SetValue(SPU_STATUS_RUNNING);
Exec(); Exec();

View file

@ -356,7 +356,7 @@ namespace vm
public: public:
typedef RT(*type)(T...); typedef RT(*type)(T...);
RT call(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified CPU thread context RT operator()(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified CPU thread context
RT operator()(T... args) const; // defined in CB_FUNC.h, call using current CPU thread context RT operator()(T... args) const; // defined in CB_FUNC.h, call using current CPU thread context

View file

@ -289,9 +289,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
if (m_flip_handler) if (m_flip_handler)
{ {
auto cb = m_flip_handler; auto cb = m_flip_handler;
Emu.GetCallbackManager().Async([cb]() Emu.GetCallbackManager().Async([cb](PPUThread& CPU)
{ {
cb(1); cb(CPU, 1);
}); });
} }
@ -2201,9 +2201,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{ {
const u32 cause = ARGS(0); const u32 cause = ARGS(0);
auto cb = m_user_handler; auto cb = m_user_handler;
Emu.GetCallbackManager().Async([cb, cause]() Emu.GetCallbackManager().Async([cb, cause](PPUThread& CPU)
{ {
cb(cause); cb(CPU, cause);
}); });
} }
break; break;
@ -2370,9 +2370,9 @@ void RSXThread::Task()
if (m_vblank_handler) if (m_vblank_handler)
{ {
auto cb = m_vblank_handler; auto cb = m_vblank_handler;
Emu.GetCallbackManager().Async([cb]() Emu.GetCallbackManager().Async([cb](PPUThread& CPU)
{ {
cb(1); cb(CPU, 1);
}); });
} }
continue; continue;

View file

@ -163,18 +163,19 @@ namespace cb_detail
namespace vm namespace vm
{ {
template<typename AT, typename RT, typename... T> template<typename AT, typename RT, typename... T>
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::call(CPUThread& CPU, T... args) const __forceinline RT _ptr_base<RT(*)(T...), 1, AT>::operator()(CPUThread& CPU, T... args) const
{ {
const u32 pc = vm::get_ref<be_t<u32>>((u32)m_addr); const u32 pc = vm::get_ref<be_t<u32>>((u32)m_addr);
const u32 rtoc = vm::get_ref<be_t<u32>>((u32)m_addr + 4); const u32 rtoc = vm::get_ref<be_t<u32>>((u32)m_addr + 4);
assert(CPU.GetType() == CPU_THREAD_PPU);
return cb_detail::_func_caller<RT, T...>::call(static_cast<PPUThread&>(CPU), pc, rtoc, args...); return cb_detail::_func_caller<RT, T...>::call(static_cast<PPUThread&>(CPU), pc, rtoc, args...);
} }
template<typename AT, typename RT, typename... T> template<typename AT, typename RT, typename... T>
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::operator ()(T... args) const __forceinline RT _ptr_base<RT(*)(T...), 1, AT>::operator()(T... args) const
{ {
return call(GetCurrentPPUThread(), args...); return operator()(GetCurrentPPUThread(), args...);
} }
} }

View file

@ -7,25 +7,33 @@
#include "Emu/ARMv7/ARMv7Thread.h" #include "Emu/ARMv7/ARMv7Thread.h"
#include "Callback.h" #include "Callback.h"
void CallbackManager::Register(const std::function<s32()>& func) void CallbackManager::Register(const std::function<s32(PPUThread& PPU)>& func)
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
m_cb_list.push_back(func); m_cb_list.push_back([=](CPUThread& CPU) -> s32
{
assert(CPU.GetType() == CPU_THREAD_PPU);
return func(static_cast<PPUThread&>(CPU));
});
} }
void CallbackManager::Async(const std::function<void()>& func) void CallbackManager::Async(const std::function<void(PPUThread& PPU)>& func)
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
m_async_list.push_back(func); m_async_list.push_back([=](CPUThread& CPU)
{
assert(CPU.GetType() == CPU_THREAD_PPU);
func(static_cast<PPUThread&>(CPU));
});
m_cb_thread->Notify(); m_cb_thread->Notify();
} }
bool CallbackManager::Check(s32& result) bool CallbackManager::Check(CPUThread& CPU, s32& result)
{ {
std::function<s32()> func = nullptr; std::function<s32(CPUThread& CPU)> func;
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
@ -38,7 +46,7 @@ bool CallbackManager::Check(s32& result)
if (func) if (func)
{ {
result = func(); result = func(CPU);
return true; return true;
} }
else else
@ -80,7 +88,7 @@ void CallbackManager::Init()
while (!Emu.IsStopped()) while (!Emu.IsStopped())
{ {
std::function<void()> func = nullptr; std::function<void(CPUThread& CPU)> func;
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
@ -93,9 +101,10 @@ void CallbackManager::Init()
if (func) if (func)
{ {
func(); func(*m_cb_thread);
continue; continue;
} }
m_cb_thread->WaitForAnySignal(); m_cb_thread->WaitForAnySignal();
} }
}); });

View file

@ -1,20 +1,21 @@
#pragma once #pragma once
class CPUThread; class CPUThread;
class PPUThread;
class CallbackManager class CallbackManager
{ {
std::vector<std::function<s32()>> m_cb_list; std::vector<std::function<s32(CPUThread& CPU)>> m_cb_list;
std::vector<std::function<void()>> m_async_list; std::vector<std::function<void(CPUThread& CPU)>> m_async_list;
CPUThread* m_cb_thread; CPUThread* m_cb_thread;
std::mutex m_mutex; std::mutex m_mutex;
public: public:
void Register(const std::function<s32()>& func); // register callback (called in Check() method) void Register(const std::function<s32(PPUThread& PPU)>& func); // register callback (called in Check() method)
void Async(const std::function<void()>& func); // register callback for callback thread (called immediately) void Async(const std::function<void(PPUThread& PPU)>& func); // register callback for callback thread (called immediately)
bool Check(s32& result); // call one callback registered by Register() method bool Check(CPUThread& CPU, s32& result); // call one callback registered by Register() method
void Init(); void Init();

View file

@ -174,7 +174,7 @@ next:
buf_size -= adec.reader.size; buf_size -= adec.reader.size;
res += adec.reader.size; res += adec.reader.size;
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, adec.task.au.auInfo_addr, adec.cbArg); adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, adec.task.au.auInfo_addr, adec.cbArg);
adec.job.pop(adec.task); adec.job.pop(adec.task);
@ -279,7 +279,7 @@ u32 adecOpen(AudioDecoder* adec_ptr)
{ {
// TODO: finalize // TODO: finalize
cellAdec->Warning("adecEndSeq:"); cellAdec->Warning("adecEndSeq:");
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
adec.just_finished = true; adec.just_finished = true;
break; break;
@ -455,12 +455,12 @@ u32 adecOpen(AudioDecoder* adec_ptr)
if (adec.frames.push(frame, &adec.is_closed)) if (adec.frames.push(frame, &adec.is_closed))
{ {
frame.data = nullptr; // to prevent destruction frame.data = nullptr; // to prevent destruction
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
} }
} }
} }
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
break; break;
} }

View file

@ -350,7 +350,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
auto dmuxMsg = vm::ptr<CellDmuxMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16)); auto dmuxMsg = vm::ptr<CellDmuxMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
dmuxMsg->supplementalInfo = stream.userdata; dmuxMsg->supplementalInfo = stream.userdata;
dmux.cbFunc.call(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg);
dmux.is_running = false; dmux.is_running = false;
continue; continue;
@ -500,7 +500,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16)); auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
} }
} }
else else
@ -565,7 +565,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16)); auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
} }
if (pes.has_ts) if (pes.has_ts)
@ -637,7 +637,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
auto dmuxMsg = vm::ptr<CellDmuxMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16)); auto dmuxMsg = vm::ptr<CellDmuxMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
dmuxMsg->supplementalInfo = stream.userdata; dmuxMsg->supplementalInfo = stream.userdata;
dmux.cbFunc.call(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg);
stream = {}; stream = {};
dmux.is_running = false; dmux.is_running = false;
@ -725,7 +725,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16)); auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
} }
if (es.raw_data.size()) if (es.raw_data.size())
@ -737,7 +737,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16)); auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE; esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE;
esMsg->supplementalInfo = stream.userdata; esMsg->supplementalInfo = stream.userdata;
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
break; break;
} }

View file

@ -171,10 +171,10 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
if (callback && (g_msg_dialog_state != msgDialogAbort)) if (callback && (g_msg_dialog_state != msgDialogAbort))
{ {
s32 status = (s32)g_msg_dialog_status; const s32 status = (s32)g_msg_dialog_status;
Emu.GetCallbackManager().Register([callback, userData, status]() -> s32 Emu.GetCallbackManager().Register([callback, userData, status](PPUThread& PPU) -> s32
{ {
callback(status, userData); callback(PPU, status, userData);
return CELL_OK; return CELL_OK;
}); });
} }

View file

@ -316,23 +316,23 @@ void sysutilSendSystemCommand(u64 status, u64 param)
{ {
if (cb.func) if (cb.func)
{ {
Emu.GetCallbackManager().Register([=]() -> s32 Emu.GetCallbackManager().Register([=](PPUThread& PPU) -> s32
{ {
cb.func(status, param, cb.arg); cb.func(PPU, status, param, cb.arg);
return CELL_OK; return CELL_OK;
}); });
} }
} }
} }
s32 cellSysutilCheckCallback() s32 cellSysutilCheckCallback(PPUThread& CPU)
{ {
cellSysutil->Log("cellSysutilCheckCallback()"); cellSysutil->Log("cellSysutilCheckCallback()");
s32 res; s32 res;
u32 count = 0; u32 count = 0;
while (Emu.GetCallbackManager().Check(res)) while (Emu.GetCallbackManager().Check(CPU, res))
{ {
count++; count++;

View file

@ -147,7 +147,7 @@ next:
buf_size -= vdec.reader.size; buf_size -= vdec.reader.size;
res += vdec.reader.size; res += vdec.reader.size;
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); vdec.cbFunc(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
vdec.job.pop(vdec.task); vdec.job.pop(vdec.task);
@ -259,7 +259,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr)
// TODO: finalize // TODO: finalize
cellVdec->Warning("vdecEndSeq:"); cellVdec->Warning("vdecEndSeq:");
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); vdec.cbFunc(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
vdec.just_finished = true; vdec.just_finished = true;
break; break;
@ -516,12 +516,12 @@ u32 vdecOpen(VideoDecoder* vdec_ptr)
if (vdec.frames.push(frame, &vdec.is_closed)) if (vdec.frames.push(frame, &vdec.is_closed))
{ {
frame.data = nullptr; // to prevent destruction frame.data = nullptr; // to prevent destruction
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); vdec.cbFunc(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
} }
} }
} }
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); vdec.cbFunc(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
break; break;
} }

View file

@ -358,7 +358,7 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
memset(mixdata, 0, sizeof(mixdata)); memset(mixdata, 0, sizeof(mixdata));
if (surMixerCb) if (surMixerCb)
{ {
surMixerCb.call(cb_thread, surMixerCbArg, (u32)mixcount, 256); surMixerCb(cb_thread, surMixerCbArg, (u32)mixcount, 256);
} }
//u64 stamp1 = get_system_time(); //u64 stamp1 = get_system_time();

View file

@ -295,7 +295,7 @@ s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group)
return CELL_ESTAT; return CELL_ESTAT;
} }
return spu_printf_agcb.call(CPU, group); return spu_printf_agcb(CPU, group);
} }
s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group) s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group)
@ -307,7 +307,7 @@ s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group)
return CELL_ESTAT; return CELL_ESTAT;
} }
return spu_printf_dgcb.call(CPU, group); return spu_printf_dgcb(CPU, group);
} }
s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread) s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread)
@ -319,7 +319,7 @@ s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread)
return CELL_ESTAT; return CELL_ESTAT;
} }
return spu_printf_atcb.call(CPU, thread); return spu_printf_atcb(CPU, thread);
} }
s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread) s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread)
@ -331,7 +331,7 @@ s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread)
return CELL_ESTAT; return CELL_ESTAT;
} }
return spu_printf_dtcb.call(CPU, thread); return spu_printf_dtcb(CPU, thread);
} }
s32 _sys_snprintf(vm::ptr<char> dst, u32 count, vm::ptr<const char> fmt) // va_args... s32 _sys_snprintf(vm::ptr<char> dst, u32 count, vm::ptr<const char> fmt) // va_args...

View file

@ -919,7 +919,6 @@ void fsAioRead(u32 fd, vm::ptr<CellFsAio> aio, int xid, vm::ptr<void(*)(vm::ptr<
const u64 old_pos = file.Tell(); const u64 old_pos = file.Tell();
file.Seek((u64)aio->offset); file.Seek((u64)aio->offset);
// TODO: use code from cellFsRead or something
if (nbytes != (u32)nbytes) if (nbytes != (u32)nbytes)
{ {
error = CELL_ENOMEM; error = CELL_ENOMEM;
@ -935,11 +934,11 @@ void fsAioRead(u32 fd, vm::ptr<CellFsAio> aio, int xid, vm::ptr<void(*)(vm::ptr<
fd, (u64)aio->offset, aio->buf.addr(), (u64)aio->size, error, res, xid); fd, (u64)aio->offset, aio->buf.addr(), (u64)aio->size, error, res, xid);
} }
if (func) // start callback thread if (func)
{ {
Emu.GetCallbackManager().Async([func, aio, error, xid, res]() Emu.GetCallbackManager().Async([func, aio, error, xid, res](PPUThread& CPU)
{ {
func(aio, error, xid, res); func(CPU, aio, error, xid, res);
}); });
} }

View file

@ -217,7 +217,7 @@ void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<atomic_t<u32>> once_ctrl, vm::p
be_t<u32> cmp = be_t<u32>::make(SYS_PPU_THREAD_ONCE_INIT); be_t<u32> cmp = be_t<u32>::make(SYS_PPU_THREAD_ONCE_INIT);
if (once_ctrl->compare_and_swap(cmp, be_t<u32>::make(SYS_PPU_THREAD_DONE_INIT)) == cmp) if (once_ctrl->compare_and_swap(cmp, be_t<u32>::make(SYS_PPU_THREAD_DONE_INIT)) == cmp)
{ {
init.call(CPU); init(CPU);
} }
} }

View file

@ -11,6 +11,7 @@
#include "Emu/Cell/SPUThread.h" #include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/PPUInstrTable.h" #include "Emu/Cell/PPUInstrTable.h"
#include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsFile.h"
#include "Emu/FS/vfsLocalFile.h"
#include "Emu/FS/vfsDeviceLocalFile.h" #include "Emu/FS/vfsDeviceLocalFile.h"
#include "Emu/DbgCommand.h" #include "Emu/DbgCommand.h"
@ -261,7 +262,7 @@ void Emulator::Load()
if (!m_loader.load(f)) if (!m_loader.load(f))
{ {
LOG_ERROR(LOADER, "Loading '%s' failed", m_elf_path.c_str()); LOG_ERROR(LOADER, "Loading '%s' failed", m_path.c_str());
vm::close(); vm::close();
return; return;
} }