diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 9ee54411c0..ba4c98f363 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -141,7 +141,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) { // 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) - Emu.GetCallbackManager().Async([this]() + Emu.GetCallbackManager().Async([this](PPUThread& PPU) { SPU.Status.SetValue(SPU_STATUS_RUNNING); Exec(); diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 60ae33900b..df230aad00 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -356,7 +356,7 @@ namespace vm public: 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 diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 660781eb51..1832b97cb6 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -289,9 +289,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const if (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); auto cb = m_user_handler; - Emu.GetCallbackManager().Async([cb, cause]() + Emu.GetCallbackManager().Async([cb, cause](PPUThread& CPU) { - cb(cause); + cb(CPU, cause); }); } break; @@ -2370,9 +2370,9 @@ void RSXThread::Task() if (m_vblank_handler) { auto cb = m_vblank_handler; - Emu.GetCallbackManager().Async([cb]() + Emu.GetCallbackManager().Async([cb](PPUThread& CPU) { - cb(1); + cb(CPU, 1); }); } continue; diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index ed711656c1..78b82961dc 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -163,18 +163,19 @@ namespace cb_detail namespace vm { template - __forceinline RT _ptr_base::call(CPUThread& CPU, T... args) const + __forceinline RT _ptr_base::operator()(CPUThread& CPU, T... args) const { const u32 pc = vm::get_ref>((u32)m_addr); const u32 rtoc = vm::get_ref>((u32)m_addr + 4); + assert(CPU.GetType() == CPU_THREAD_PPU); return cb_detail::_func_caller::call(static_cast(CPU), pc, rtoc, args...); } template - __forceinline RT _ptr_base::operator ()(T... args) const + __forceinline RT _ptr_base::operator()(T... args) const { - return call(GetCurrentPPUThread(), args...); + return operator()(GetCurrentPPUThread(), args...); } } diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index 71fa8ba830..e01b341fbe 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -7,25 +7,33 @@ #include "Emu/ARMv7/ARMv7Thread.h" #include "Callback.h" -void CallbackManager::Register(const std::function& func) +void CallbackManager::Register(const std::function& func) { std::lock_guard 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(CPU)); + }); } -void CallbackManager::Async(const std::function& func) +void CallbackManager::Async(const std::function& func) { std::lock_guard 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(CPU)); + }); + m_cb_thread->Notify(); } -bool CallbackManager::Check(s32& result) +bool CallbackManager::Check(CPUThread& CPU, s32& result) { - std::function func = nullptr; - + std::function func; { std::lock_guard lock(m_mutex); @@ -38,7 +46,7 @@ bool CallbackManager::Check(s32& result) if (func) { - result = func(); + result = func(CPU); return true; } else @@ -80,7 +88,7 @@ void CallbackManager::Init() while (!Emu.IsStopped()) { - std::function func = nullptr; + std::function func; { std::lock_guard lock(m_mutex); @@ -93,9 +101,10 @@ void CallbackManager::Init() if (func) { - func(); + func(*m_cb_thread); continue; } + m_cb_thread->WaitForAnySignal(); } }); diff --git a/rpcs3/Emu/SysCalls/Callback.h b/rpcs3/Emu/SysCalls/Callback.h index ba16b38830..7cb6b8699b 100644 --- a/rpcs3/Emu/SysCalls/Callback.h +++ b/rpcs3/Emu/SysCalls/Callback.h @@ -1,20 +1,21 @@ #pragma once class CPUThread; +class PPUThread; class CallbackManager { - std::vector> m_cb_list; - std::vector> m_async_list; + std::vector> m_cb_list; + std::vector> m_async_list; CPUThread* m_cb_thread; std::mutex m_mutex; public: - void Register(const std::function& func); // register callback (called in Check() method) + void Register(const std::function& func); // register callback (called in Check() method) - void Async(const std::function& func); // register callback for callback thread (called immediately) + void Async(const std::function& 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(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 139ab029f0..8e91455acf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -174,7 +174,7 @@ next: buf_size -= 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); @@ -279,7 +279,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) { // TODO: finalize 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; break; @@ -455,12 +455,12 @@ u32 adecOpen(AudioDecoder* adec_ptr) if (adec.frames.push(frame, &adec.is_closed)) { 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; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 5c17b81125..20d194da6b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -350,7 +350,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) auto dmuxMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; 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; continue; @@ -500,7 +500,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; 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 @@ -565,7 +565,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; 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) @@ -637,7 +637,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) auto dmuxMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->supplementalInfo = stream.userdata; - dmux.cbFunc.call(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); + dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); stream = {}; dmux.is_running = false; @@ -725,7 +725,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; 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()) @@ -737,7 +737,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) auto esMsg = vm::ptr::make(a128(dmux.memAddr) + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE; 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; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index f6f7fefbbe..a652d134f9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -171,10 +171,10 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr s32 + const s32 status = (s32)g_msg_dialog_status; + Emu.GetCallbackManager().Register([callback, userData, status](PPUThread& PPU) -> s32 { - callback(status, userData); + callback(PPU, status, userData); return CELL_OK; }); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 06c419b4b8..cae2a74172 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -316,23 +316,23 @@ void sysutilSendSystemCommand(u64 status, u64 param) { 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; }); } } } -s32 cellSysutilCheckCallback() +s32 cellSysutilCheckCallback(PPUThread& CPU) { cellSysutil->Log("cellSysutilCheckCallback()"); s32 res; u32 count = 0; - while (Emu.GetCallbackManager().Check(res)) + while (Emu.GetCallbackManager().Check(CPU, res)) { count++; diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index ddf5726ff4..2cd526a35d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -147,7 +147,7 @@ next: buf_size -= 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); @@ -259,7 +259,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) // TODO: finalize 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; break; @@ -516,12 +516,12 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) if (vdec.frames.push(frame, &vdec.is_closed)) { 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; } diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 21646f4d1c..bfafe453c1 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -358,7 +358,7 @@ int cellSurMixerCreate(vm::ptr config) memset(mixdata, 0, sizeof(mixdata)); if (surMixerCb) { - surMixerCb.call(cb_thread, surMixerCbArg, (u32)mixcount, 256); + surMixerCb(cb_thread, surMixerCbArg, (u32)mixcount, 256); } //u64 stamp1 = get_system_time(); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 767c3c04da..1629d3fb05 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -295,7 +295,7 @@ s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group) 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) @@ -307,7 +307,7 @@ s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group) 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) @@ -319,7 +319,7 @@ s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread) 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) @@ -331,7 +331,7 @@ s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread) return CELL_ESTAT; } - return spu_printf_dtcb.call(CPU, thread); + return spu_printf_dtcb(CPU, thread); } s32 _sys_snprintf(vm::ptr dst, u32 count, vm::ptr fmt) // va_args... diff --git a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp index ec5e07daed..39f25e1513 100644 --- a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -919,7 +919,6 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptroffset); - // TODO: use code from cellFsRead or something if (nbytes != (u32)nbytes) { error = CELL_ENOMEM; @@ -935,11 +934,11 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptroffset, 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); }); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index bb1b49eead..4f2d19d532 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -217,7 +217,7 @@ void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm::p be_t cmp = be_t::make(SYS_PPU_THREAD_ONCE_INIT); if (once_ctrl->compare_and_swap(cmp, be_t::make(SYS_PPU_THREAD_DONE_INIT)) == cmp) { - init.call(CPU); + init(CPU); } } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 9e9da63152..ee84464bd8 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -11,6 +11,7 @@ #include "Emu/Cell/SPUThread.h" #include "Emu/Cell/PPUInstrTable.h" #include "Emu/FS/vfsFile.h" +#include "Emu/FS/vfsLocalFile.h" #include "Emu/FS/vfsDeviceLocalFile.h" #include "Emu/DbgCommand.h" @@ -261,7 +262,7 @@ void Emulator::Load() 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(); return; }