Allow sys_raw_spu_create_tag to be called more than once

This commit is contained in:
Eladash 2019-12-21 08:16:47 +02:00 committed by Ivan
parent 923cd7ad72
commit 45cff1219c
3 changed files with 9 additions and 9 deletions

View file

@ -936,13 +936,13 @@ void spu_int_ctrl_t::set(u64 ints)
ints &= mask; ints &= mask;
// notify if at least 1 bit was set // notify if at least 1 bit was set
if (ints && ~stat.fetch_or(ints) & ints && tag) if (ints && ~stat.fetch_or(ints) & ints && !tag.expired())
{ {
reader_lock rlock(id_manager::g_mutex); reader_lock rlock(id_manager::g_mutex);
if (tag) if (const auto tag_ptr = tag.lock())
{ {
if (auto handler = tag->handler.lock()) if (auto handler = tag_ptr->handler.lock())
{ {
handler->exec(); handler->exec();
} }

View file

@ -353,7 +353,7 @@ struct spu_int_ctrl_t
atomic_t<u64> mask; atomic_t<u64> mask;
atomic_t<u64> stat; atomic_t<u64> stat;
std::shared_ptr<struct lv2_int_tag> tag; std::weak_ptr<struct lv2_int_tag> tag;
void set(u64 ints); void set(u64 ints);
@ -366,7 +366,7 @@ struct spu_int_ctrl_t
{ {
mask.release(0); mask.release(0);
stat.release(0); stat.release(0);
tag = nullptr; tag.reset();
} }
}; };

View file

@ -1473,16 +1473,16 @@ error_code sys_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 (intr.tag) if (const auto tag = intr.tag.lock())
{ {
if (auto handler = intr.tag->handler.lock()) if (auto handler = tag->handler.lock())
{ {
// SLEEP // SLEEP
handler->join(); handler->join();
to_remove.emplace(handler.get(), 0); to_remove.emplace(handler.get(), 0);
} }
to_remove.emplace(intr.tag.get(), 0); to_remove.emplace(tag.get(), 0);
} }
} }
@ -1537,7 +1537,7 @@ error_code sys_raw_spu_create_interrupt_tag(ppu_thread& ppu, u32 id, u32 class_i
auto& int_ctrl = thread->int_ctrl[class_id]; auto& int_ctrl = thread->int_ctrl[class_id];
if (int_ctrl.tag) if (!int_ctrl.tag.expired())
{ {
error = CELL_EAGAIN; error = CELL_EAGAIN;
return result; return result;