From 297e797a320f099e376af27a9b7a7159d0f13964 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 30 Aug 2026 08:18:50 +0200 Subject: [PATCH] [hle/kernel] remove flusher thread from OutputDebugString (#4291) Signed-off-by: lizzie - [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- Unneeded abstraction? either way it seems this thread is not required anyone thinking otherwise feel free to lmk directly contradicts with #4290 and #3744 Remember that messages will be displayed out of order this can make actual debugging much harder I'm afraid Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4291 Reviewed-by: MaranBr Reviewed-by: crueter --- src/core/hle/kernel/svc/svc_debug_string.cpp | 50 ++------------------ 1 file changed, 3 insertions(+), 47 deletions(-) diff --git a/src/core/hle/kernel/svc/svc_debug_string.cpp b/src/core/hle/kernel/svc/svc_debug_string.cpp index c190fa7a3f..6db3849a82 100644 --- a/src/core/hle/kernel/svc/svc_debug_string.cpp +++ b/src/core/hle/kernel/svc/svc_debug_string.cpp @@ -17,56 +17,12 @@ namespace Kernel::Svc { -constexpr auto MAX_MSG_TIME = std::chrono::milliseconds(250); -const auto MAX_MSG_SIZE = 0x1000; - /// Used to output a message on a debug hardware unit - does nothing on a retail unit Result OutputDebugString(Core::System& system, u64 address, u64 len) { - static struct DebugFlusher { - std::string msg_buffer; - std::mutex msg_mutex; - std::condition_variable msg_cv; - std::chrono::steady_clock::time_point last_msg_time; - std::optional thread; - } flusher_data; R_SUCCEED_IF(len == 0); - // Only start the thread the very first time this function is called - if (!flusher_data.thread) { - flusher_data.thread.emplace([](std::stop_token stop_token) { - while (!stop_token.stop_requested()) { - std::unique_lock lock(flusher_data.msg_mutex); - flusher_data.msg_cv.wait(lock, [&stop_token] { - return !flusher_data.msg_buffer.empty() || stop_token.stop_requested(); - }); - if (stop_token.stop_requested() && flusher_data.msg_buffer.empty()) - break; - auto timeout = flusher_data.last_msg_time + MAX_MSG_TIME; - bool woke_early = flusher_data.msg_cv.wait_until(lock, timeout, [&stop_token] { - return flusher_data.msg_buffer.size() >= MAX_MSG_SIZE || stop_token.stop_requested(); - }); - if (!woke_early || flusher_data.msg_buffer.size() >= MAX_MSG_SIZE || stop_token.stop_requested()) { - if (!flusher_data.msg_buffer.empty()) { - // Remove trailing newline as LOG_INFO adds that anyways - if (flusher_data.msg_buffer.back() == '\n') - flusher_data.msg_buffer.pop_back(); - - LOG_INFO(Debug_Emulated, "\n{}", flusher_data.msg_buffer); - flusher_data.msg_buffer.clear(); - } - if (stop_token.stop_requested()) break; - } - } - flusher_data.msg_cv.notify_all(); - }); - } - { - std::lock_guard lock(flusher_data.msg_mutex); - const auto old_size = flusher_data.msg_buffer.size(); - flusher_data.msg_buffer.resize(old_size + len); - GetCurrentMemory(system.Kernel()).ReadBlock(address, flusher_data.msg_buffer.data() + old_size, len); - flusher_data.last_msg_time = std::chrono::steady_clock::now(); - } - flusher_data.msg_cv.notify_one(); + std::string msg_buffer(len, 0); + GetCurrentMemory(system.Kernel()).ReadBlock(address, msg_buffer.data(), len); + LOG_INFO(Debug_Emulated, "{}", msg_buffer); R_SUCCEED(); }