From ed3924722e8c98825966f78e906275b2905bad6a Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 20 May 2026 19:11:27 +0300 Subject: [PATCH] Kernel: Remove kernel CPU load printing We still keep track of processor loads but the hacky printing is no longer done in kernel space :) --- kernel/include/kernel/Processor.h | 19 +++--- kernel/kernel/Device/FramebufferDevice.cpp | 46 +-------------- kernel/kernel/Input/InputDevice.cpp | 3 - kernel/kernel/Processor.cpp | 68 ++++++++++++---------- 4 files changed, 48 insertions(+), 88 deletions(-) diff --git a/kernel/include/kernel/Processor.h b/kernel/include/kernel/Processor.h index 64f79482..e99da4f3 100644 --- a/kernel/include/kernel/Processor.h +++ b/kernel/include/kernel/Processor.h @@ -57,6 +57,12 @@ namespace Kernel }; }; + struct LoadStats + { + uint64_t ns_idle; + uint64_t ns_total; + }; + public: static Processor& create(ProcessorID id); static Processor& initialize(); @@ -72,9 +78,6 @@ namespace Kernel static void set_smp_enabled() { s_is_smp_enabled = true; } static void wait_until_processors_ready(); - static void toggle_should_print_cpu_load() { s_should_print_cpu_load = !s_should_print_cpu_load; } - static bool get_should_print_cpu_load() { return s_should_print_cpu_load; } - static ProcessorID bsp_id() { return s_bsp_id; } static bool current_is_bsp() { return current_id() == bsp_id(); } @@ -116,6 +119,8 @@ namespace Kernel static void* get_current_page_table() { return read_gs_sized(offsetof(Processor, m_current_page_table)); } static void set_current_page_table(void* page_table) { write_gs_sized(offsetof(Processor, m_current_page_table), page_table); } + static LoadStats get_load_stats(size_t index); + static void yield(); static Scheduler& scheduler() { return *read_gs_sized(offsetof(Processor, m_scheduler)); } @@ -187,7 +192,6 @@ namespace Kernel static ProcessorID s_bsp_id; static BAN::Atomic s_processor_count; static BAN::Atomic s_is_smp_enabled; - static BAN::Atomic s_should_print_cpu_load; static paddr_t s_shared_page_paddr; static vaddr_t s_shared_page_vaddr; @@ -207,10 +211,9 @@ 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_load_stat_lock; + uint64_t m_load_start_ns { 0 }; + LoadStats m_load_stats {}; BAN::Atomic m_smp_pending { nullptr }; BAN::Atomic m_smp_free { nullptr }; diff --git a/kernel/kernel/Device/FramebufferDevice.cpp b/kernel/kernel/Device/FramebufferDevice.cpp index 2d2df44e..570a8567 100644 --- a/kernel/kernel/Device/FramebufferDevice.cpp +++ b/kernel/kernel/Device/FramebufferDevice.cpp @@ -356,51 +356,7 @@ namespace Kernel void do_msync(uint32_t first_pixel, uint32_t pixel_count) { - if (!Processor::get_should_print_cpu_load()) - return m_framebuffer->sync_pixels_linear(first_pixel, pixel_count); - - const uint32_t fb_width = m_framebuffer->width(); - - // If we are here (in FramebufferMemoryRegion), our terminal driver is FramebufferTerminalDriver - ASSERT(g_terminal_driver->has_font()); - const auto& font = g_terminal_driver->font(); - - const uint32_t x = first_pixel % fb_width; - const uint32_t y = first_pixel / fb_width; - - const uint32_t load_w = 16 * font.width(); - const uint32_t load_h = Processor::count() * font.height(); - - if (y >= load_h || x + pixel_count <= fb_width - load_w) - return m_framebuffer->sync_pixels_linear(first_pixel, pixel_count); - - if (x >= fb_width - load_w && x + pixel_count <= fb_width) - return; - - if (x < fb_width - load_w) - m_framebuffer->sync_pixels_linear(first_pixel, fb_width - load_w - x); - - if (x + pixel_count > fb_width) - { - const uint32_t past_last_pixel = first_pixel + pixel_count; - - first_pixel = (y + 1) * fb_width; - pixel_count = past_last_pixel - first_pixel; - - const uint32_t cpu_load_end = load_h * fb_width; - - while (pixel_count && first_pixel < cpu_load_end) - { - m_framebuffer->sync_pixels_linear(first_pixel, BAN::Math::min(pixel_count, fb_width - load_w)); - - const uint32_t advance = BAN::Math::min(pixel_count, fb_width); - pixel_count -= advance; - first_pixel += advance; - } - - if (pixel_count) - m_framebuffer->sync_pixels_linear(first_pixel, pixel_count); - } + m_framebuffer->sync_pixels_linear(first_pixel, pixel_count); } private: diff --git a/kernel/kernel/Input/InputDevice.cpp b/kernel/kernel/Input/InputDevice.cpp index bafa632f..583504e0 100644 --- a/kernel/kernel/Input/InputDevice.cpp +++ b/kernel/kernel/Input/InputDevice.cpp @@ -197,9 +197,6 @@ namespace Kernel } else switch (key_event.keycode) { - case LibInput::keycode_function(1): - Processor::toggle_should_print_cpu_load(); - break; case LibInput::keycode_function(11): DevFileSystem::get().initiate_disk_cache_drop(); break; diff --git a/kernel/kernel/Processor.cpp b/kernel/kernel/Processor.cpp index 3bb9c7ea..0706c1fb 100644 --- a/kernel/kernel/Processor.cpp +++ b/kernel/kernel/Processor.cpp @@ -23,7 +23,6 @@ namespace Kernel ProcessorID Processor::s_bsp_id { PROCESSOR_NONE }; BAN::Atomic Processor::s_processor_count { 0 }; BAN::Atomic Processor::s_is_smp_enabled { false }; - BAN::Atomic Processor::s_should_print_cpu_load { false }; paddr_t Processor::s_shared_page_paddr { 0 }; vaddr_t Processor::s_shared_page_vaddr { 0 }; @@ -598,6 +597,26 @@ namespace Kernel set_interrupt_state(state); } + Processor::LoadStats Processor::get_load_stats(size_t index) + { + ASSERT(index < Processor::count()); + + auto& processor = s_processors[s_processor_ids[index].as_u32()]; + + bool expected = false; + while (!processor.m_load_stat_lock.compare_exchange(expected, true)) + { + Processor::pause(); + expected = false; + } + + const auto load_stats = processor.m_load_stats; + + processor.m_load_stat_lock.store(false); + + return load_stats; + } + void Processor::yield() { auto state = get_interrupt_state(); @@ -605,47 +624,32 @@ namespace Kernel ASSERT(!Thread::current().has_spinlock()); - auto& processor_info = s_processors[current_id().as_u32()]; + auto& processor = 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) + bool expected = false; + while (!processor.m_load_stat_lock.compare_exchange(expected, true)) { - 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 - BAN::Math::min(processor_info.m_idle_ns, duration_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::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; + Processor::pause(); + expected = false; } + + const uint64_t elapsed_ns = SystemTimer::get().ns_since_boot() - processor.m_load_start_ns; + + auto& load_stats = processor.m_load_stats; + if (scheduler().is_idle()) + load_stats.ns_idle += elapsed_ns; + load_stats.ns_total += elapsed_ns; + + processor.m_load_stat_lock.store(false); } if (!scheduler().is_idle()) Thread::current().set_cpu_time_stop(); - asm_yield_trampoline(processor_info.stack_top_vaddr()); + asm_yield_trampoline(processor.stack_top_vaddr()); - processor_info.m_start_ns = SystemTimer::get().ns_since_boot(); + processor.m_load_start_ns = SystemTimer::get().ns_since_boot(); if (!scheduler().is_idle()) Thread::current().set_cpu_time_start();