Add sleeping mechanism
All checks were successful
continuous-integration/drone/pr Build is passing

This commit is contained in:
apio 2022-12-07 15:55:58 +01:00
parent 71d2b492ea
commit 6f05feb55f
Signed by: apio
GPG Key ID: B8A7D06E42258954
6 changed files with 35 additions and 25 deletions

View File

@ -20,6 +20,4 @@ namespace CPU
void enable_interrupts(); void enable_interrupts();
void disable_interrupts(); void disable_interrupts();
void wait_for_interrupt(); void wait_for_interrupt();
} }
extern "C" void kernel_yield();

View File

@ -31,6 +31,7 @@ void Thread::init_regs_kernel()
memset(&regs, 0, sizeof(Registers)); memset(&regs, 0, sizeof(Registers));
regs.cs = 0x08; regs.cs = 0x08;
regs.ss = 0x10; regs.ss = 0x10;
regs.rflags = 1 << 9; // IF (Interrupt enable flag)
} }
void Thread::set_arguments(u64 arg1, u64 arg2, u64 arg3, u64 arg4) void Thread::set_arguments(u64 arg1, u64 arg2, u64 arg3, u64 arg4)

View File

@ -9,24 +9,17 @@
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/Units.h> #include <luna/Units.h>
void print_in_loop() void async_thread()
{ {
while (true) while (true)
{ {
CPU::disable_interrupts(); Thread* current = Scheduler::current();
Serial::printf("%lu", Scheduler::current()->id); kinfoln("Ticks: %lu, %lu user, %lu kernel, %lu idle", current->ticks, current->ticks_in_user,
CPU::enable_interrupts(); current->ticks_in_kernel, Scheduler::idle()->ticks);
}
}
void print_one_and_then_yield() CPU::wait_for_interrupt();
{
while (true) kernel_sleep(1000);
{
CPU::disable_interrupts();
Serial::printf("%lu", Scheduler::current()->id);
kernel_yield();
CPU::enable_interrupts();
} }
} }
@ -52,13 +45,7 @@ Result<void> init()
Scheduler::init(); Scheduler::init();
TRY(Scheduler::new_kernel_thread(print_in_loop)); TRY(Scheduler::new_kernel_thread(async_thread));
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));
CPU::platform_finish_init(); CPU::platform_finish_init();

View File

@ -39,6 +39,11 @@ namespace Scheduler
return g_current; return g_current;
} }
Thread* idle()
{
return &g_idle;
}
Result<void> kernel_thread_alloc_stack_and_append_impl(Thread* thread) Result<void> kernel_thread_alloc_stack_and_append_impl(Thread* thread)
{ {
// FIXME: We will leak the thread if VM allocation or alloc_at fail. // FIXME: We will leak the thread if VM allocation or alloc_at fail.
@ -146,6 +151,20 @@ namespace Scheduler
g_current->ticks_left--; 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); 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();
} }

View File

@ -6,6 +6,7 @@ namespace Scheduler
void init(); void init();
Thread* current(); Thread* current();
Thread* idle();
Result<void> new_kernel_thread(u64 address); Result<void> new_kernel_thread(u64 address);
Result<void> new_kernel_thread(void (*func)(void)); Result<void> new_kernel_thread(void (*func)(void));
@ -16,4 +17,7 @@ namespace Scheduler
void switch_task(Registers* regs); void switch_task(Registers* regs);
void invoke(Registers* regs); void invoke(Registers* regs);
} }
extern "C" void kernel_yield();
void kernel_sleep(u64 ms);

View File

@ -28,6 +28,7 @@ struct Thread : public DoublyLinkedListNode<Thread>
u64 ticks_in_kernel = 0; u64 ticks_in_kernel = 0;
u64 ticks_left; u64 ticks_left;
u64 sleep_ticks_left;
ThreadState state = ThreadState::Runnable; ThreadState state = ThreadState::Runnable;