From e322826347f383ec8ca6ae14326c761a1d7bef8a 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 3efd51024e..ba5511c4ab 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 5fa5005422..c4b0572d32 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 61dffeb7ad..fd7fcc1ed1 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 7b65c2f9c2..df089066db 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();