mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
sys_ppu_thread: fixing detached threads
This commit is contained in:
parent
752c4a7b0d
commit
6ee9153329
1 changed files with 36 additions and 18 deletions
|
@ -11,6 +11,26 @@
|
|||
|
||||
LOG_CHANNEL(sys_ppu_thread);
|
||||
|
||||
// Simple structure to cleanup previous thread, because can't remove its own thread
|
||||
struct ppu_thread_cleaner
|
||||
{
|
||||
atomic_t<u32> old_id = 0;
|
||||
|
||||
void clean(u32 new_id)
|
||||
{
|
||||
if (old_id) [[likely]]
|
||||
{
|
||||
if (u32 id = old_id.exchange(new_id)) [[likely]]
|
||||
{
|
||||
if (!idm::remove<named_thread<ppu_thread>>(old_id)) [[unlikely]]
|
||||
{
|
||||
sys_ppu_thread.fatal("Failed to remove detached thread 0x%x", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
@ -41,24 +61,7 @@ void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
|
|||
|
||||
if (jid == umax)
|
||||
{
|
||||
// Simple structure to cleanup previous thread, because can't remove its own thread
|
||||
struct ppu_thread_cleaner
|
||||
{
|
||||
atomic_t<u32> id = 0;
|
||||
};
|
||||
|
||||
auto cleaner = g_fxo->get<ppu_thread_cleaner>();
|
||||
|
||||
if (cleaner->id || !cleaner->id.compare_and_swap_test(0, ppu.id)) [[likely]]
|
||||
{
|
||||
if (u32 old_id = cleaner->id.exchange(ppu.id))
|
||||
{
|
||||
if (!idm::remove<named_thread<ppu_thread>>(old_id))
|
||||
{
|
||||
sys_ppu_thread.fatal("Failed to remove detached thread 0x%x", old_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_fxo->get<ppu_thread_cleaner>()->clean(ppu.id);
|
||||
}
|
||||
else if (jid != 0)
|
||||
{
|
||||
|
@ -88,6 +91,9 @@ error_code sys_ppu_thread_join(ppu_thread& ppu, u32 thread_id, vm::ptr<u64> vptr
|
|||
|
||||
sys_ppu_thread.trace("sys_ppu_thread_join(thread_id=0x%x, vptr=*0x%x)", thread_id, vptr);
|
||||
|
||||
// Clean some detached thread (hack)
|
||||
g_fxo->get<ppu_thread_cleaner>()->clean(0);
|
||||
|
||||
const auto thread = idm::get<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread) -> CellError
|
||||
{
|
||||
CellError result = thread.joiner.atomic_op([&](u32& value) -> CellError
|
||||
|
@ -161,6 +167,9 @@ error_code sys_ppu_thread_detach(u32 thread_id)
|
|||
{
|
||||
sys_ppu_thread.trace("sys_ppu_thread_detach(thread_id=0x%x)", thread_id);
|
||||
|
||||
// Clean some detached thread (hack)
|
||||
g_fxo->get<ppu_thread_cleaner>()->clean(0);
|
||||
|
||||
const auto thread = idm::check<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread) -> CellError
|
||||
{
|
||||
return thread.joiner.atomic_op([&](u32& value) -> CellError
|
||||
|
@ -231,6 +240,9 @@ error_code sys_ppu_thread_set_priority(ppu_thread& ppu, u32 thread_id, s32 prio)
|
|||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
// Clean some detached thread (hack)
|
||||
g_fxo->get<ppu_thread_cleaner>()->clean(0);
|
||||
|
||||
const auto thread = idm::check<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread)
|
||||
{
|
||||
if (thread.prio != prio)
|
||||
|
@ -251,6 +263,9 @@ error_code sys_ppu_thread_get_priority(u32 thread_id, vm::ptr<s32> priop)
|
|||
{
|
||||
sys_ppu_thread.trace("sys_ppu_thread_get_priority(thread_id=0x%x, priop=*0x%x)", thread_id, priop);
|
||||
|
||||
// Clean some detached thread (hack)
|
||||
g_fxo->get<ppu_thread_cleaner>()->clean(0);
|
||||
|
||||
const auto thread = idm::check<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread)
|
||||
{
|
||||
*priop = thread.prio;
|
||||
|
@ -325,6 +340,9 @@ error_code _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_par
|
|||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
// Clean some detached thread (hack)
|
||||
g_fxo->get<ppu_thread_cleaner>()->clean(0);
|
||||
|
||||
// Compute actual stack size and allocate
|
||||
const u32 stack_size = ::align<u32>(std::max<u32>(_stacksz, 4096), 4096);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue