1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 12:12:50 +01:00

rsx/overlays: Use lf_queue for a lock-free stack implementation

This commit is contained in:
kd-11 2023-02-14 02:27:47 +03:00 committed by kd-11
parent 388ca1c645
commit 7db6594358
4 changed files with 34 additions and 50 deletions

View File

@ -359,6 +359,14 @@ public:
return result;
}
// Withdraw the list in reverse order (LIFO/FILO)
lf_queue_slice<T> pop_all_reversed()
{
lf_queue_slice<T> result;
result.m_head = m_head.exchange(nullptr);
return result;
}
// Apply func(data) to each element, return the total length
template <typename F>
usz apply(F func)

View File

@ -7,6 +7,15 @@ namespace rsx
{
namespace overlays
{
display_manager::display_manager(int)
{
m_input_thread = std::make_shared<named_thread<overlay_input_thread>>();
(*m_input_thread)([this]()
{
input_thread_loop();
});
}
display_manager::~display_manager()
{
if (m_input_thread)
@ -135,22 +144,9 @@ namespace rsx
m_type_ids_to_remove.clear();
}
void display_manager::on_overlay_activated(const std::shared_ptr<overlay>& item)
void display_manager::on_overlay_activated(const std::shared_ptr<overlay>& /*item*/)
{
if (auto iface = std::dynamic_pointer_cast<user_interface>(item))
{
// Kick input thread if not enabled. Expect the interface to attach shortly
std::lock_guard lock(m_input_thread_lock);
if (!m_input_thread)
{
m_input_thread = std::make_shared<named_thread<overlay_input_thread>>();
(*m_input_thread)([this]()
{
input_thread_loop();
});
}
}
// TODO: Internal management, callbacks, etc
}
void display_manager::attach_thread_input(
@ -161,8 +157,7 @@ namespace rsx
{
if (auto iface = std::dynamic_pointer_cast<user_interface>(get(uid)))
{
std::lock_guard lock(m_input_thread_lock);
m_input_token_stack.emplace_front(
m_input_token_stack.push(
std::move(iface),
on_input_loop_enter,
on_input_loop_exit,
@ -172,46 +167,27 @@ namespace rsx
void display_manager::on_overlay_removed(const std::shared_ptr<overlay>& item)
{
if (!dynamic_cast<user_interface*>(item.get()))
auto iface = std::dynamic_pointer_cast<user_interface>(item);
if (!iface)
{
// Not instance of UI, ignore
return;
}
std::lock_guard lock(m_input_thread_lock);
for (auto& entry : m_input_token_stack)
{
if (entry.target->uid == item->uid)
{
// Release
entry.target = {};
break;
}
}
// The top must never be an empty ref. Pop all empties.
while (!m_input_token_stack.empty() && !m_input_token_stack.front().target)
{
m_input_token_stack.pop_front();
}
iface->detach_input();
}
void display_manager::input_thread_loop()
{
while (!m_input_thread_abort)
{
input_thread_context_t input_context;
for (auto&& input_context : m_input_token_stack.pop_all_reversed())
{
reader_lock lock(m_input_thread_lock);
if (!m_input_token_stack.empty())
if (input_context.target->is_detached())
{
input_context = m_input_token_stack.front();
m_input_token_stack.pop_front();
continue;
}
}
if (input_context.target)
{
if (input_context.input_loop_prologue)
{
input_context.input_loop_prologue();
@ -236,10 +212,8 @@ namespace rsx
rsx_log.error("Input loop exited with error code=%d", result);
}
}
else
{
thread_ctrl::wait_for(1000);
}
m_input_token_stack.wait();
}
}
}

View File

@ -39,8 +39,7 @@ namespace rsx
public:
// Disable default construction to make it conditionally available in g_fxo
explicit display_manager(int) noexcept
{}
explicit display_manager(int) noexcept;
~display_manager();
@ -176,8 +175,7 @@ namespace rsx
std::function<s32()> input_loop_override = nullptr;
};
std::deque<input_thread_context_t> m_input_token_stack;
shared_mutex m_input_thread_lock;
lf_queue<input_thread_context_t> m_input_token_stack;
atomic_t<bool> m_input_thread_abort = false;
std::shared_ptr<named_thread<overlay_input_thread>> m_input_thread;

View File

@ -112,6 +112,7 @@ namespace rsx
atomic_t<bool> m_interactive = false;
bool m_start_pad_interception = true;
atomic_t<bool> m_stop_pad_interception = false;
atomic_t<bool> m_input_thread_detached = false;
atomic_t<u64> thread_bits = 0;
bool m_keyboard_input_enabled = false; // Allow keyboard input
bool m_keyboard_pad_handler_active = true; // Initialized as true to prevent keyboard input until proven otherwise.
@ -146,6 +147,9 @@ namespace rsx
public:
s32 return_code = 0; // CELL_OK
bool is_detached() const { return m_input_thread_detached; }
void detach_input() { m_input_thread_detached.store(true); }
void update() override {}
compiled_resource get_compiled() override = 0;