From c936aac777a5bae4f8311accd73ee71fc9e1e5d9 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 3 Apr 2023 01:51:05 +0300 Subject: [PATCH] Kernel: Optimize scheduler idling Now after each interrupt we will ask the scheduler to reschedule if the current thread is the idle thread. This allows semaphore unblocking to be practically instant when there is only one thread executing. Now disk reading is back to ~3 MB/s for single threaded process --- kernel/arch/i386/IDT.cpp | 3 +++ kernel/arch/x86_64/IDT.cpp | 3 +++ kernel/include/kernel/Scheduler.h | 1 + kernel/kernel/Scheduler.cpp | 14 ++++++++++++++ 4 files changed, 21 insertions(+) diff --git a/kernel/arch/i386/IDT.cpp b/kernel/arch/i386/IDT.cpp index 3efd5102..ba5511c4 100644 --- a/kernel/arch/i386/IDT.cpp +++ b/kernel/arch/i386/IDT.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #define INTERRUPT_HANDLER____(i, msg) \ static void interrupt ## i () \ @@ -132,6 +133,8 @@ found: // NOTE: Scheduler sends PIT eoi's if (irq != PIT_IRQ) InterruptController::get().eoi(irq); + + Kernel::Scheduler::get().reschedule_if_idling(); } extern "C" void handle_irq_common(); diff --git a/kernel/arch/x86_64/IDT.cpp b/kernel/arch/x86_64/IDT.cpp index 5fa50054..c4b0572d 100644 --- a/kernel/arch/x86_64/IDT.cpp +++ b/kernel/arch/x86_64/IDT.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #define REGISTER_ISR_HANDLER(i) register_interrupt_handler(i, isr ## i) #define REGISTER_IRQ_HANDLER(i) register_interrupt_handler(IRQ_VECTOR_BASE + i, irq ## i) @@ -129,6 +130,8 @@ namespace IDT // NOTE: Scheduler sends PIT eoi's if (irq != PIT_IRQ) InterruptController::get().eoi(irq); + + Kernel::Scheduler::get().reschedule_if_idling(); } static void flush_idt() diff --git a/kernel/include/kernel/Scheduler.h b/kernel/include/kernel/Scheduler.h index 61dffeb7..fd7fcc1e 100644 --- a/kernel/include/kernel/Scheduler.h +++ b/kernel/include/kernel/Scheduler.h @@ -16,6 +16,7 @@ namespace Kernel void start(); void reschedule(); + void reschedule_if_idling(); BAN::ErrorOr add_thread(Thread*); diff --git a/kernel/kernel/Scheduler.cpp b/kernel/kernel/Scheduler.cpp index 7b65c2f9..df089066 100644 --- a/kernel/kernel/Scheduler.cpp +++ b/kernel/kernel/Scheduler.cpp @@ -70,6 +70,20 @@ namespace Kernel ASSERT_NOT_REACHED(); } + void Scheduler::reschedule_if_idling() + { + VERIFY_CLI(); + + if (m_active_threads.empty() || ¤t_thread() != m_idle_thread) + return; + + if (save_current_thread()) + return; + m_current_thread = m_active_threads.begin(); + execute_current_thread(); + ASSERT_NOT_REACHED(); + } + void Scheduler::wake_threads() { VERIFY_CLI();