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
This commit is contained in:
Bananymous 2023-04-03 01:51:05 +03:00
parent 3998c5f955
commit e322826347
4 changed files with 21 additions and 0 deletions

View File

@ -3,6 +3,7 @@
#include <kernel/InterruptController.h> #include <kernel/InterruptController.h>
#include <kernel/kmalloc.h> #include <kernel/kmalloc.h>
#include <kernel/Panic.h> #include <kernel/Panic.h>
#include <kernel/Scheduler.h>
#define INTERRUPT_HANDLER____(i, msg) \ #define INTERRUPT_HANDLER____(i, msg) \
static void interrupt ## i () \ static void interrupt ## i () \
@ -132,6 +133,8 @@ found:
// NOTE: Scheduler sends PIT eoi's // NOTE: Scheduler sends PIT eoi's
if (irq != PIT_IRQ) if (irq != PIT_IRQ)
InterruptController::get().eoi(irq); InterruptController::get().eoi(irq);
Kernel::Scheduler::get().reschedule_if_idling();
} }
extern "C" void handle_irq_common(); extern "C" void handle_irq_common();

View File

@ -3,6 +3,7 @@
#include <kernel/InterruptController.h> #include <kernel/InterruptController.h>
#include <kernel/kmalloc.h> #include <kernel/kmalloc.h>
#include <kernel/Panic.h> #include <kernel/Panic.h>
#include <kernel/Scheduler.h>
#define REGISTER_ISR_HANDLER(i) register_interrupt_handler(i, isr ## i) #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) #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 // NOTE: Scheduler sends PIT eoi's
if (irq != PIT_IRQ) if (irq != PIT_IRQ)
InterruptController::get().eoi(irq); InterruptController::get().eoi(irq);
Kernel::Scheduler::get().reschedule_if_idling();
} }
static void flush_idt() static void flush_idt()

View File

@ -16,6 +16,7 @@ namespace Kernel
void start(); void start();
void reschedule(); void reschedule();
void reschedule_if_idling();
BAN::ErrorOr<void> add_thread(Thread*); BAN::ErrorOr<void> add_thread(Thread*);

View File

@ -70,6 +70,20 @@ namespace Kernel
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
void Scheduler::reschedule_if_idling()
{
VERIFY_CLI();
if (m_active_threads.empty() || &current_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() void Scheduler::wake_threads()
{ {
VERIFY_CLI(); VERIFY_CLI();