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.
This commit is contained in:
Bananymous 2024-07-22 00:43:13 +03:00
parent f8261c60c0
commit 3e0150f847
3 changed files with 46 additions and 0 deletions

View File

@ -177,6 +177,7 @@ namespace Kernel
static ProcessorID s_bsb_id;
static BAN::Atomic<uint8_t> s_processor_count;
static BAN::Atomic<bool> s_is_smp_enabled;
static BAN::Atomic<bool> 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<bool> m_smp_pending_lock { false };
SMPMessage* m_smp_pending { nullptr };

View File

@ -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;

View File

@ -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);
}