Skip to content

Commit

Permalink
Remove SPU and PPU destructors
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Jan 20, 2021
1 parent dbecf0f commit 4f9f67e
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 46 deletions.
13 changes: 0 additions & 13 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,19 +912,6 @@ void ppu_thread::exec_task()
}
}

ppu_thread::~ppu_thread()
{
// Deallocate Stack Area
ensure(vm::dealloc(stack_addr, vm::stack));

if (const auto dct = g_fxo->get<lv2_memory_container>())
{
dct->used -= stack_size;
}

perf_log.notice("Perf stats for STCX reload: successs %u, failure %u", last_succ, last_fail);
}

ppu_thread::ppu_thread(const ppu_thread_params& param, std::string_view name, u32 prio, int detached)
: cpu_thread(idm::last_id())
, prio(prio)
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/PPUThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class ppu_thread : public cpu_thread
virtual std::string dump_misc() const override;
virtual void cpu_task() override final;
virtual void cpu_sleep() override;
virtual ~ppu_thread() override;
virtual ~ppu_thread() {};

ppu_thread(const ppu_thread_params&, std::string_view name, u32 prio, int detached = 0);

Expand Down
38 changes: 20 additions & 18 deletions rpcs3/Emu/Cell/SPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1675,26 +1675,12 @@ void spu_thread::cpu_task()
}
}

spu_thread::~spu_thread()
void spu_thread::cleanup()
{
{
vm::writer_lock(0);

for (s32 i = -1; i < 2; i++)
{
// Unmap LS mirrors
shm->unmap_critical(ls + (i * SPU_LS_SIZE));
}
}
const u32 addr = group ? SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (id & 0xffffff) : RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index;

if (!group)
{
// Deallocate local storage (thread groups are handled in sys_spu.cpp)
ensure(vm::dealloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, vm::spu));
}

// Release LS mirrors area
utils::memory_release(ls - (SPU_LS_SIZE * 2), SPU_LS_SIZE * 5);
// Deallocate local storage
ensure(vm::dealloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, vm::spu, &shm) == SPU_LS_SIZE);

// Deallocate RawSPU ID
if (get_type() >= spu_type::raw)
Expand All @@ -1710,6 +1696,22 @@ spu_thread::~spu_thread()
perf_log.notice("Perf stats for PUTLLC reload: successs %u, failure %u", last_succ, last_fail);
}

void spu_thread::cleanup()
{
{
vm::writer_lock lock(0);

for (s32 i = -1; i < 2; i++)
{
// Unmap LS mirrors
shm->unmap_critical(ls + (i * SPU_LS_SIZE));
}
}

// Release LS mirrors area
utils::memory_release(ls - (SPU_LS_SIZE * 2), SPU_LS_SIZE * 5);
}

spu_thread::spu_thread(lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated, u32 option)
: cpu_thread(idm::last_id())
, index(index)
Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/Cell/SPUThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ class spu_thread : public cpu_thread
virtual void cpu_task() override final;
virtual void cpu_return() override;
virtual ~spu_thread() override;
void cleanup();
void cpu_init();

static const u32 id_base = 0x02000000; // TODO (used to determine thread type)
Expand Down
8 changes: 2 additions & 6 deletions rpcs3/Emu/Cell/lv2/sys_interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,14 @@ void lv2_int_serv::exec()
thread_ctrl::notify(*thread);
}

bool interrupt_thread_exit(ppu_thread& ppu)
{
ppu.state += cpu_flag::exit;
return false;
}
bool ppu_thread_exit(ppu_thread& ppu);

void lv2_int_serv::join()
{
thread->cmd_list
({
{ ppu_cmd::ptr_call, 0 },
std::bit_cast<u64>(&interrupt_thread_exit)
std::bit_cast<u64>(&ppu_thread_exit)
});

thread_ctrl::notify(*thread);
Expand Down
46 changes: 40 additions & 6 deletions rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "sys_ppu_thread.h"

#include "Emu/IdManager.h"
#include "Emu/perf_meter.hpp"

#include "Emu/Cell/ErrorCodes.h"
#include "Emu/Cell/PPUThread.h"
Expand Down Expand Up @@ -36,6 +37,22 @@ struct ppu_thread_cleaner
}
};

