From 6f05feb55f20f213b18e3b2c6807030a3eb9d46b Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 7 Dec 2022 15:55:58 +0100 Subject: [PATCH] Add sleeping mechanism --- kernel/src/arch/CPU.h | 4 +--- kernel/src/arch/x86_64/Thread.cpp | 1 + kernel/src/main.cpp | 29 ++++++++--------------------- kernel/src/thread/Scheduler.cpp | 19 +++++++++++++++++++ kernel/src/thread/Scheduler.h | 6 +++++- kernel/src/thread/Thread.h | 1 + 6 files changed, 35 insertions(+), 25 deletions(-) diff --git a/kernel/src/arch/CPU.h b/kernel/src/arch/CPU.h index 0021fea8..35159630 100644 --- a/kernel/src/arch/CPU.h +++ b/kernel/src/arch/CPU.h @@ -20,6 +20,4 @@ namespace CPU void enable_interrupts(); void disable_interrupts(); void wait_for_interrupt(); -} - -extern "C" void kernel_yield(); \ No newline at end of file +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/Thread.cpp b/kernel/src/arch/x86_64/Thread.cpp index 7eb3160e..4e1ffe86 100644 --- a/kernel/src/arch/x86_64/Thread.cpp +++ b/kernel/src/arch/x86_64/Thread.cpp @@ -31,6 +31,7 @@ void Thread::init_regs_kernel() memset(®s, 0, sizeof(Registers)); regs.cs = 0x08; regs.ss = 0x10; + regs.rflags = 1 << 9; // IF (Interrupt enable flag) } void Thread::set_arguments(u64 arg1, u64 arg2, u64 arg3, u64 arg4) diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 7016296d..80c7accc 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -9,24 +9,17 @@ #include #include -void print_in_loop() +void async_thread() { while (true) { - CPU::disable_interrupts(); - Serial::printf("%lu", Scheduler::current()->id); - CPU::enable_interrupts(); - } -} + Thread* current = Scheduler::current(); + kinfoln("Ticks: %lu, %lu user, %lu kernel, %lu idle", current->ticks, current->ticks_in_user, + current->ticks_in_kernel, Scheduler::idle()->ticks); -void print_one_and_then_yield() -{ - while (true) - { - CPU::disable_interrupts(); - Serial::printf("%lu", Scheduler::current()->id); - kernel_yield(); - CPU::enable_interrupts(); + CPU::wait_for_interrupt(); + + kernel_sleep(1000); } } @@ -52,13 +45,7 @@ Result init() Scheduler::init(); - TRY(Scheduler::new_kernel_thread(print_in_loop)); - TRY(Scheduler::new_kernel_thread(print_in_loop)); - TRY(Scheduler::new_kernel_thread(print_in_loop)); - TRY(Scheduler::new_kernel_thread(print_in_loop)); - TRY(Scheduler::new_kernel_thread(print_in_loop)); - TRY(Scheduler::new_kernel_thread(print_in_loop)); - TRY(Scheduler::new_kernel_thread(print_one_and_then_yield)); + TRY(Scheduler::new_kernel_thread(async_thread)); CPU::platform_finish_init(); diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 9722afac..c6b7fe90 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -39,6 +39,11 @@ namespace Scheduler return g_current; } + Thread* idle() + { + return &g_idle; + } + Result kernel_thread_alloc_stack_and_append_impl(Thread* thread) { // FIXME: We will leak the thread if VM allocation or alloc_at fail. @@ -146,6 +151,20 @@ namespace Scheduler g_current->ticks_left--; + g_threads.for_each([](Thread* thread) { + if (thread->state == ThreadState::Sleeping) + { + if (--thread->sleep_ticks_left == 0) thread->state = ThreadState::Runnable; + } + }); + if (!g_current->ticks_left) switch_task(regs); } +} + +void kernel_sleep(u64 ms) +{ + g_current->sleep_ticks_left = ms; + g_current->state = ThreadState::Sleeping; + kernel_yield(); } \ No newline at end of file diff --git a/kernel/src/thread/Scheduler.h b/kernel/src/thread/Scheduler.h index 95b12451..57bb85ad 100644 --- a/kernel/src/thread/Scheduler.h +++ b/kernel/src/thread/Scheduler.h @@ -6,6 +6,7 @@ namespace Scheduler void init(); Thread* current(); + Thread* idle(); Result new_kernel_thread(u64 address); Result new_kernel_thread(void (*func)(void)); @@ -16,4 +17,7 @@ namespace Scheduler void switch_task(Registers* regs); void invoke(Registers* regs); -} \ No newline at end of file +} + +extern "C" void kernel_yield(); +void kernel_sleep(u64 ms); \ No newline at end of file diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index d63e58c4..53e41a21 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -28,6 +28,7 @@ struct Thread : public DoublyLinkedListNode u64 ticks_in_kernel = 0; u64 ticks_left; + u64 sleep_ticks_left; ThreadState state = ThreadState::Runnable;