Skip to content

Commit

Permalink
Threads: Fix tasks queue after thread aborted
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Sep 9, 2021
1 parent df080fb commit cd7bab9
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 14 deletions.
11 changes: 10 additions & 1 deletion Utilities/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2061,6 +2061,8 @@ u64 thread_base::finalize(thread_state result_state) noexcept
// Signal waiting threads
m_sync.notify_all(2);

thread_base::exec();

return _self;
}

Expand Down Expand Up @@ -2440,6 +2442,11 @@ void thread_base::push(shared_ptr<thread_future> task)
const auto next = &task->next;
m_taskq.push_head(*next, std::move(task));
m_taskq.notify_one();

if (m_sync & 2)
{
exec();
}
}

void thread_base::exec()
Expand Down Expand Up @@ -2473,7 +2480,9 @@ void thread_base::exec()

for (auto ptr = prev->get(); ptr; ptr = ptr->prev->get())
{
if (auto task = ptr->exec.load()) [[likely]]
static constexpr auto null_func = +[](thread_base*, thread_future*){};

if (auto task = ptr->exec.exchange(null_func)) [[likely]]
{
// Execute or discard (if aborting)
if ((m_sync & 3) == 0) [[likely]]
Expand Down
3 changes: 0 additions & 3 deletions rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,6 @@ namespace rsx
}
}
}

thread_bits &= ~tbit;
thread_bits.notify_all();
});
}
}
Expand Down
3 changes: 0 additions & 3 deletions rpcs3/Emu/RSX/Overlays/overlay_osk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1042,9 +1042,6 @@ namespace rsx
{
rsx_log.error("Osk input loop exited with error code=%d", error);
}

thread_bits &= ~tbit;
thread_bits.notify_all();
});
}
}
Expand Down
3 changes: 0 additions & 3 deletions rpcs3/Emu/RSX/Overlays/overlay_user_list_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,6 @@ namespace rsx
{
rsx_log.error("Dialog input loop exited with error code=%d", error);
}

thread_bits &= ~tbit;
thread_bits.notify_all();
});

return CELL_OK;
Expand Down
7 changes: 4 additions & 3 deletions rpcs3/Emu/RSX/Overlays/overlays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ namespace rsx
{
thread_local DECLARE(user_interface::g_thread_bit) = 0;

u64 user_interface::alloc_thread_bit()
thread_bit_t user_interface::alloc_thread_bit()
{
const u64 old_bit = g_thread_bit;
auto [_old, ok] = this->thread_bits.fetch_op([](u64& bits)
{
if (~bits)
Expand All @@ -30,12 +31,12 @@ namespace rsx
if (!ok)
{
::overlays.fatal("Out of thread bits in user interface");
return 0;
return thread_bit_t(this->thread_bits, 0, old_bit);
}

const u64 r = u64{1} << std::countr_one(_old);
::overlays.trace("Bit allocated (%u)", r);
return r;
return thread_bit_t(this->thread_bits, r, old_bit);
}

// Singleton instance declaration
Expand Down
40 changes: 39 additions & 1 deletion rpcs3/Emu/RSX/Overlays/overlays.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,45 @@ namespace rsx

static thread_local u64 g_thread_bit;

u64 alloc_thread_bit();
struct thread_bit_t
{
atomic_t<u64>& bits;
u64 tbit = 0;
u64 old_bit = 0;

thread_bit_t(atomic_t<u64>& _bits, u64 _bit, u64 _old)
: bits(_bits)
, tbit(_bit)
, old_bit(_old)
{
}

thread_bit_t(const thread_bit_t&) = delete;

thread_bit_t(thread_bit_t&& t)
: bits(t.bits)
, tbit(std::exchange(t.tbit, 0))
, old_bit(t.old_bit)
{
}

~thread_bit_t()
{
if (tbit)
{
bits &= ~tbit;
bits.notify_all();
g_thread_bit = old_bit;
}
}

operator u64() const
{
return tbit;
}
};

thread_bit_t alloc_thread_bit();

std::function<void(s32 status)> on_close;

Expand Down

0 comments on commit cd7bab9

Please sign in to comment.