[fix] preemptive scheduler not interleaving tasks
This commit is contained in:
+8
-4
@@ -55,6 +55,10 @@ static void irq_handler(trap_frame* frame) {
|
|||||||
UINT8 vector = (UINT8)frame->vector;
|
UINT8 vector = (UINT8)frame->vector;
|
||||||
UINT8 irq = vector - PIC_IRQ_BASE;
|
UINT8 irq = vector - PIC_IRQ_BASE;
|
||||||
|
|
||||||
|
// Send EOI BEFORE handling, so PIC can deliver new interrupts
|
||||||
|
// immediately after a context switch inside the handler.
|
||||||
|
pic_send_eoi(irq);
|
||||||
|
|
||||||
switch (irq) {
|
switch (irq) {
|
||||||
case 0: // PIT timer
|
case 0: // PIT timer
|
||||||
pit_irq_handler();
|
pit_irq_handler();
|
||||||
@@ -62,9 +66,6 @@ static void irq_handler(trap_frame* frame) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send EOI to PIC
|
|
||||||
pic_send_eoi(irq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void kernel_main() {
|
extern "C" void kernel_main() {
|
||||||
@@ -156,10 +157,11 @@ extern "C" void kernel_main() {
|
|||||||
|
|
||||||
// Task A: prints messages — preemption handles time slicing
|
// Task A: prints messages — preemption handles time slicing
|
||||||
task_create("taskA", []() {
|
task_create("taskA", []() {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
serial_write("[taskA] running iteration ");
|
serial_write("[taskA] running iteration ");
|
||||||
serial_write_hex(i);
|
serial_write_hex(i);
|
||||||
serial_write("\n");
|
serial_write("\n");
|
||||||
|
for (volatile int j = 0; j < 50000000; j++) {}
|
||||||
}
|
}
|
||||||
serial_write("[taskA] done\n");
|
serial_write("[taskA] done\n");
|
||||||
});
|
});
|
||||||
@@ -170,6 +172,7 @@ extern "C" void kernel_main() {
|
|||||||
serial_write("[taskB] hello from taskB #");
|
serial_write("[taskB] hello from taskB #");
|
||||||
serial_write_hex(i);
|
serial_write_hex(i);
|
||||||
serial_write("\n");
|
serial_write("\n");
|
||||||
|
for (volatile int j = 0; j < 50000000; j++) {}
|
||||||
}
|
}
|
||||||
serial_write("[taskB] done\n");
|
serial_write("[taskB] done\n");
|
||||||
});
|
});
|
||||||
@@ -177,6 +180,7 @@ extern "C" void kernel_main() {
|
|||||||
// Task C: short task
|
// Task C: short task
|
||||||
task_create("taskC", []() {
|
task_create("taskC", []() {
|
||||||
serial_write("[taskC] quick task\n");
|
serial_write("[taskC] quick task\n");
|
||||||
|
for (volatile int j = 0; j < 50000000; j++) {}
|
||||||
serial_write("[taskC] finished\n");
|
serial_write("[taskC] finished\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ static task_t* g_task_list = NULL; // circular linked list head
|
|||||||
static void (*g_task_entries[TASK_MAX])(void);
|
static void (*g_task_entries[TASK_MAX])(void);
|
||||||
|
|
||||||
extern "C" void task_entry_trampoline() {
|
extern "C" void task_entry_trampoline() {
|
||||||
|
ASM("sti");
|
||||||
task_t* cur = scheduler_current();
|
task_t* cur = scheduler_current();
|
||||||
if (cur && g_task_entries[cur->id]) {
|
if (cur && g_task_entries[cur->id]) {
|
||||||
g_task_entries[cur->id]();
|
g_task_entries[cur->id]();
|
||||||
|
|||||||
Reference in New Issue
Block a user