mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
Remove SPU and PPU destructors
This commit is contained in:
parent
eb086b0e3f
commit
f81674232e
@ -914,15 +914,6 @@ void ppu_thread::exec_task()
|
|||||||
|
|
||||||
ppu_thread::~ppu_thread()
|
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)
|
ppu_thread::ppu_thread(const ppu_thread_params& param, std::string_view name, u32 prio, int detached)
|
||||||
|
@ -1675,26 +1675,12 @@ void spu_thread::cpu_task()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spu_thread::~spu_thread()
|
void spu_thread::cleanup()
|
||||||
{
|
{
|
||||||
{
|
const u32 addr = group ? SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (id & 0xffffff) : RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index;
|
||||||
vm::writer_lock(0);
|
|
||||||
|
|
||||||
for (s32 i = -1; i < 2; i++)
|
// Deallocate local storage
|
||||||
{
|
ensure(vm::dealloc(addr, vm::spu, &shm));
|
||||||
// Unmap LS mirrors
|
|
||||||
shm->unmap_critical(ls + (i * SPU_LS_SIZE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 RawSPU ID
|
// Deallocate RawSPU ID
|
||||||
if (get_type() >= spu_type::raw)
|
if (get_type() >= spu_type::raw)
|
||||||
@ -1710,14 +1696,28 @@ spu_thread::~spu_thread()
|
|||||||
perf_log.notice("Perf stats for PUTLLC reload: successs %u, failure %u", last_succ, last_fail);
|
perf_log.notice("Perf stats for PUTLLC reload: successs %u, failure %u", last_succ, last_fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spu_thread::~spu_thread()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
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)
|
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())
|
: cpu_thread(idm::last_id())
|
||||||
, index(index)
|
, index(index)
|
||||||
, shm(std::make_shared<utils::shm>(SPU_LS_SIZE))
|
, shm(std::make_shared<utils::shm>(SPU_LS_SIZE))
|
||||||
, ls([&]()
|
, ls([&]()
|
||||||
{
|
{
|
||||||
const auto addr = static_cast<u8*>(utils::memory_reserve(SPU_LS_SIZE * 5));
|
|
||||||
|
|
||||||
if (!group)
|
if (!group)
|
||||||
{
|
{
|
||||||
ensure(vm::get(vm::spu)->falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, SPU_LS_SIZE, &shm));
|
ensure(vm::get(vm::spu)->falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, SPU_LS_SIZE, &shm));
|
||||||
@ -1728,7 +1728,9 @@ spu_thread::spu_thread(lv2_spu_group* group, u32 index, std::string_view name, u
|
|||||||
ensure(vm::get(vm::spu)->falloc(SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (cpu_thread::id & 0xffffff), SPU_LS_SIZE, &shm, 0x1000));
|
ensure(vm::get(vm::spu)->falloc(SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (cpu_thread::id & 0xffffff), SPU_LS_SIZE, &shm, 0x1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
vm::writer_lock(0);
|
vm::writer_lock lock(0);
|
||||||
|
|
||||||
|
const auto addr = static_cast<u8*>(utils::memory_reserve(SPU_LS_SIZE * 5));
|
||||||
|
|
||||||
for (u32 i = 1; i < 4; i++)
|
for (u32 i = 1; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
@ -634,6 +634,7 @@ public:
|
|||||||
virtual void cpu_task() override final;
|
virtual void cpu_task() override final;
|
||||||
virtual void cpu_return() override;
|
virtual void cpu_return() override;
|
||||||
virtual ~spu_thread() override;
|
virtual ~spu_thread() override;
|
||||||
|
void cleanup();
|
||||||
void cpu_init();
|
void cpu_init();
|
||||||
|
|
||||||
static const u32 id_base = 0x02000000; // TODO (used to determine thread type)
|
static const u32 id_base = 0x02000000; // TODO (used to determine thread type)
|
||||||
|
@ -22,18 +22,14 @@ void lv2_int_serv::exec()
|
|||||||
thread_ctrl::notify(*thread);
|
thread_ctrl::notify(*thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool interrupt_thread_exit(ppu_thread& ppu)
|
bool ppu_thread_exit(ppu_thread& ppu);
|
||||||
{
|
|
||||||
ppu.state += cpu_flag::exit;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv2_int_serv::join()
|
void lv2_int_serv::join()
|
||||||
{
|
{
|
||||||
thread->cmd_list
|
thread->cmd_list
|
||||||
({
|
({
|
||||||
{ ppu_cmd::ptr_call, 0 },
|
{ ppu_cmd::ptr_call, 0 },
|
||||||
std::bit_cast<u64>(&interrupt_thread_exit)
|
std::bit_cast<u64>(&ppu_thread_exit)
|
||||||
});
|
});
|
||||||
|
|
||||||
thread_ctrl::notify(*thread);
|
thread_ctrl::notify(*thread);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "sys_ppu_thread.h"
|
#include "sys_ppu_thread.h"
|
||||||
|
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
|
#include "Emu/perf_meter.hpp"
|
||||||
|
|
||||||
#include "Emu/Cell/ErrorCodes.h"
|
#include "Emu/Cell/ErrorCodes.h"
|
||||||
#include "Emu/Cell/PPUThread.h"
|
#include "Emu/Cell/PPUThread.h"
|
||||||
@ -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)
|
void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
|
||||||
{
|
{
|
||||||
ppu.state += cpu_flag::wait;
|
ppu.state += cpu_flag::wait;
|
||||||
@ -77,10 +94,15 @@ void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode)
|
|||||||
ppu.state -= cpu_flag::suspend;
|
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)
|
s32 sys_ppu_thread_yield(ppu_thread& ppu)
|
||||||
@ -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)
|
if (value == ppu_join_status::zombie)
|
||||||
{
|
{
|
||||||
value = ppu_join_status::exited;
|
value = ppu_join_status::exited;
|
||||||
return CELL_EBUSY;
|
return CELL_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == ppu_join_status::exited)
|
if (value == ppu_join_status::exited)
|
||||||
@ -135,6 +157,10 @@ error_code sys_ppu_thread_join(ppu_thread& ppu, u32 thread_id, vm::ptr<u64> vptr
|
|||||||
{
|
{
|
||||||
lv2_obj::sleep(ppu);
|
lv2_obj::sleep(ppu);
|
||||||
}
|
}
|
||||||
|
else if (result == CELL_EAGAIN)
|
||||||
|
{
|
||||||
|
thread.joiner.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@ -144,7 +170,7 @@ error_code sys_ppu_thread_join(ppu_thread& ppu, u32 thread_id, vm::ptr<u64> vptr
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread.ret && thread.ret != CELL_EBUSY)
|
if (thread.ret && thread.ret != CELL_EAGAIN)
|
||||||
{
|
{
|
||||||
return thread.ret;
|
return thread.ret;
|
||||||
}
|
}
|
||||||
@ -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
|
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)
|
if (value == ppu_join_status::zombie)
|
||||||
{
|
{
|
||||||
@ -209,6 +235,13 @@ error_code sys_ppu_thread_detach(ppu_thread& ppu, u32 thread_id)
|
|||||||
value = ppu_join_status::detached;
|
value = ppu_join_status::detached;
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (result == CELL_EAGAIN)
|
||||||
|
{
|
||||||
|
thread.joiner.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!thread)
|
if (!thread)
|
||||||
@ -223,7 +256,8 @@ error_code sys_ppu_thread_detach(ppu_thread& ppu, u32 thread_id)
|
|||||||
|
|
||||||
if (thread.ret == CELL_EAGAIN)
|
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;
|
return CELL_OK;
|
||||||
|
@ -687,7 +687,7 @@ error_code sys_spu_thread_group_destroy(ppu_thread& ppu, u32 id)
|
|||||||
if (auto thread = t.get())
|
if (auto thread = t.get())
|
||||||
{
|
{
|
||||||
// Deallocate LS
|
// 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)
|
// Remove ID from IDM (destruction will occur in group destructor)
|
||||||
idm::remove<named_thread<spu_thread>>(thread->id);
|
idm::remove<named_thread<spu_thread>>(thread->id);
|
||||||
@ -1989,7 +1989,16 @@ error_code raw_spu_destroy(ppu_thread& ppu, u32 id)
|
|||||||
|
|
||||||
(*thread)();
|
(*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) -> CellError
|
||||||
|
{
|
||||||
|
if (std::addressof(spu) != std::addressof(*thread))
|
||||||
|
{
|
||||||
|
return CELL_ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
spu.cleanup();
|
||||||
|
return {};
|
||||||
|
}).ret)
|
||||||
{
|
{
|
||||||
// Other thread destroyed beforehead
|
// Other thread destroyed beforehead
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
|
Loading…
Reference in New Issue
Block a user