mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-27 17:31:31 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 86be89ed46 | |||
| c9c59407ca |
@@ -17,56 +17,12 @@
|
|||||||
|
|
||||||
namespace Kernel::Svc {
|
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
|
/// 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) {
|
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<std::jthread> thread;
|
|
||||||
} flusher_data;
|
|
||||||
R_SUCCEED_IF(len == 0);
|
R_SUCCEED_IF(len == 0);
|
||||||
// Only start the thread the very first time this function is called
|
std::string msg_buffer(len, 0);
|
||||||
if (!flusher_data.thread) {
|
GetCurrentMemory(system.Kernel()).ReadBlock(address, msg_buffer.data(), len);
|
||||||
flusher_data.thread.emplace([](std::stop_token stop_token) {
|
LOG_INFO(Debug_Emulated, "{}", msg_buffer);
|
||||||
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();
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user