mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
Various changes
This commit is contained in:
parent
d1fbccc9ce
commit
ea5110cec3
@ -64,7 +64,7 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr<const void> pAr
|
||||
{
|
||||
sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock);
|
||||
|
||||
std::shared_ptr<CPUThread> 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<CPUThread> 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<s32> pExitStatus, vm::psv:
|
||||
{
|
||||
sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout);
|
||||
|
||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7);
|
||||
const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7);
|
||||
|
||||
if (!t)
|
||||
{
|
||||
|
@ -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<spu_group_t> group = tg.lock();
|
||||
std::shared_ptr<CPUThread> 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<SPUThread&>(*t);
|
||||
auto& spu = static_cast<SPUThread&>(*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<event_queue_t> 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<event_queue_t> 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<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<spu_group_t> group = tg.lock();
|
||||
const auto group = tg.lock();
|
||||
|
||||
if (!group)
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<CellAudioPortParam> audioParam, vm::ptr<u32> 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<std::mutex> 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
|
||||
{
|
||||
|
@ -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_t> level_set;
|
||||
};
|
||||
|
||||
struct AudioConfig //custom structure
|
||||
|
@ -319,8 +319,7 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> 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);
|
||||
|
||||
|
@ -579,7 +579,7 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> 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<atomic_t<u32>> lock)
|
||||
g_sys_spinlock_wm.notify(lock.addr());
|
||||
}
|
||||
|
||||
s32 sys_ppu_thread_create(PPUThread& CPU, vm::ptr<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> 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<ppu_thread_param_t> 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<u32>(*thread_id));
|
||||
}
|
||||
|
||||
s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<u64> 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<atomic_t<u32>> once_ctrl, vm::ptr<void()> init)
|
||||
{
|
||||
sysPrxForUser.Warning("sys_ppu_thread_once(once_ctrl=*0x%x, init=*0x%x)", once_ctrl, init);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_once_mutex);
|
||||
|
||||
if (once_ctrl->compare_and_swap_test(be_t<u32>::make(SYS_PPU_THREAD_ONCE_INIT), be_t<u32>::make(SYS_PPU_THREAD_DONE_INIT)))
|
||||
{
|
||||
// call init function using current thread context
|
||||
init(CPU);
|
||||
}
|
||||
}
|
||||
|
||||
Module sysPrxForUser("sysPrxForUser", []()
|
||||
{
|
||||
g_tls_start = 0;
|
||||
|
@ -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;
|
||||
|
@ -149,7 +149,7 @@ u32 sleep_queue_t::signal(u32 protocol)
|
||||
u64 sel = ~0ull;
|
||||
for (auto& v : m_waiting)
|
||||
{
|
||||
if (std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(v))
|
||||
if (const auto t = Emu.GetCPU().GetThread(v))
|
||||
{
|
||||
const u64 prio = t->GetPrio();
|
||||
if (prio < highest_prio)
|
||||
|
@ -19,9 +19,9 @@ s32 sys_cond_create(vm::ptr<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribu
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<mutex_t>(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_t> cond;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<cond_t>(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_t> cond;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<cond_t>(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_t> cond;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<cond_t>(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_t> cond;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<cond_t>(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_t> cond;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<cond_t>(cond_id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(cond_id, cond))
|
||||
if (!cond)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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;
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ struct cond_t
|
||||
|
||||
// TODO: use sleep queue, possibly remove condition variable
|
||||
std::condition_variable cv;
|
||||
std::atomic<u32> waiters;
|
||||
std::unordered_set<u32> waiters;
|
||||
|
||||
cond_t(std::shared_ptr<mutex_t>& mutex, u64 name)
|
||||
cond_t(const std::shared_ptr<mutex_t>& mutex, u64 name)
|
||||
: mutex(mutex)
|
||||
, name(name)
|
||||
, signaled(0)
|
||||
|
@ -67,9 +67,9 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<event_queue_t> queue;
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(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<sys_event_t> event_array,
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<event_queue_t> queue;
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(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<sys_event_t>
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<event_queue_t> queue;
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(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<event_queue_t> queue;
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(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<event_port_t> port;
|
||||
const auto port = Emu.GetIdManager().GetIDData<event_port_t>(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<event_port_t> port;
|
||||
std::shared_ptr<event_queue_t> queue;
|
||||
const auto port = Emu.GetIdManager().GetIDData<event_port_t>(eport_id);
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(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<event_port_t> port;
|
||||
const auto port = Emu.GetIdManager().GetIDData<event_port_t>(eport_id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(eport_id, port))
|
||||
if (!port)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<event_queue_t> 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<event_port_t> port;
|
||||
const auto port = Emu.GetIdManager().GetIDData<event_port_t>(eport_id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(eport_id, port))
|
||||
if (!port)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<event_queue_t> queue = port->queue.lock();
|
||||
const auto queue = port->queue.lock();
|
||||
|
||||
if (!queue)
|
||||
{
|
||||
|
@ -60,9 +60,9 @@ s32 sys_event_flag_destroy(u32 id)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<u64> result, u64 t
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<u64> result)
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<u32> num)
|
||||
*num = 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<u64> flags)
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
std::shared_ptr<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(id, ef))
|
||||
if (!ef)
|
||||
{
|
||||
*flags = 0;
|
||||
|
||||
|
@ -135,9 +135,9 @@ s32 sys_fs_read(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> 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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<const void> buf, u64 nbytes, vm::ptr<u64> 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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<CellFsDirent> dir, vm::ptr<u64> nread)
|
||||
{
|
||||
sys_fs.Warning("sys_fs_readdir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread);
|
||||
|
||||
std::shared_ptr<vfsDirBase> directory;
|
||||
const auto directory = Emu.GetIdManager().GetIDData<vfsDirBase>(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<vfsDirBase> directory;
|
||||
const auto directory = Emu.GetIdManager().GetIDData<vfsDirBase>(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<CellFsStat> sb)
|
||||
{
|
||||
sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb);
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<u64> pos)
|
||||
return CELL_FS_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<u64> sector_size, vm::ptr<u64> 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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
CELL_FS_EBADF;
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(file->mutex);
|
||||
|
||||
u64 initialSize = file->file->GetSize();
|
||||
|
||||
if (initialSize < size)
|
||||
|
@ -23,7 +23,7 @@ s32 sys_interrupt_tag_destroy(u32 intrtag)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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<u32> ih, u32 intrtag, u64 intrthread,
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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<u32> ih, u32 intrtag, u64 intrthread,
|
||||
|
||||
// CELL_ESTAT is not returned (can't detect exact condition)
|
||||
|
||||
std::shared_ptr<CPUThread> 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<u64> r13)
|
||||
{
|
||||
sys_interrupt.Todo("_sys_interrupt_thread_disestablish(ih=0x%x, r13=*0x%x)", ih, r13);
|
||||
|
||||
std::shared_ptr<interrupt_handler_t> handler;
|
||||
if (!Emu.GetIdManager().GetIDData(ih, handler))
|
||||
const auto handler = Emu.GetIdManager().GetIDData<interrupt_handler_t>(ih);
|
||||
|
||||
if (!handler)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
@ -37,14 +37,14 @@ s32 _sys_lwcond_destroy(u32 lwcond_id)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<lwcond_t> cond;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<lwcond_t>(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<lwcond_t> cond;
|
||||
std::shared_ptr<lwmutex_t> mutex;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<lwcond_t>(lwcond_id);
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<lwmutex_t>(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<lwcond_t> cond;
|
||||
std::shared_ptr<lwmutex_t> mutex;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<lwcond_t>(lwcond_id);
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<lwmutex_t>(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<lwcond_t> cond;
|
||||
std::shared_ptr<lwmutex_t> mutex;
|
||||
const auto cond = Emu.GetIdManager().GetIDData<lwcond_t>(lwcond_id);
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<lwmutex_t>(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)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ struct lwcond_t
|
||||
|
||||
// TODO: use sleep queue
|
||||
std::condition_variable cv;
|
||||
std::atomic<u32> waiters;
|
||||
std::unordered_set<u32> waiters;
|
||||
|
||||
lwcond_t(u64 name)
|
||||
: name(name)
|
||||
@ -47,4 +47,4 @@ s32 _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sys_lwcon
|
||||
s32 _sys_lwcond_destroy(u32 lwcond_id);
|
||||
s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mode);
|
||||
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);
|
||||
|
@ -52,9 +52,9 @@ s32 _sys_lwmutex_destroy(u32 lwmutex_id)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<lwmutex_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<lwmutex_t>(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<lwmutex_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<lwmutex_t>(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<lwmutex_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<lwmutex_t>(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<lwmutex_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<lwmutex_t>(lwmutex_id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex))
|
||||
if (!mutex)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
@ -54,9 +54,9 @@ s32 sys_mutex_destroy(u32 mutex_id)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<mutex_t>(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_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<mutex_t>(mutex_id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
if (!mutex)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<mutex_t>(mutex_id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
if (!mutex)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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_t> mutex;
|
||||
const auto mutex = Emu.GetIdManager().GetIDData<mutex_t>(mutex_id);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
|
||||
if (!mutex)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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;
|
||||
}
|
||||
|
@ -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<u64> vptr)
|
||||
s32 sys_ppu_thread_join(u32 thread_id, vm::ptr<u64> 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<CPUThread> 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<u64> 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<CPUThread> 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<s32> 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<CPUThread> 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<s32> 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<CPUThread> 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<CPUThread> thr = Emu.GetCPU().GetThread(thread_id);
|
||||
if (!thr)
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
thr->Stop();
|
||||
*priop = static_cast<s32>(t->GetPrio());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_ppu_thread_restart(u64 thread_id)
|
||||
s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr<sys_ppu_thread_stack_t> 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<CPUThread> 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<void(PPUThread&)> task)
|
||||
{
|
||||
auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
const auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
auto& ppu = static_cast<PPUThread&>(*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<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname)
|
||||
s32 _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> 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<PPUThread&>(*new_thread);
|
||||
|
||||
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<atomic_t<u32>> once_ctrl, vm::ptr<void()> 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<std::mutex> lock(g_once_mutex);
|
||||
ppu.GPR[3] = arg;
|
||||
ppu.GPR[4] = unk; // actually unknown
|
||||
|
||||
if (once_ctrl->compare_and_swap_test(be_t<u32>::make(SYS_PPU_THREAD_ONCE_INIT), be_t<u32>::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<u64> 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<const char> 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<CPUThread> 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<const char> 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<const char> name)
|
||||
}
|
||||
|
||||
t->SetThreadName(name.get_ptr());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -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<void(PPUThread&)> 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<u64> 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<u64> vptr);
|
||||
s32 sys_ppu_thread_detach(u32 thread_id);
|
||||
void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr<s32> 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<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname);
|
||||
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<atomic_t<u32>> once_ctrl, vm::ptr<void()> init);
|
||||
s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<u64> thread_id);
|
||||
s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr<const char> name);
|
||||
s32 sys_ppu_thread_set_priority(u32 thread_id, s32 prio);
|
||||
s32 sys_ppu_thread_get_priority(u32 thread_id, vm::ptr<s32> priop);
|
||||
s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr<sys_ppu_thread_stack_t> sp);
|
||||
s32 sys_ppu_thread_stop(u32 thread_id);
|
||||
s32 sys_ppu_thread_restart(u32 thread_id);
|
||||
s32 _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> param, u64 arg, u64 arg4, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname);
|
||||
s32 sys_ppu_thread_start(u32 thread_id);
|
||||
s32 sys_ppu_thread_rename(u32 thread_id, vm::ptr<const char> name);
|
||||
|
@ -99,7 +99,7 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr<sys_spu_image> 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<SPUThread&>(*t);
|
||||
|
||||
@ -108,8 +108,7 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr<sys_spu_image> img,
|
||||
spu.SetName(name);
|
||||
spu.m_custom_task = task;
|
||||
|
||||
std::shared_ptr<spu_group_t> group;
|
||||
Emu.GetIdManager().GetIDData(group_id, group);
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(group_id);
|
||||
|
||||
spu.tg = group;
|
||||
group->threads[spu_num] = t;
|
||||
@ -141,8 +140,9 @@ s32 sys_spu_thread_initialize(vm::ptr<u32> thread, u32 group_id, u32 spu_num, vm
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(group_id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(group_id);
|
||||
|
||||
if (!group)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -167,7 +167,8 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr<sys_spu_thread_argument> arg)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<CPUThread> 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<sys_spu_thread_argument> arg)
|
||||
|
||||
auto& spu = static_cast<SPUThread&>(*t);
|
||||
|
||||
std::shared_ptr<spu_group_t> 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<u32> status)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<CPUThread> 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<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(id);
|
||||
|
||||
if (!group)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -283,8 +285,9 @@ s32 sys_spu_thread_group_start(u32 id)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(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<event_queue_t> 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<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(id);
|
||||
|
||||
if (!group)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -402,8 +406,9 @@ s32 sys_spu_thread_group_resume(u32 id)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(id);
|
||||
|
||||
if (!group)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -448,15 +453,16 @@ s32 sys_spu_thread_group_yield(u32 id)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(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<spu_group_t>(id);
|
||||
|
||||
std::shared_ptr<spu_group_t> group;
|
||||
std::shared_ptr<CPUThread> 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<u32> cause, vm::ptr<u32> status)
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(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<CPUThread> 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<u64> 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<CPUThread> 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<CPUThread> 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<CPUThread> 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<u64> value)
|
||||
{
|
||||
sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
std::shared_ptr<CPUThread> 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<CPUThread> 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<spu_group_t> group;
|
||||
std::shared_ptr<event_queue_t> queue;
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(id);
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(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<spu_group_t> group;
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(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<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||
const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(eq);
|
||||
|
||||
std::shared_ptr<event_queue_t> 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<CPUThread> 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<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||
const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(spuq);
|
||||
|
||||
std::shared_ptr<event_queue_t> 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<CPUThread> 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<spu_group_t> group;
|
||||
std::shared_ptr<event_queue_t> queue;
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(id);
|
||||
const auto queue = Emu.GetIdManager().GetIDData<event_queue_t>(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<spu_group_t> group;
|
||||
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||
const auto group = Emu.GetIdManager().GetIDData<spu_group_t>(id);
|
||||
|
||||
if (!group)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -1142,7 +1147,7 @@ s32 sys_raw_spu_create(vm::ptr<u32> id, vm::ptr<void> 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<CPUThread> 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<CPUThread> 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<CPUThread> 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<u64> mask)
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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<CPUThread> 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<u64> stat)
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> 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<u32> value)
|
||||
{
|
||||
sys_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
std::shared_ptr<CPUThread> 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<CPUThread> 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<u32> value)
|
||||
{
|
||||
sys_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
const auto t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
|
||||
if (!t)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user