mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 05:51:27 +12:00
overlays: add "thread bits" to wait on and avoid lockup
Add TLS variable to store its own bit.
This commit is contained in:
parent
d0b2eecc9a
commit
ecd68dfc70
4 changed files with 48 additions and 20 deletions
|
@ -242,10 +242,10 @@ namespace rsx
|
||||||
{
|
{
|
||||||
if (!exit)
|
if (!exit)
|
||||||
{
|
{
|
||||||
thread_count++;
|
g_fxo->init<named_thread>("MsgDialog Thread", [&, tbit = alloc_thread_bit()]()
|
||||||
|
|
||||||
g_fxo->init<named_thread>("MsgDialog Thread", [&]()
|
|
||||||
{
|
{
|
||||||
|
g_thread_bit = tbit;
|
||||||
|
|
||||||
if (interactive)
|
if (interactive)
|
||||||
{
|
{
|
||||||
auto ref = g_fxo->get<display_manager>()->get(uid);
|
auto ref = g_fxo->get<display_manager>()->get(uid);
|
||||||
|
@ -267,15 +267,13 @@ namespace rsx
|
||||||
if (!g_fxo->get<display_manager>())
|
if (!g_fxo->get<display_manager>())
|
||||||
{
|
{
|
||||||
rsx_log.fatal("display_manager was improperly destroyed");
|
rsx_log.fatal("display_manager was improperly destroyed");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!--thread_count)
|
thread_bits &= ~tbit;
|
||||||
{
|
thread_bits.notify_all();
|
||||||
thread_count.notify_all();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,19 +208,17 @@ namespace rsx
|
||||||
fade_animation.duration = 0.5f;
|
fade_animation.duration = 0.5f;
|
||||||
fade_animation.active = true;
|
fade_animation.active = true;
|
||||||
|
|
||||||
thread_count++;
|
g_fxo->init<named_thread>("OSK Thread", [this, tbit = alloc_thread_bit()]
|
||||||
|
|
||||||
g_fxo->init<named_thread>("OSK Thread", [this]
|
|
||||||
{
|
{
|
||||||
|
g_thread_bit = tbit;
|
||||||
|
|
||||||
if (auto error = run_input_loop())
|
if (auto error = run_input_loop())
|
||||||
{
|
{
|
||||||
rsx_log.error("Osk input loop exited with error code=%d", error);
|
rsx_log.error("Osk input loop exited with error code=%d", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!--thread_count)
|
thread_bits &= ~tbit;
|
||||||
{
|
thread_bits.notify_all();
|
||||||
thread_count.notify_all();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,33 @@ namespace rsx
|
||||||
{
|
{
|
||||||
namespace overlays
|
namespace overlays
|
||||||
{
|
{
|
||||||
|
thread_local DECLARE(user_interface::g_thread_bit) = 0;
|
||||||
|
|
||||||
|
u64 user_interface::alloc_thread_bit()
|
||||||
|
{
|
||||||
|
auto [_old, ok] = this->thread_bits.fetch_op([](u64& bits)
|
||||||
|
{
|
||||||
|
if (~bits)
|
||||||
|
{
|
||||||
|
// Set lowest clear bit
|
||||||
|
bits |= bits + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
::overlays.fatal("Out of thread bits in user interface");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 r = u64{1} << utils::cnttz64(~_old, false);
|
||||||
|
::overlays.trace("Bit allocated (%u)", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
// Singleton instance declaration
|
// Singleton instance declaration
|
||||||
fontmgr* fontmgr::m_instance = nullptr;
|
fontmgr* fontmgr::m_instance = nullptr;
|
||||||
|
|
||||||
|
@ -159,14 +186,15 @@ namespace rsx
|
||||||
// Force unload
|
// Force unload
|
||||||
exit.release(true);
|
exit.release(true);
|
||||||
|
|
||||||
while (u32 i = thread_count)
|
while (u64 b = thread_bits)
|
||||||
{
|
{
|
||||||
thread_count.wait(i);
|
if (b == g_thread_bit)
|
||||||
|
|
||||||
if (thread_ctrl::state() == thread_state::aborting)
|
|
||||||
{
|
{
|
||||||
|
// Don't wait for its own bit
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_bits.wait(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
pad::SetIntercepted(false);
|
pad::SetIntercepted(false);
|
||||||
|
|
|
@ -72,7 +72,11 @@ namespace rsx
|
||||||
protected:
|
protected:
|
||||||
Timer input_timer;
|
Timer input_timer;
|
||||||
atomic_t<bool> exit = false;
|
atomic_t<bool> exit = false;
|
||||||
atomic_t<u32> thread_count = 0;
|
atomic_t<u64> thread_bits = 0;
|
||||||
|
|
||||||
|
static thread_local u64 g_thread_bit;
|
||||||
|
|
||||||
|
u64 alloc_thread_bit();
|
||||||
|
|
||||||
std::function<void(s32 status)> on_close;
|
std::function<void(s32 status)> on_close;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue