mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-11 02:29:29 +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);
|
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)
|
void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
|
||||||
{
|
{
|
||||||
vm::temporary_unlock(ppu);
|
vm::temporary_unlock(ppu);
|
||||||
|
@ -41,24 +61,7 @@ void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
|
||||||
|
|
||||||
if (jid == umax)
|
if (jid == umax)
|
||||||
{
|
{
|
||||||
// Simple structure to cleanup previous thread, because can't remove its own thread
|
g_fxo->get<ppu_thread_cleaner>()->clean(ppu.id);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (jid != 0)
|
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);
|
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
|
const auto thread = idm::get<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread) -> CellError
|
||||||
{
|
{
|
||||||
CellError result = thread.joiner.atomic_op([&](u32& value) -> 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);
|
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
|
const auto thread = idm::check<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread) -> CellError
|
||||||
{
|
{
|
||||||
return thread.joiner.atomic_op([&](u32& value) -> 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;
|
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)
|
const auto thread = idm::check<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread)
|
||||||
{
|
{
|
||||||
if (thread.prio != prio)
|
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);
|
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)
|
const auto thread = idm::check<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread)
|
||||||
{
|
{
|
||||||
*priop = thread.prio;
|
*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;
|
return CELL_EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean some detached thread (hack)
|
||||||
|
g_fxo->get<ppu_thread_cleaner>()->clean(0);
|
||||||
|
|
||||||
// Compute actual stack size and allocate
|
// Compute actual stack size and allocate
|
||||||
const u32 stack_size = ::align<u32>(std::max<u32>(_stacksz, 4096), 4096);
|
const u32 stack_size = ::align<u32>(std::max<u32>(_stacksz, 4096), 4096);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue