1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:57:36 +00:00

Kernel: Stop idling after handling an IRQ

If we receive an IRQ while the idle task is running, prevent it from
re-halting the CPU after the IRQ handler returns.

Instead have the idle task yield to the scheduler, so we can see if
the IRQ has unblocked something.
This commit is contained in:
Andreas Kling 2019-09-14 19:44:22 +02:00
parent b35ad5b523
commit e1481dcb42
4 changed files with 28 additions and 5 deletions

View file

@ -490,8 +490,10 @@ void handle_irq()
} }
} }
if (s_irq_handler[irq]) if (s_irq_handler[irq]) {
s_irq_handler[irq]->handle_irq(); s_irq_handler[irq]->handle_irq();
Scheduler::stop_idling();
}
PIC::eoi(irq); PIC::eoi(irq);
} }

View file

@ -575,3 +575,24 @@ void Scheduler::timer_tick(RegisterDump& regs)
"orl $0x00004000, (%esp)\n" "orl $0x00004000, (%esp)\n"
"popf\n"); "popf\n");
} }
static bool s_should_stop_idling = false;
void Scheduler::stop_idling()
{
if (current != &s_colonel_process->main_thread())
return;
s_should_stop_idling = true;
}
void Scheduler::idle_loop()
{
for (;;) {
asm("hlt");
if (s_should_stop_idling) {
s_should_stop_idling = false;
yield();
}
}
}

View file

@ -30,6 +30,8 @@ public:
static Process* colonel(); static Process* colonel();
static bool is_active(); static bool is_active();
static void beep(); static void beep();
static void idle_loop();
static void stop_idling();
template<typename Callback> template<typename Callback>
static inline IterationDecision for_each_runnable(Callback); static inline IterationDecision for_each_runnable(Callback);

View file

@ -277,8 +277,6 @@ extern "C" [[noreturn]] void init()
sti(); sti();
// This now becomes the idle process :^) Scheduler::idle_loop();
for (;;) { ASSERT_NOT_REACHED();
asm("hlt");
}
} }