sys_interrupt: weak_ptr -> shared_ptr

This commit is contained in:
Eladash 2021-05-14 17:55:07 +03:00 committed by Ivan
parent 33580e0aa1
commit c681395fb2
6 changed files with 20 additions and 14 deletions

View File

@ -1160,9 +1160,9 @@ void spu_int_ctrl_t::set(u64 ints)
{ {
std::shared_lock rlock(id_manager::g_mutex); std::shared_lock rlock(id_manager::g_mutex);
if (const auto tag_ptr = tag.lock()) if (tag && tag->exists)
{ {
if (auto handler = tag_ptr->handler.lock()) if (auto handler = tag->handler; handler && handler->exists)
{ {
rlock.unlock(); rlock.unlock();
handler->exec(); handler->exec();

View File

@ -474,7 +474,7 @@ struct spu_int_ctrl_t
atomic_t<u64> mask; atomic_t<u64> mask;
atomic_t<u64> stat; atomic_t<u64> stat;
std::weak_ptr<struct lv2_int_tag> tag; std::shared_ptr<struct lv2_int_tag> tag;
void set(u64 ints); void set(u64 ints);

View File

@ -12,6 +12,7 @@ LOG_CHANNEL(sys_interrupt);
lv2_int_tag::lv2_int_tag() noexcept lv2_int_tag::lv2_int_tag() noexcept
: id(idm::last_id()) : id(idm::last_id())
{ {
exists.release(1);
} }
lv2_int_serv::lv2_int_serv(const std::shared_ptr<named_thread<ppu_thread>>& thread, u64 arg1, u64 arg2) noexcept lv2_int_serv::lv2_int_serv(const std::shared_ptr<named_thread<ppu_thread>>& thread, u64 arg1, u64 arg2) noexcept
@ -20,6 +21,7 @@ lv2_int_serv::lv2_int_serv(const std::shared_ptr<named_thread<ppu_thread>>& thre
, arg1(arg1) , arg1(arg1)
, arg2(arg2) , arg2(arg2)
{ {
exists.release(1);
} }
void lv2_int_serv::exec() const void lv2_int_serv::exec() const
@ -61,11 +63,12 @@ error_code sys_interrupt_tag_destroy(ppu_thread& ppu, u32 intrtag)
const auto tag = idm::withdraw<lv2_obj, lv2_int_tag>(intrtag, [](lv2_int_tag& tag) -> CellError const auto tag = idm::withdraw<lv2_obj, lv2_int_tag>(intrtag, [](lv2_int_tag& tag) -> CellError
{ {
if (!tag.handler.expired()) if (tag.handler && tag.handler->exists)
{ {
return CELL_EBUSY; return CELL_EBUSY;
} }
tag.exists.release(0);
return {}; return {};
}); });
@ -120,7 +123,7 @@ error_code _sys_interrupt_thread_establish(ppu_thread& ppu, vm::ptr<u32> ih, u32
} }
// It's unclear if multiple handlers can be established on single interrupt tag // It's unclear if multiple handlers can be established on single interrupt tag
if (!tag->handler.expired()) if (tag->handler && tag->handler->exists)
{ {
error = CELL_ESTAT; error = CELL_ESTAT;
return result; return result;
@ -148,7 +151,10 @@ error_code _sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih, vm::ptr<u
sys_interrupt.warning("_sys_interrupt_thread_disestablish(ih=0x%x, r13=*0x%x)", ih, r13); sys_interrupt.warning("_sys_interrupt_thread_disestablish(ih=0x%x, r13=*0x%x)", ih, r13);
const auto handler = idm::withdraw<lv2_obj, lv2_int_serv>(ih); const auto handler = idm::withdraw<lv2_obj, lv2_int_serv>(ih, [](lv2_obj& obj)
{
obj.exists.release(0);
});
if (!handler) if (!handler)
{ {

View File

@ -11,7 +11,7 @@ struct lv2_int_tag final : lv2_obj
static const u32 id_base = 0x0a000000; static const u32 id_base = 0x0a000000;
const u32 id; const u32 id;
std::weak_ptr<struct lv2_int_serv> handler; std::shared_ptr<struct lv2_int_serv> handler;
lv2_int_tag() noexcept; lv2_int_tag() noexcept;
}; };

View File

@ -1938,17 +1938,17 @@ error_code raw_spu_destroy(ppu_thread& ppu, u32 id)
// Clear interrupt handlers // Clear interrupt handlers
for (auto& intr : thread->int_ctrl) for (auto& intr : thread->int_ctrl)
{ {
if (auto tag = intr.tag.lock()) if (auto& tag = intr.tag; tag && tag->exists)
{ {
if (auto handler = tag->handler.lock()) if (auto& handler = tag->handler; handler && handler->exists)
{ {
// SLEEP // SLEEP
lv2_obj::sleep(ppu); lv2_obj::sleep(ppu);
handler->join(); handler->join();
to_remove.emplace_back(std::move(handler), +handler->id); to_remove.emplace_back(handler, handler->id);
} }
to_remove.emplace_back(std::move(tag), +tag->id); to_remove.emplace_back(tag, tag->id);
} }
} }
@ -2023,7 +2023,7 @@ error_code raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 /*hwthread*/,
auto& int_ctrl = thread->int_ctrl[class_id]; auto& int_ctrl = thread->int_ctrl[class_id];
if (!int_ctrl.tag.expired()) if (int_ctrl.tag && int_ctrl.tag->exists)
{ {
error = CELL_EAGAIN; error = CELL_EAGAIN;
return result; return result;

View File

@ -350,9 +350,9 @@ void kernel_explorer::Update()
case SYS_INTR_TAG_OBJECT: case SYS_INTR_TAG_OBJECT:
{ {
auto& tag = static_cast<lv2_int_tag&>(obj); auto& tag = static_cast<lv2_int_tag&>(obj);
auto handler = tag.handler.lock(); const auto handler = tag.handler.get();
if (handler && handler.get() == idm::check_unlocked<lv2_obj, lv2_int_serv>(handler->id)) if (handler && handler->exists)
{ {
add_leaf(node, qstr(fmt::format("Intr Tag 0x%08x, Handler: 0x%08x", id, handler->id))); add_leaf(node, qstr(fmt::format("Intr Tag 0x%08x, Handler: 0x%08x", id, handler->id)));
break; break;