From 3e0150f847f7894adb1a706be8b48b805c9f018f Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 22 Jul 2024 00:43:13 +0300 Subject: [PATCH] Kernel: Pressing F1 now toggles rendering of CPU loads to the terminal This can be nice for seeing the performance and problems on the load balancing algorithm. --- kernel/include/kernel/Processor.h | 6 +++++ kernel/kernel/Input/InputDevice.cpp | 3 +++ kernel/kernel/Processor.cpp | 37 +++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/kernel/include/kernel/Processor.h b/kernel/include/kernel/Processor.h index e13d4033..ea87fe94 100644 --- a/kernel/include/kernel/Processor.h +++ b/kernel/include/kernel/Processor.h @@ -177,6 +177,7 @@ namespace Kernel static ProcessorID s_bsb_id; static BAN::Atomic s_processor_count; static BAN::Atomic s_is_smp_enabled; + static BAN::Atomic s_should_print_cpu_load; ProcessorID m_id { PROCESSOR_NONE }; @@ -188,6 +189,11 @@ namespace Kernel Scheduler* m_scheduler { nullptr }; + uint64_t m_start_ns { 0 }; + uint64_t m_idle_ns { 0 }; + uint64_t m_last_update_ns { 0 }; + uint64_t m_next_update_ns { 0 }; + BAN::Atomic m_smp_pending_lock { false }; SMPMessage* m_smp_pending { nullptr }; diff --git a/kernel/kernel/Input/InputDevice.cpp b/kernel/kernel/Input/InputDevice.cpp index da6fe0fc..8790c5bc 100644 --- a/kernel/kernel/Input/InputDevice.cpp +++ b/kernel/kernel/Input/InputDevice.cpp @@ -114,6 +114,9 @@ namespace Kernel { switch (key_event.keycode) { + case LibInput::keycode_function(1): + Processor::toggle_should_print_cpu_load(); + break; case LibInput::keycode_function(12): Kernel::panic("Keyboard kernel panic :)"); break; diff --git a/kernel/kernel/Processor.cpp b/kernel/kernel/Processor.cpp index 67fe4e26..2c40a115 100644 --- a/kernel/kernel/Processor.cpp +++ b/kernel/kernel/Processor.cpp @@ -332,6 +332,41 @@ namespace Kernel auto state = get_interrupt_state(); set_interrupt_state(InterruptState::Disabled); + auto& processor_info = s_processors[current_id().as_u32()]; + + { + constexpr uint64_t load_update_interval_ns = 1'000'000'000; + + const uint64_t current_ns = SystemTimer::get().ns_since_boot(); + + if (scheduler().is_idle()) + processor_info.m_idle_ns += current_ns - processor_info.m_start_ns; + + if (current_ns >= processor_info.m_next_update_ns) + { + if (s_should_print_cpu_load && g_terminal_driver) + { + const uint64_t duration_ns = current_ns - processor_info.m_last_update_ns; + const uint64_t load_x1000 = 100'000 * (duration_ns - processor_info.m_idle_ns) / duration_ns; + + uint32_t x = g_terminal_driver->width() - 16; + uint32_t y = current_id().as_u32(); + const auto proc_putc = + [&x, y](char ch) + { + if (x < g_terminal_driver->width() && y < g_terminal_driver->height()) + g_terminal_driver->putchar_at(ch, x++, y, TerminalColor::BRIGHT_WHITE, TerminalColor::BLACK); + }; + + BAN::Formatter::print(proc_putc, "CPU { 2}: { 3}.{3}%", current_id(), load_x1000 / 1000, load_x1000 % 1000); + } + + processor_info.m_idle_ns = 0; + processor_info.m_last_update_ns = current_ns; + processor_info.m_next_update_ns += load_update_interval_ns; + } + } + #if ARCH(x86_64) asm volatile( "movq %%rsp, %%rcx;" @@ -360,6 +395,8 @@ namespace Kernel #error #endif + processor_info.m_start_ns = SystemTimer::get().ns_since_boot(); + Processor::set_interrupt_state(state); }