From ea5110cec3c8d5e5f19166a131fc8f8658241f84 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 12 Apr 2015 04:36:25 +0300 Subject: [PATCH] Various changes --- rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp | 6 +- rpcs3/Emu/Cell/SPUThread.cpp | 22 +- rpcs3/Emu/RSX/RSXThread.cpp | 13 +- rpcs3/Emu/SysCalls/FuncList.cpp | 8 +- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 34 +-- rpcs3/Emu/SysCalls/Modules/cellAudio.h | 12 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 3 +- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 61 +++++- rpcs3/Emu/SysCalls/SysCalls.cpp | 24 +-- rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_cond.cpp | 61 +++--- rpcs3/Emu/SysCalls/lv2/sys_cond.h | 4 +- rpcs3/Emu/SysCalls/lv2/sys_event.cpp | 50 ++--- rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp | 28 +-- rpcs3/Emu/SysCalls/lv2/sys_fs.cpp | 42 ++-- rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp | 11 +- rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp | 85 ++++---- rpcs3/Emu/SysCalls/lv2/sys_lwcond.h | 4 +- rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp | 16 +- rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp | 24 +-- rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp | 207 +++++++++++-------- rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h | 38 ++-- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 131 ++++++------ 23 files changed, 483 insertions(+), 403 deletions(-) diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp index b619d5bb6b..42bdedb6d2 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp @@ -64,7 +64,7 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr pAr { sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock); - std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); if (!t) { @@ -106,7 +106,7 @@ s32 sceKernelDeleteThread(s32 threadId) { sceLibKernel.Warning("sceKernelDeleteThread(threadId=0x%x)", threadId); - std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); if (!t) { @@ -264,7 +264,7 @@ s32 sceKernelWaitThreadEnd(s32 threadId, vm::psv::ptr pExitStatus, vm::psv: { sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout); - std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); if (!t) { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 317e2a450a..7468d41116 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -273,12 +273,11 @@ void SPUThread::do_dma_transfer(u32 cmd, spu_mfc_arg_t args) const u32 index = (eal - SYS_SPU_THREAD_BASE_LOW) / SYS_SPU_THREAD_OFFSET; // thread number in group const u32 offset = (eal - SYS_SPU_THREAD_BASE_LOW) % SYS_SPU_THREAD_OFFSET; // LS offset or MMIO register - std::shared_ptr group = tg.lock(); - std::shared_ptr t; + const auto group = tg.lock(); - if (group && index < group->num && (t = group->threads[index])) + if (group && index < group->num && group->threads[index]) { - auto& spu = static_cast(*t); + auto& spu = static_cast(*group->threads[index]); if (offset + args.size - 1 < 0x40000) // LS access { @@ -489,6 +488,7 @@ u32 SPUThread::get_ch_count(u32 ch) switch (ch) { + //case MFC_Cmd: return 16; //case SPU_WrSRR0: return 1; break; //case SPU_RdSRR0: return 1; break; case SPU_WrOutMbox: return ch_out_mbox.get_count() ^ 1; break; @@ -673,7 +673,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr queue = this->spup[spup].lock(); + const auto queue = this->spup[spup].lock(); if (!queue) { @@ -710,7 +710,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr queue = this->spup[spup].lock(); + const auto queue = this->spup[spup].lock(); if (!queue) { @@ -753,9 +753,9 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(data); - if (!Emu.GetIdManager().GetIDData(data, ef)) + if (!ef) { return ch_in_mbox.push_uncond(CELL_ESRCH); } @@ -799,9 +799,9 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(data); - if (!Emu.GetIdManager().GetIDData(data, ef)) + if (!ef) { return; } @@ -1121,7 +1121,7 @@ void SPUThread::stop_and_signal(u32 code) LV2_LOCK; - std::shared_ptr group = tg.lock(); + const auto group = tg.lock(); if (!group) { diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index e302ec5de5..72f76f6fca 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2484,18 +2484,19 @@ void RSXThread::Task() if (get_system_time() - start_time > m_vblank_count * 1000000 / 60) { m_vblank_count++; - if (m_vblank_handler) + + if (auto cb = m_vblank_handler) { - auto cb = m_vblank_handler; - Emu.GetCallbackManager().Async([cb](PPUThread& CPU) + Emu.GetCallbackManager().Async([=](PPUThread& CPU) { cb(CPU, 1); }); } - continue; } - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + } } }); diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index f6a5eae46d..b240a0d6ed 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -5,7 +5,7 @@ std::string SysCalls::GetFuncName(const u64 fid) { // check syscalls - switch (fid) + switch (~fid) { case 1: return "sys_process_getpid"; case 2: return "sys_process_wait_for_child"; @@ -26,7 +26,7 @@ std::string SysCalls::GetFuncName(const u64 fid) case 29: return "sys_process_get_id"; case 30: return "_sys_process_get_paramsfo"; case 31: return "sys_process_get_ppu_guid"; - case 41: return "sys_internal_ppu_thread_exit"; + case 41: return "_sys_ppu_thread_exit"; case 43: return "sys_ppu_thread_yield"; case 44: return "sys_ppu_thread_join"; case 45: return "sys_ppu_thread_detach"; @@ -36,7 +36,7 @@ std::string SysCalls::GetFuncName(const u64 fid) case 49: return "sys_ppu_thread_get_stack_information"; case 50: return "sys_ppu_thread_stop"; case 51: return "sys_ppu_thread_restart"; - case 52: return "sys_ppu_thread_create"; + case 52: return "_sys_ppu_thread_create"; case 53: return "sys_ppu_thread_start"; case 56: return "sys_ppu_thread_rename"; case 57: return "sys_ppu_thread_recover_page_fault"; @@ -4414,5 +4414,5 @@ std::string SysCalls::GetFuncName(const u64 fid) } } - return fmt::format("0x%08llX", fid); + return ~fid < 1024 ? fmt::format("syscall_%lld", ~fid) : fmt::format("0x%08llX", fid); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index b5d9abd8df..47e7e9543c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -206,25 +206,17 @@ s32 cellAudioInit() auto step_volume = [](AudioPortConfig& port) // part of cellAudioSetPortLevel functionality { - if (port.level_inc) - { - port.level += port.level_inc; + const auto param = port.level_set.read_sync(); - if (port.level_inc > 0.0f) + if (param.inc != 0.0f) + { + port.level += param.inc; + const bool dec = param.inc < 0.0f; + + if ((!dec && param.value - port.level <= 0.0f) || (dec && param.value - port.level >= 0.0f)) { - if (port.level_set - port.level <= 0.0f) - { - port.level = port.level_set; - port.level_inc = 0.0f; - } - } - else - { - if (port.level_set - port.level >= 0.0f) - { - port.level = port.level_set; - port.level_inc = 0.0f; - } + port.level = param.value; + port.level_set.compare_and_swap(param, { param.value, 0.0f }); } } }; @@ -547,8 +539,7 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN port.level = 1.0f; } - port.level_set = port.level; - port.level_inc = 0.0f; + port.level_set.data = { port.level, 0.0f }; *portNum = port_index; cellAudio.Warning("*** audio port opened(nChannel=%d, nBlock=%d, attr=0x%llx, level=%f): port = %d", channel, block, attr, port.level, port_index); @@ -754,10 +745,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) if (level >= 0.0f) { - std::lock_guard lock(g_audio.mutex); - - port.level_set = level; - port.level_inc = (port.level - level) / 624.0f; + port.level_set.exchange({ level, (port.level - level) / 624.0f }); } else { diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.h b/rpcs3/Emu/SysCalls/Modules/cellAudio.h index ca165476c1..84b6bd65b4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.h @@ -108,9 +108,15 @@ struct AudioPortConfig u32 addr; u32 read_index_addr; u32 size; - float level; - float level_set; - float level_inc; + + struct level_set_t + { + float value; + float inc; + }; + + float level; + atomic_le_t level_set; }; struct AudioConfig //custom structure diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index dcf5cc2863..5e289cfb12 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -319,8 +319,7 @@ int cellSurMixerCreate(vm::ptr config) port.size = port.channel * port.block * AUDIO_SAMPLES * sizeof(float); port.tag = 0; port.level = 1.0f; - port.level_set = 1.0f; - port.level_inc = 0.0f; + port.level_set.data = { 1.0f, 0.0f }; libmixer.Warning("*** audio port opened (port=%d)", g_surmx.audio_port); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index f5d3426e95..8923084b84 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -579,7 +579,7 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr lwcond, u64 timeout) lwmutex->recursive_count = 0; // call the syscall - s32 res = _sys_lwcond_queue_wait(lwcond->lwcond_queue, lwmutex->sleep_queue, timeout); + s32 res = _sys_lwcond_queue_wait(CPU, lwcond->lwcond_queue, lwmutex->sleep_queue, timeout); if (res == CELL_OK || res == CELL_ESRCH) { @@ -1210,6 +1210,65 @@ void sys_spinlock_unlock(vm::ptr> lock) g_sys_spinlock_wm.notify(lock.addr()); } +s32 sys_ppu_thread_create(PPUThread& CPU, vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) +{ + sysPrxForUser.Warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", thread_id, entry, arg, prio, stacksize, flags, threadname); + + // (allocate TLS) + // (return CELL_ENOMEM if failed) + // ... + + vm::stackvar attr(CPU); + + attr->entry = entry; + attr->tls = 0; + + // call the syscall + if (s32 res = _sys_ppu_thread_create(thread_id, attr, arg, 0, prio, stacksize, flags, threadname)) + { + return res; + } + + // run the thread + return flags & SYS_PPU_THREAD_CREATE_INTERRUPT ? CELL_OK : sys_ppu_thread_start(static_cast(*thread_id)); +} + +s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr thread_id) +{ + sysPrxForUser.Log("sys_ppu_thread_get_id(thread_id=*0x%x)", thread_id); + + *thread_id = CPU.GetId(); + + return CELL_OK; +} + +void sys_ppu_thread_exit(PPUThread& CPU, u64 val) +{ + sysPrxForUser.Log("sys_ppu_thread_exit(val=0x%llx)", val); + + // (call registered atexit functions) + // (deallocate TLS) + // ... + + // call the syscall + _sys_ppu_thread_exit(CPU, val); +} + +std::mutex g_once_mutex; + +void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm::ptr init) +{ + sysPrxForUser.Warning("sys_ppu_thread_once(once_ctrl=*0x%x, init=*0x%x)", once_ctrl, init); + + std::lock_guard lock(g_once_mutex); + + if (once_ctrl->compare_and_swap_test(be_t::make(SYS_PPU_THREAD_ONCE_INIT), be_t::make(SYS_PPU_THREAD_DONE_INIT))) + { + // call init function using current thread context + init(CPU); + } +} + Module sysPrxForUser("sysPrxForUser", []() { g_tls_start = 0; diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index fa4a7db522..7f3608fbfb 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -75,7 +75,7 @@ const ppu_func_caller sc_table[1024] = null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, //32-40 UNS - bind_func(sys_internal_ppu_thread_exit), //41 (0x029) + bind_func(_sys_ppu_thread_exit), //41 (0x029) null_func, //42 (0x02A) UNS bind_func(sys_ppu_thread_yield), //43 (0x02B) bind_func(sys_ppu_thread_join), //44 (0x02C) @@ -86,8 +86,8 @@ const ppu_func_caller sc_table[1024] = bind_func(sys_ppu_thread_get_stack_information), //49 (0x031) null_func,//bind_func(sys_ppu_thread_stop), //50 (0x032) ROOT null_func,//bind_func(sys_ppu_thread_restart), //51 (0x033) ROOT - null_func,//bind_func(sys_ppu_thread_create), //52 (0x034) DBG - null_func,//bind_func(sys_ppu_thread_start), //53 (0x035) + bind_func(_sys_ppu_thread_create), //52 (0x034) DBG + bind_func(sys_ppu_thread_start), //53 (0x035) null_func,//bind_func(sys_ppu_...), //54 (0x036) ROOT null_func,//bind_func(sys_ppu_...), //55 (0x037) ROOT bind_func(sys_ppu_thread_rename), //56 (0x038) @@ -888,34 +888,32 @@ const ppu_func_caller sc_table[1024] = void null_func(PPUThread& CPU) { - LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", CPU.GPR[11], SysCalls::GetFuncName(CPU.GPR[11])); + const auto code = CPU.GPR[11]; + LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code)); CPU.GPR[3] = 0; - return; } void SysCalls::DoSyscall(PPUThread& CPU, u64 code) { - auto old_last_syscall = CPU.m_last_syscall; - CPU.m_last_syscall = code; - if (code >= 1024) { + CPU.m_last_syscall = code; throw "Invalid syscall number"; } - - //Auto Pause using simple singleton. - Debug::AutoPause::getInstance().TryPause(code); + + auto old_last_syscall = CPU.m_last_syscall; + CPU.m_last_syscall = ~code; if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "Syscall %d called: %s", code, SysCalls::GetFuncName(code)); + LOG_NOTICE(PPU, "Syscall %lld called: %s", code, SysCalls::GetFuncName(~code)); } sc_table[code](CPU); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "Syscall %d finished: %s -> 0x%llx", code, SysCalls::GetFuncName(code), CPU.GPR[3]); + LOG_NOTICE(PPU, "Syscall %lld finished: %s -> 0x%llx", code, SysCalls::GetFuncName(~code), CPU.GPR[3]); } CPU.m_last_syscall = old_last_syscall; diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp b/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp index cc1ebc702f..0cf0fa52f7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp @@ -149,7 +149,7 @@ u32 sleep_queue_t::signal(u32 protocol) u64 sel = ~0ull; for (auto& v : m_waiting) { - if (std::shared_ptr t = Emu.GetCPU().GetThread(v)) + if (const auto t = Emu.GetCPU().GetThread(v)) { const u64 prio = t->GetPrio(); if (prio < highest_prio) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index 844fb58641..408549eed3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -19,9 +19,9 @@ s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -50,14 +50,14 @@ s32 sys_cond_destroy(u32 cond_id) LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters || cond->signaled) + if (!cond->waiters.empty() || cond->signaled) { return CELL_EBUSY; } @@ -78,17 +78,17 @@ s32 sys_cond_signal(u32 cond_id) LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters) + if (!cond->waiters.empty()) { cond->signaled++; - cond->waiters--; + cond->waiters.erase(cond->waiters.begin()); cond->cv.notify_one(); } @@ -101,16 +101,17 @@ s32 sys_cond_signal_all(u32 cond_id) LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters) + if (const u32 count = cond->waiters.size()) { - cond->signaled += cond->waiters.exchange(0); + cond->signaled += count; + cond->waiters.clear(); cond->cv.notify_all(); } @@ -119,13 +120,13 @@ s32 sys_cond_signal_all(u32 cond_id) s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) { - sys_cond.Todo("sys_cond_signal_to(cond_id=%d, thread_id=%d)", cond_id, thread_id); + sys_cond.Log("sys_cond_signal_to(cond_id=%d, thread_id=%d)", cond_id, thread_id); LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } @@ -135,13 +136,15 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) return CELL_ESRCH; } - if (!cond->waiters) + const auto found = cond->waiters.find(thread_id); + + if (found == cond->waiters.end()) { return CELL_EPERM; } cond->signaled++; - cond->waiters--; + cond->waiters.erase(found); cond->cv.notify_one(); return CELL_OK; @@ -155,22 +158,22 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId()); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); if (cond->mutex->owner.owner_before(thread) || thread.owner_before(cond->mutex->owner)) // check equality { return CELL_EPERM; } - // protocol is ignored in current implementation - cond->waiters++; + // add waiter; protocol is ignored in current implementation + cond->waiters.emplace(CPU.GetId()); // unlock mutex cond->mutex->owner.reset(); @@ -183,17 +186,21 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) // save recursive value const u32 recursive_value = cond->mutex->recursive_count.exchange(0); - while (!cond->mutex->owner.expired() || !cond->signaled) + while (!cond->mutex->owner.expired() || !cond->signaled || cond->waiters.count(CPU.GetId())) { const bool is_timedout = timeout && get_system_time() - start_time > timeout; - // check timeout only if no thread signaled (the flaw of avoiding sleep queue) - if (is_timedout && cond->mutex->owner.expired() && !cond->signaled) + // check timeout + if (is_timedout && cond->mutex->owner.expired()) { // cancel waiting if the mutex is free, restore its owner and recursive value cond->mutex->owner = thread; cond->mutex->recursive_count = recursive_value; - cond->waiters--; + + if (!cond->waiters.erase(CPU.GetId())) + { + throw __FUNCTION__; + } return CELL_ETIMEDOUT; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.h b/rpcs3/Emu/SysCalls/lv2/sys_cond.h index 6b2bda4720..43164e58c7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.h @@ -24,9 +24,9 @@ struct cond_t // TODO: use sleep queue, possibly remove condition variable std::condition_variable cv; - std::atomic waiters; + std::unordered_set waiters; - cond_t(std::shared_ptr& mutex, u64 name) + cond_t(const std::shared_ptr& mutex, u64 name) : mutex(mutex) , name(name) , signaled(0) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index fbe5ea7b8d..0fa40d34a5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -67,9 +67,9 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } @@ -106,9 +106,9 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } @@ -146,9 +146,9 @@ s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } @@ -203,14 +203,14 @@ s32 sys_event_queue_drain(u32 equeue_id) LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } - queue->events = {}; + queue->events.clear(); return CELL_OK; } @@ -245,9 +245,9 @@ s32 sys_event_port_destroy(u32 eport_id) LV2_LOCK; - std::shared_ptr port; + const auto port = Emu.GetIdManager().GetIDData(eport_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port)) + if (!port) { return CELL_ESRCH; } @@ -268,10 +268,10 @@ s32 sys_event_port_connect_local(u32 eport_id, u32 equeue_id) LV2_LOCK; - std::shared_ptr port; - std::shared_ptr queue; + const auto port = Emu.GetIdManager().GetIDData(eport_id); + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port) || !Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!port || !queue) { return CELL_ESRCH; } @@ -297,14 +297,14 @@ s32 sys_event_port_disconnect(u32 eport_id) LV2_LOCK; - std::shared_ptr port; + const auto port = Emu.GetIdManager().GetIDData(eport_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port)) + if (!port) { return CELL_ESRCH; } - std::shared_ptr queue = port->queue.lock(); + const auto queue = port->queue.lock(); if (!queue) { @@ -313,16 +313,6 @@ s32 sys_event_port_disconnect(u32 eport_id) // CELL_EBUSY is not returned - //const u64 source = port->name ? port->name : ((u64)process_getpid() << 32) | (u64)eport_id; - - //for (auto& event : queue->events) - //{ - // if (event.source == source) - // { - // return CELL_EBUSY; // ??? - // } - //} - port->queue.reset(); return CELL_OK; @@ -334,14 +324,14 @@ s32 sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) LV2_LOCK; - std::shared_ptr port; + const auto port = Emu.GetIdManager().GetIDData(eport_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port)) + if (!port) { return CELL_ESRCH; } - std::shared_ptr queue = port->queue.lock(); + const auto queue = port->queue.lock(); if (!queue) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index bd1857bdd4..927b622158 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -60,9 +60,9 @@ s32 sys_event_flag_destroy(u32 id) LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -105,9 +105,9 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t default: return CELL_EINVAL; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -212,9 +212,9 @@ s32 sys_event_flag_trywait(u32 id, u64 bitptn, u32 mode, vm::ptr result) default: return CELL_EINVAL; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -252,9 +252,9 @@ s32 sys_event_flag_set(u32 id, u64 bitptn) LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -280,9 +280,9 @@ s32 sys_event_flag_clear(u32 id, u64 bitptn) LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -308,9 +308,9 @@ s32 sys_event_flag_cancel(u32 id, vm::ptr num) *num = 0; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -344,9 +344,9 @@ s32 sys_event_flag_get(u32 id, vm::ptr flags) return CELL_EFAULT; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { *flags = 0; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index f252098984..b025d2a11d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -135,9 +135,9 @@ s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) { sys_fs.Log("sys_fs_read(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file) || file->flags & CELL_FS_O_WRONLY) + if (!file || file->flags & CELL_FS_O_WRONLY) { return CELL_FS_EBADF; } @@ -153,9 +153,9 @@ s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrit { sys_fs.Log("sys_fs_write(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file) || !(file->flags & CELL_FS_O_ACCMODE)) + if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { return CELL_FS_EBADF; } @@ -173,9 +173,9 @@ s32 sys_fs_close(u32 fd) { sys_fs.Log("sys_fs_close(fd=0x%x)", fd); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -209,9 +209,9 @@ s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) { sys_fs.Warning("sys_fs_readdir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread); - std::shared_ptr directory; + const auto directory = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, directory)) + if (!directory) { return CELL_FS_EBADF; } @@ -237,9 +237,9 @@ s32 sys_fs_closedir(u32 fd) { sys_fs.Log("sys_fs_closedir(fd=0x%x)", fd); - std::shared_ptr directory; + const auto directory = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, directory)) + if (!directory) { return CELL_FS_EBADF; } @@ -336,9 +336,9 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) { sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -480,9 +480,9 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) return CELL_FS_EINVAL; } - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -498,11 +498,11 @@ s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_ { sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { - CELL_FS_EBADF; + return CELL_FS_EBADF; } *sector_size = 4096; // ? @@ -558,13 +558,15 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) { sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { - CELL_FS_EBADF; + return CELL_FS_EBADF; } + std::lock_guard lock(file->mutex); + u64 initialSize = file->file->GetSize(); if (initialSize < size) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index f124378b37..5da5c863e0 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -23,7 +23,7 @@ s32 sys_interrupt_tag_destroy(u32 intrtag) return CELL_ESRCH; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); + const auto t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); if (!t) { @@ -58,7 +58,7 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, return CELL_ESRCH; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); + const auto t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); if (!t) { @@ -71,7 +71,7 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, // CELL_ESTAT is not returned (can't detect exact condition) - std::shared_ptr it = Emu.GetCPU().GetThread((u32)intrthread); + const auto it = Emu.GetCPU().GetThread((u32)intrthread); if (!it) { @@ -132,8 +132,9 @@ s32 _sys_interrupt_thread_disestablish(u32 ih, vm::ptr r13) { sys_interrupt.Todo("_sys_interrupt_thread_disestablish(ih=0x%x, r13=*0x%x)", ih, r13); - std::shared_ptr handler; - if (!Emu.GetIdManager().GetIDData(ih, handler)) + const auto handler = Emu.GetIdManager().GetIDData(ih); + + if (!handler) { return CELL_ESRCH; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp index a2765b462a..c0f5dfe699 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp @@ -37,14 +37,14 @@ s32 _sys_lwcond_destroy(u32 lwcond_id) LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters) + if (!cond->waiters.empty() || cond->signaled1 || cond->signaled2) { return CELL_EBUSY; } @@ -60,36 +60,26 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod LV2_LOCK; - std::shared_ptr cond; - std::shared_ptr mutex; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) + if (!cond || (lwmutex_id && !mutex)) { return CELL_ESRCH; } - if (lwmutex_id && !Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) - { - return CELL_ESRCH; - } - - // ppu_thread_id is ignored in current implementation - if (mode != 1 && mode != 2 && mode != 3) { sys_lwcond.Error("_sys_lwcond_signal(%d): invalid mode (%d)", lwcond_id, mode); } - if (~ppu_thread_id) - { - sys_lwcond.Todo("_sys_lwcond_signal(%d): ppu_thread_id (%d)", lwcond_id, ppu_thread_id); - } + const auto found = ~ppu_thread_id ? cond->waiters.find(ppu_thread_id) : cond->waiters.begin(); if (mode == 1) { // mode 1: lightweight mutex was initially owned by the calling thread - if (!cond->waiters) + if (found == cond->waiters.end()) { return CELL_EPERM; } @@ -100,7 +90,7 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod { // mode 2: lightweight mutex was not owned by the calling thread and waiter hasn't been increased - if (!cond->waiters) + if (found == cond->waiters.end()) { return CELL_OK; } @@ -111,7 +101,7 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod { // in mode 3, lightweight mutex was forcefully owned by the calling thread - if (!cond->waiters) + if (found == cond->waiters.end()) { return ~ppu_thread_id ? CELL_ENOENT : CELL_EPERM; } @@ -119,10 +109,8 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod cond->signaled1++; } - if (--cond->waiters) - { - cond->cv.notify_one(); - } + cond->waiters.erase(found); + cond->cv.notify_one(); return CELL_OK; } @@ -133,15 +121,10 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) LV2_LOCK; - std::shared_ptr cond; - std::shared_ptr mutex; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) - { - return CELL_ESRCH; - } - - if (lwmutex_id && !Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!cond || (lwmutex_id && !mutex)) { return CELL_ESRCH; } @@ -151,10 +134,11 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) sys_lwcond.Error("_sys_lwcond_signal_all(%d): invalid mode (%d)", lwcond_id, mode); } - const s32 count = cond->waiters.exchange(0); + const u32 count = cond->waiters.size(); if (count) { + cond->waiters.clear(); cond->cv.notify_all(); } @@ -176,7 +160,7 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) } } -s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) +s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 timeout) { sys_lwcond.Log("_sys_lwcond_queue_wait(lwcond_id=%d, lwmutex_id=%d, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout); @@ -184,15 +168,10 @@ s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) LV2_LOCK; - std::shared_ptr cond; - std::shared_ptr mutex; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) - { - return CELL_ESRCH; - } - - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!cond || !mutex) { return CELL_ESRCH; } @@ -205,18 +184,28 @@ s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) mutex->cv.notify_one(); } - // protocol is ignored in current implementation - cond->waiters++; + // add waiter; protocol is ignored in current implementation + cond->waiters.emplace(CPU.GetId()); - while (!(cond->signaled1 && mutex->signaled) && !cond->signaled2) + while ((!(cond->signaled1 && mutex->signaled) && !cond->signaled2) || cond->waiters.count(CPU.GetId())) { const bool is_timedout = timeout && get_system_time() - start_time > timeout; - // check timeout only if no thread signaled in mode 1 (the flaw of avoiding sleep queue) - if (is_timedout && !cond->signaled1) + // check timeout + if (is_timedout) { // cancel waiting - cond->waiters--; + if (!cond->waiters.erase(CPU.GetId())) + { + if (cond->signaled1 && !mutex->signaled) + { + cond->signaled1--; + } + else + { + throw __FUNCTION__; + } + } if (mutex->signaled) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h index ef02f85899..7e94ccbdc2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h @@ -26,7 +26,7 @@ struct lwcond_t // TODO: use sleep queue std::condition_variable cv; - std::atomic waiters; + std::unordered_set waiters; lwcond_t(u64 name) : name(name) @@ -47,4 +47,4 @@ s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -77,9 +77,9 @@ s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout) LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -117,9 +117,9 @@ s32 _sys_lwmutex_trylock(u32 lwmutex_id) LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -140,9 +140,9 @@ s32 _sys_lwmutex_unlock(u32 lwmutex_id) LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index 29ee05df8d..79e2a064e4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -54,9 +54,9 @@ s32 sys_mutex_destroy(u32 mutex_id) LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -90,14 +90,14 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId(), CPU_THREAD_PPU); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId(), CPU_THREAD_PPU); if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality { @@ -148,14 +148,14 @@ s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id) LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId()); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality { @@ -190,16 +190,16 @@ s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id) LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId()); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); - if (mutex->owner.owner_before(thread) || thread.owner_before(mutex->owner)) // check equality + if (mutex->owner.owner_before(thread) || thread.owner_before(mutex->owner)) // check inequality { return CELL_EPERM; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index 282d985b68..fe75d53073 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -10,8 +10,10 @@ SysCallBase sys_ppu_thread("sys_ppu_thread"); -void ppu_thread_exit(PPUThread& CPU, u64 errorcode) +void _sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode) { + sys_ppu_thread.Warning("_sys_ppu_thread_exit(errorcode=0x%llx)", errorcode); + CPU.SetExitStatus(errorcode); CPU.Stop(); @@ -25,37 +27,25 @@ void ppu_thread_exit(PPUThread& CPU, u64 errorcode) } } -void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode) -{ - sys_ppu_thread.Log("sys_ppu_thread_exit(0x%llx)", errorcode); - - ppu_thread_exit(CPU, errorcode); -} - -void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode) -{ - sys_ppu_thread.Warning("sys_internal_ppu_thread_exit(0x%llx)", errorcode); - - ppu_thread_exit(CPU, errorcode); -} - -s32 sys_ppu_thread_yield() +void sys_ppu_thread_yield() { sys_ppu_thread.Log("sys_ppu_thread_yield()"); // Note: Or do we actually want to yield? std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - return CELL_OK; } -s32 sys_ppu_thread_join(u64 thread_id, vm::ptr vptr) +s32 sys_ppu_thread_join(u32 thread_id, vm::ptr vptr) { - sys_ppu_thread.Warning("sys_ppu_thread_join(thread_id=%lld, vptr_addr=0x%x)", thread_id, vptr.addr()); + sys_ppu_thread.Warning("sys_ppu_thread_join(thread_id=%d, vptr=*0x%x)", thread_id, vptr); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) return - CELL_ESRCH; + const auto t = Emu.GetCPU().GetThread(thread_id); - while (thr->IsAlive()) + if (!t) + { + return CELL_ESRCH; + } + + while (t->IsAlive()) { if (Emu.IsStopped()) { @@ -65,98 +55,117 @@ s32 sys_ppu_thread_join(u64 thread_id, vm::ptr vptr) std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } - *vptr = thr->GetExitStatus(); + *vptr = t->GetExitStatus(); Emu.GetCPU().RemoveThread(thread_id); return CELL_OK; } -s32 sys_ppu_thread_detach(u64 thread_id) +s32 sys_ppu_thread_detach(u32 thread_id) { - sys_ppu_thread.Todo("sys_ppu_thread_detach(thread_id=%lld)", thread_id); + sys_ppu_thread.Warning("sys_ppu_thread_detach(thread_id=%d)", thread_id); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { return CELL_ESRCH; + } - if (!thr->IsJoinable()) + if (!t->IsJoinable()) + { return CELL_EINVAL; - thr->SetJoinable(false); + } + + t->SetJoinable(false); return CELL_OK; } void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable) { - sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable.addr()); + sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable=*0x%x)", isjoinable); *isjoinable = CPU.IsJoinable(); } -s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio) +s32 sys_ppu_thread_set_priority(u32 thread_id, s32 prio) { - sys_ppu_thread.Log("sys_ppu_thread_set_priority(thread_id=%lld, prio=%d)", thread_id, prio); + sys_ppu_thread.Log("sys_ppu_thread_set_priority(thread_id=%d, prio=%d)", thread_id, prio); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { return CELL_ESRCH; + } - thr->SetPrio(prio); + t->SetPrio(prio); return CELL_OK; } -s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr) +s32 sys_ppu_thread_get_priority(u32 thread_id, vm::ptr priop) { - sys_ppu_thread.Log("sys_ppu_thread_get_priority(thread_id=%lld, prio_addr=0x%x)", thread_id, prio_addr); + sys_ppu_thread.Log("sys_ppu_thread_get_priority(thread_id=%d, priop=*0x%x)", thread_id, priop); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if(!thr) return CELL_ESRCH; + const auto t = Emu.GetCPU().GetThread(thread_id); - vm::write32(prio_addr, (s32)thr->GetPrio()); - - return CELL_OK; -} - -s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr) -{ - sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr); - - vm::write32(info_addr, (u32)CPU.GetStackAddr()); - vm::write32(info_addr + 4, CPU.GetStackSize()); - - return CELL_OK; -} - -s32 sys_ppu_thread_stop(u64 thread_id) -{ - sys_ppu_thread.Warning("sys_ppu_thread_stop(thread_id=%lld)", thread_id); - - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + if (!t) + { return CELL_ESRCH; + } - thr->Stop(); + *priop = static_cast(t->GetPrio()); return CELL_OK; } -s32 sys_ppu_thread_restart(u64 thread_id) +s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr sp) { - sys_ppu_thread.Warning("sys_ppu_thread_restart(thread_id=%lld)", thread_id); + sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(sp=*0x%x)", sp); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + sp->pst_addr = CPU.GetStackAddr(); + sp->pst_size = CPU.GetStackSize(); + + return CELL_OK; +} + +s32 sys_ppu_thread_stop(u32 thread_id) +{ + sys_ppu_thread.Error("sys_ppu_thread_stop(thread_id=%d)", thread_id); + + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { return CELL_ESRCH; + } - thr->Stop(); - thr->Run(); + t->Stop(); + + return CELL_OK; +} + +s32 sys_ppu_thread_restart(u32 thread_id) +{ + sys_ppu_thread.Error("sys_ppu_thread_restart(thread_id=%d)", thread_id); + + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { + return CELL_ESRCH; + } + + t->Stop(); + t->Run(); return CELL_OK; } u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, std::string name, std::function task) { - auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + const auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); auto& ppu = static_cast(*new_thread); @@ -177,54 +186,69 @@ u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joina return ppu.GetId(); } -s32 sys_ppu_thread_create(vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) +s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) { - sys_ppu_thread.Warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", thread_id, entry, arg, prio, stacksize, flags, threadname); + sys_ppu_thread.Warning("_sys_ppu_thread_create(thread_id=*0x%x, param=*0x%x, arg=0x%llx, unk=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", + thread_id, param, arg, unk, prio, stacksize, flags, threadname); if (prio < 0 || prio > 3071) { return CELL_EINVAL; } - bool is_joinable = flags & SYS_PPU_THREAD_CREATE_JOINABLE; - bool is_interrupt = flags & SYS_PPU_THREAD_CREATE_INTERRUPT; + const bool is_joinable = flags & SYS_PPU_THREAD_CREATE_JOINABLE; + const bool is_interrupt = flags & SYS_PPU_THREAD_CREATE_INTERRUPT; if (is_joinable && is_interrupt) { return CELL_EPERM; } - *thread_id = ppu_thread_create(entry, arg, prio, stacksize, is_joinable, is_interrupt, threadname ? threadname.get_ptr() : ""); - return CELL_OK; -} + const auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); -std::mutex g_once_mutex; + auto& ppu = static_cast(*new_thread); -void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm::ptr init) -{ - sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl=*0x%x, init=*0x%x)", once_ctrl, init); + ppu.SetEntry(param->entry); + ppu.SetPrio(prio); + ppu.SetStackSize(stacksize < 0x4000 ? 0x4000 : stacksize); // (hack) adjust minimal stack size + ppu.SetJoinable(is_joinable); + ppu.SetName(threadname.get_ptr()); + ppu.Run(); - std::lock_guard lock(g_once_mutex); + ppu.GPR[3] = arg; + ppu.GPR[4] = unk; // actually unknown - if (once_ctrl->compare_and_swap_test(be_t::make(SYS_PPU_THREAD_ONCE_INIT), be_t::make(SYS_PPU_THREAD_DONE_INIT))) + if (u32 tls = param->tls) // hack { - init(CPU); + ppu.GPR[13] = tls; } -} -s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr thread_id) -{ - sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.addr()); + *thread_id = ppu.GetId(); - *thread_id = CPU.GetId(); return CELL_OK; } -s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr name) +s32 sys_ppu_thread_start(u32 thread_id) { - sys_ppu_thread.Log("sys_ppu_thread_rename(thread_id=0x%llx, name=*0x%x)", thread_id, name); + sys_ppu_thread.Warning("sys_ppu_thread_start(thread_id=%d)", thread_id); - std::shared_ptr t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); + const auto t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); + + if (!t) + { + return CELL_ESRCH; + } + + t->Exec(); + + return CELL_OK; +} + +s32 sys_ppu_thread_rename(u32 thread_id, vm::ptr name) +{ + sys_ppu_thread.Error("sys_ppu_thread_rename(thread_id=%d, name=*0x%x)", thread_id, name); + + const auto t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); if (!t) { @@ -232,5 +256,6 @@ s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr name) } t->SetThreadName(name.get_ptr()); + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h index 5894d5d9c3..ae7057bbef 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h @@ -15,22 +15,32 @@ enum : u64 SYS_PPU_THREAD_CREATE_INTERRUPT = 0x2, }; +struct sys_ppu_thread_stack_t +{ + u32 pst_addr; + u32 pst_size; +}; + +struct ppu_thread_param_t +{ + u32 entry; + u32 tls; +}; + // Aux u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, std::string name, std::function task = nullptr); // SysCalls -void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); -void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode); -s32 sys_ppu_thread_yield(); -s32 sys_ppu_thread_join(u64 thread_id, vm::ptr vptr); -s32 sys_ppu_thread_detach(u64 thread_id); +void _sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); +void sys_ppu_thread_yield(); +s32 sys_ppu_thread_join(u32 thread_id, vm::ptr vptr); +s32 sys_ppu_thread_detach(u32 thread_id); void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable); -s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio); -s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr); -s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr); -s32 sys_ppu_thread_stop(u64 thread_id); -s32 sys_ppu_thread_restart(u64 thread_id); -s32 sys_ppu_thread_create(vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname); -void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm::ptr init); -s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr thread_id); -s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr name); +s32 sys_ppu_thread_set_priority(u32 thread_id, s32 prio); +s32 sys_ppu_thread_get_priority(u32 thread_id, vm::ptr priop); +s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr sp); +s32 sys_ppu_thread_stop(u32 thread_id); +s32 sys_ppu_thread_restart(u32 thread_id); +s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 arg4, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname); +s32 sys_ppu_thread_start(u32 thread_id); +s32 sys_ppu_thread_rename(u32 thread_id, vm::ptr name); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index f4eb597754..eee7e4aa62 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -99,7 +99,7 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, sys_spu.Todo("Unsupported SPU Thread options (0x%x)", option); } - auto t = Emu.GetCPU().AddThread(CPU_THREAD_SPU); + const auto t = Emu.GetCPU().AddThread(CPU_THREAD_SPU); auto& spu = static_cast(*t); @@ -108,8 +108,7 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, spu.SetName(name); spu.m_custom_task = task; - std::shared_ptr group; - Emu.GetIdManager().GetIDData(group_id, group); + const auto group = Emu.GetIdManager().GetIDData(group_id); spu.tg = group; group->threads[spu_num] = t; @@ -141,8 +140,9 @@ s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(group_id, group)) + const auto group = Emu.GetIdManager().GetIDData(group_id); + + if (!group) { return CELL_ESRCH; } @@ -167,7 +167,8 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + if (!t) { return CELL_ESRCH; @@ -175,7 +176,7 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg) auto& spu = static_cast(*t); - std::shared_ptr group = spu.tg.lock(); + const auto group = spu.tg.lock(); assert(spu.index < group->threads.size()); @@ -193,7 +194,7 @@ s32 sys_spu_thread_get_exit_status(u32 id, vm::ptr status) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -246,8 +247,9 @@ s32 sys_spu_thread_group_destroy(u32 id) LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -283,8 +285,9 @@ s32 sys_spu_thread_group_start(u32 id) LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -326,7 +329,7 @@ s32 sys_spu_thread_group_start(u32 id) // because SPU_THREAD_GROUP_STATUS_READY is not possible, run event is delivered immediately - if (std::shared_ptr queue = group->ep_run.lock()) + if (auto queue = group->ep_run.lock()) { queue->push(SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY, id, 0, 0); // TODO: check data2 and data3 } @@ -348,8 +351,9 @@ s32 sys_spu_thread_group_suspend(u32 id) LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -402,8 +406,9 @@ s32 sys_spu_thread_group_resume(u32 id) LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -448,15 +453,16 @@ s32 sys_spu_thread_group_yield(u32 id) LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } if (group->state != SPU_THREAD_GROUP_STATUS_RUNNING) { - return CELL_EINVAL; + return CELL_ESTAT; } // SPU_THREAD_GROUP_STATUS_READY state is not used, so this function does nothing @@ -471,11 +477,10 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) LV2_LOCK; // seems the id can be either SPU Thread Group or SPU Thread + auto thread = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + auto group = Emu.GetIdManager().GetIDData(id); - std::shared_ptr group; - std::shared_ptr thread = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); - - if (!Emu.GetIdManager().GetIDData(id, group) && !thread) + if (!group && !thread) { return CELL_ESRCH; } @@ -510,7 +515,7 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) if (group->state <= SPU_THREAD_GROUP_STATUS_INITIALIZED || group->state == SPU_THREAD_GROUP_STATUS_WAITING || group->state == SPU_THREAD_GROUP_STATUS_WAITING) { - return CELL_EINVAL; + return CELL_ESTAT; } for (auto& t : group->threads) @@ -538,8 +543,9 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -621,7 +627,7 @@ s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) { sys_spu.Log("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=%d)", id, address, value, type); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -656,7 +662,7 @@ s32 sys_spu_thread_read_ls(u32 id, u32 address, vm::ptr value, u32 type) { sys_spu.Log("sys_spu_thread_read_ls(id=%d, address=0x%x, value=*0x%x, type=%d)", id, address, value, type); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -691,7 +697,7 @@ s32 sys_spu_thread_write_spu_mb(u32 id, u32 value) { sys_spu.Warning("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -709,7 +715,7 @@ s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value) { sys_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -732,7 +738,7 @@ s32 sys_spu_thread_get_spu_cfg(u32 id, vm::ptr value) { sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value=*0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -750,7 +756,7 @@ s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value) { sys_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -775,10 +781,10 @@ s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et) LV2_LOCK; - std::shared_ptr group; - std::shared_ptr queue; + const auto group = Emu.GetIdManager().GetIDData(id); + const auto queue = Emu.GetIdManager().GetIDData(eq); - if (!Emu.GetIdManager().GetIDData(id, group) || !Emu.GetIdManager().GetIDData(eq, queue)) + if (!group || !queue) { return CELL_ESRCH; } @@ -831,9 +837,9 @@ s32 sys_spu_thread_group_disconnect_event(u32 id, u32 et) LV2_LOCK; - std::shared_ptr group; + const auto group = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, group)) + if (!group) { return CELL_ESRCH; } @@ -894,11 +900,10 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto queue = Emu.GetIdManager().GetIDData(eq); - std::shared_ptr queue; - - if (!t || !Emu.GetIdManager().GetIDData(eq, queue)) + if (!t || !queue) { return CELL_ESRCH; } @@ -929,7 +934,7 @@ s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -962,11 +967,10 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto queue = Emu.GetIdManager().GetIDData(spuq); - std::shared_ptr queue; - - if (!t || !Emu.GetIdManager().GetIDData(spuq, queue)) + if (!t || !queue) { return CELL_ESRCH; } @@ -1009,7 +1013,7 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -1037,10 +1041,10 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm:: LV2_LOCK; - std::shared_ptr group; - std::shared_ptr queue; + const auto group = Emu.GetIdManager().GetIDData(id); + const auto queue = Emu.GetIdManager().GetIDData(eq); - if (!Emu.GetIdManager().GetIDData(id, group) || !Emu.GetIdManager().GetIDData(eq, queue)) + if (!group || !queue) { return CELL_ESRCH; } @@ -1112,8 +1116,9 @@ s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -1142,7 +1147,7 @@ s32 sys_raw_spu_create(vm::ptr id, vm::ptr attr) LV2_LOCK; - auto t = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); + const auto t = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); if (!t) { @@ -1164,7 +1169,7 @@ s32 sys_raw_spu_destroy(u32 id) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1191,7 +1196,7 @@ s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ptr return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1221,7 +1226,7 @@ s32 sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1244,7 +1249,7 @@ s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, vm::ptr mask) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1267,7 +1272,7 @@ s32 sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1290,7 +1295,7 @@ s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ptr stat) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1308,7 +1313,7 @@ s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr value) { sys_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value=*0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1331,7 +1336,7 @@ s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value) sys_spu.Fatal("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value); } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1349,7 +1354,7 @@ s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr value) { sys_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value=*0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) {