bool ppu_thread_exit(ppu_thread& ppu)
{
ppu.state += cpu_flag::exit + cpu_flag::wait;

// Deallocate Stack Area
ensure(vm::dealloc(ppu.stack_addr, vm::stack) == ppu.stack_size);

if (const auto dct = g_fxo->get<lv2_memory_container>())
{
dct->used -= ppu.stack_size;
}

perf_log.notice("Perf stats for STCX reload: successs %u, failure %u", ppu.last_succ, ppu.last_fail);
return false;
}

void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
{
ppu.state += cpu_flag::wait;
Expand Down Expand Up @@ -77,10 +94,15 @@ void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
ppu.state -= cpu_flag::suspend;
}

if (old_status == ppu_join_status::detached)
g_fxo->get<ppu_thread_cleaner>()->clean(old_status == ppu_join_status::detached ? ppu.id : 0);

if (old_status == ppu_join_status::joinable)
{
g_fxo->get<ppu_thread_cleaner>()->clean(ppu.id);
// Wait for termination
ppu.joiner.wait(ppu_join_status::zombie);
}

ppu_thread_exit(ppu);
}

s32 sys_ppu_thread_yield(ppu_thread& ppu)
Expand Down Expand Up @@ -114,7 +136,7 @@ error_code sys_ppu_thread_join(ppu_thread& ppu, u32 thread_id, vm::ptr<u64> vptr
if (value == ppu_join_status::zombie)
{
value = ppu_join_status::exited;
return CELL_EBUSY;
return CELL_EAGAIN;
}

if (value == ppu_join_status::exited)
Expand All @@ -135,6 +157,10 @@ error_code sys_ppu_thread_join(ppu_thread& ppu, u32 thread_id, vm::ptr<u64> vptr
{
lv2_obj::sleep(ppu);
}
else if (result == CELL_EAGAIN)
{
thread.joiner.notify_one();
}

return result;
});
Expand All @@ -144,7 +170,7 @@ error_code sys_ppu_thread_join(ppu_thread& ppu, u32 thread_id, vm::ptr<u64> vptr
return CELL_ESRCH;
}

if (thread.ret && thread.ret != CELL_EBUSY)
if (thread.ret && thread.ret != CELL_EAGAIN)
{
return thread.ret;
}
Expand Down Expand Up @@ -183,7 +209,7 @@ error_code sys_ppu_thread_detach(ppu_thread& ppu, u32 thread_id)

const auto thread = idm::check<named_thread<ppu_thread>>(thread_id, [&](ppu_thread& thread) -> CellError
{
return thread.joiner.atomic_op([](ppu_join_status& value) -> CellError
CellError result = thread.joiner.atomic_op([](ppu_join_status& value) -> CellError
{
if (value == ppu_join_status::zombie)
{
Expand All @@ -209,6 +235,13 @@ error_code sys_ppu_thread_detach(ppu_thread& ppu, u32 thread_id)
value = ppu_join_status::detached;
return {};
});

if (result == CELL_EAGAIN)
{
thread.joiner.notify_one();
}

return result;
});

if (!thread)
Expand All @@ -223,7 +256,8 @@ error_code sys_ppu_thread_detach(ppu_thread& ppu, u32 thread_id)

if (thread.ret == CELL_EAGAIN)
{
ensure(idm::remove<named_thread<ppu_thread>>(thread_id));
g_fxo->get<ppu_thread_cleaner>()->clean(thread_id);
g_fxo->get<ppu_thread_cleaner>()->clean(0);
}

return CELL_OK;
Expand Down
13 changes: 11 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_spu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ error_code sys_spu_thread_group_destroy(ppu_thread& ppu, u32 id)
if (auto thread = t.get())
{
// Deallocate LS
ensure(vm::get(vm::spu)->dealloc(SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (thread->id & 0xffffff), &thread->shm));
thread->cleanup();

// Remove ID from IDM (destruction will occur in group destructor)
idm::remove<named_thread<spu_thread>>(thread->id);
Expand Down Expand Up @@ -1989,7 +1989,16 @@ error_code raw_spu_destroy(ppu_thread& ppu, u32 id)

(*thread)();

if (!idm::remove_verify<named_thread<spu_thread>>(idm_id, std::move(thread.ptr)))
if (idm::withdraw<named_thread<spu_thread>>(idm_id, [&](spu_thread& spu)
{
if (std::addressof(spu) != std::addressof(*thread))
{
return CELL_ESRCH;
}

spu.cleanup();
return CELL_OK;
}).second)
{
// Other thread destroyed beforehead
return CELL_ESRCH;
Expand Down

0 comments on commit 4f9f67e

Please sign in to comment.