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

@ -21,5 +21,3 @@ namespace CPU
void disable_interrupts();
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));
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)

View File

@ -9,24 +9,17 @@
#include <luna/Result.h>
#include <luna/Units.h>
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<void> 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();

View File

@ -39,6 +39,11 @@ namespace Scheduler
return g_current;
}
Thread* idle()
{
return &g_idle;
}
Result<void> 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();
}

View File

@ -6,6 +6,7 @@ namespace Scheduler
void init();
Thread* current();
Thread* idle();
Result<void> new_kernel_thread(u64 address);
Result<void> new_kernel_thread(void (*func)(void));
@ -17,3 +18,6 @@ namespace Scheduler
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_left;
u64 sleep_ticks_left;
ThreadState state = ThreadState::Runnable;