Various changes

This commit is contained in:
Nekotekina 2015-04-12 04:36:25 +03:00
parent d1fbccc9ce
commit ea5110cec3
23 changed files with 483 additions and 403 deletions

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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
}
}
});

View File

@ -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);
}

View File

@ -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
{

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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)

View File

@ -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)
{

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{