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:
parent
3998c5f955
commit
e322826347
|
@ -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();
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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*);
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,20 @@ namespace Kernel
|
||||||
ASSERT_NOT_REACHED();
|
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()
|
void Scheduler::wake_threads()
|
||||||
{
|
{
|
||||||
VERIFY_CLI();
|
VERIFY_CLI();
|
||||||
|
|
Loading…
Reference in New Issue