diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index baf57bf705..542ed346c8 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -467,13 +467,43 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) LV2_LOCK; + // seems the id can be either SPU Thread Group or SPU Thread + std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + std::shared_ptr thread = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + + if (!Emu.GetIdManager().GetIDData(id, group) && !thread) { return CELL_ESRCH; } - // CELL_EPERM is not returned (can't check the condition) + auto& spu = static_cast(*thread); + + if (thread) + { + if (group) + { + throw __FUNCTION__; + } + + group = spu.tg.lock(); + + for (auto& t : group->threads) + { + // find primary (?) thread and compare it with the one specified + if (t) + { + if (t == thread) + { + break; + } + else + { + return CELL_EPERM; + } + } + } + } if (group->state <= SPU_THREAD_GROUP_STATUS_INITIALIZED || group->state == SPU_THREAD_GROUP_STATUS_WAITING || group->state == SPU_THREAD_GROUP_STATUS_WAITING) { @@ -495,6 +525,7 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) group->exit_status = value; group->join_state |= SPU_TGJSF_TERMINATED; group->join_cv.notify_one(); + return CELL_OK; }