This commit is contained in:
parent
71d2b492ea
commit
6f05feb55f
@ -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();
|
|
@ -31,6 +31,7 @@ void Thread::init_regs_kernel()
|
|||||||
memset(®s, 0, sizeof(Registers));
|
memset(®s, 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)
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
@ -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);
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user