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);
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();
handler->exec();

View File

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

View File

@ -12,6 +12,7 @@ LOG_CHANNEL(sys_interrupt);
lv2_int_tag::lv2_int_tag() noexcept
: 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
@ -20,6 +21,7 @@ lv2_int_serv::lv2_int_serv(const std::shared_ptr<named_thread<ppu_thread>>& thre
, arg1(arg1)
, arg2(arg2)
{
exists.release(1);
}
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
{
if (!tag.handler.expired())
if (tag.handler && tag.handler->exists)
{
return CELL_EBUSY;
}
tag.exists.release(0);
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
if (!tag->handler.expired())
if (tag->handler && tag->handler->exists)
{
error = CELL_ESTAT;
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);
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)
{

View File

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

View File

@ -1938,17 +1938,17 @@ error_code raw_spu_destroy(ppu_thread& ppu, u32 id)
// Clear interrupt handlers
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
lv2_obj::sleep(ppu);
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];
if (!int_ctrl.tag.expired())
if (int_ctrl.tag && int_ctrl.tag->exists)
{
error = CELL_EAGAIN;
return result;

View File

@ -350,9 +350,9 @@ void kernel_explorer::Update()
case SYS_INTR_TAG_OBJECT:
{
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)));
break;