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:
parent
388ca1c645
commit
7db6594358
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user