This commit is contained in:
parent
71d2b492ea
commit
6f05feb55f
@ -20,6 +20,4 @@ namespace CPU
|
||||
void enable_interrupts();
|
||||
void disable_interrupts();
|
||||
void wait_for_interrupt();
|
||||
}
|
||||
|
||||
extern "C" void kernel_yield();
|
||||
}
|
@ -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)
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
}
|
@ -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));
|
||||
@ -16,4 +17,7 @@ namespace Scheduler
|
||||
void switch_task(Registers* regs);
|
||||
|
||||
void invoke(Registers* regs);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void kernel_yield();
|
||||
void kernel_sleep(u64 ms);
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user