From 1e464d1d1431d9d715bda598402295a4892ec72a Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Thu, 27 May 2021 19:41:25 +0900 Subject: [PATCH] Let other APs sleep until there's something to schedule --- base/usr/include/kernel/process.h | 1 + kernel/arch/x86_64/acpi.c | 9 +++++++++ kernel/sys/process.c | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/base/usr/include/kernel/process.h b/base/usr/include/kernel/process.h index 9502622..a7823b2 100644 --- a/base/usr/include/kernel/process.h +++ b/base/usr/include/kernel/process.h @@ -216,4 +216,5 @@ extern void arch_set_kernel_stack(uintptr_t); extern void arch_enter_user(uintptr_t entrypoint, int argc, char * argv[], char * envp[], uintptr_t stack); __attribute__((noreturn)) extern void arch_enter_signal_handler(uintptr_t,int); +extern void arch_wakeup_others(void); diff --git a/kernel/arch/x86_64/acpi.c b/kernel/arch/x86_64/acpi.c index 223d795..fc3643f 100644 --- a/kernel/arch/x86_64/acpi.c +++ b/kernel/arch/x86_64/acpi.c @@ -282,3 +282,12 @@ void acpi_initialize(void) { } } +void arch_wakeup_others(void) { + /* Never wake up BSP, don't hit ourselves, easy. */ + for (int i = 1; i < processor_count; ++i) { + if (i == this_core->cpu_id) continue; + if (processor_local_data[i].current_process == processor_local_data[i].kernel_idle_task) { + lapic_send_ipi(processor_local_data[i].lapic_id, 0x407E); + } + } +} diff --git a/kernel/sys/process.c b/kernel/sys/process.c index eec3ce2..cdf4e44 100644 --- a/kernel/sys/process.c +++ b/kernel/sys/process.c @@ -293,6 +293,7 @@ static void _kidle(void) { static void _kburn(void) { while (1) { + arch_pause(); if (((volatile list_t *)process_queue)->head) switch_next(); } } @@ -558,6 +559,8 @@ void make_process_ready(volatile process_t * proc) { spin_lock(process_queue_lock); list_append(process_queue, (node_t*)&proc->sched_node); spin_unlock(process_queue_lock); + + arch_wakeup_others(); } /** @@ -866,6 +869,7 @@ int waitpid(int pid, int * status, int options) { } int pid = candidate->id; if (candidate->flags & PROC_FLAG_FINISHED) { + while (*((volatile int *)&candidate->flags) & PROC_FLAG_RUNNING); process_delete((process_t*)candidate); } return pid;