Compare commits

...

2 Commits

Author SHA1 Message Date
751377de0a
Scheduler: Make it possible for a thread to stop existing
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 18:43:34 +01:00
1b92fe36b4
Store the stack inside a thread 2022-12-18 18:43:17 +01:00
5 changed files with 78 additions and 3 deletions

View File

@ -35,7 +35,36 @@ void heap_thread()
CPU::disable_interrupts(); CPU::disable_interrupts();
dump_heap_usage(); dump_heap_usage();
kdbgln("Kernel uses %lu vm pages", KernelVM::used() / ARCH_PAGE_SIZE); kdbgln("Kernel uses %lu vm pages", KernelVM::used() / ARCH_PAGE_SIZE);
while (true) kernel_sleep(UINT64_MAX); kernel_exit();
}
void reap_thread()
{
while (true)
{
CPU::disable_interrupts();
auto dying_threads = Scheduler::check_for_dying_threads();
CPU::enable_interrupts();
if (dying_threads.count())
{
Thread* thread_to_reap = dying_threads.expect_first();
Thread* next_thread = thread_to_reap;
while (thread_to_reap)
{
next_thread = dying_threads.next(thread_to_reap).value_or(nullptr);
kinfoln("reap: reaping thread with id %zu", thread_to_reap->id);
auto stack = thread_to_reap->stack;
kinfoln("deleting thread stack @ %#lx, has %zu bytes of stack", stack.bottom(), stack.bytes());
MemoryManager::unmap_owned_and_free_vm(stack.bottom(), stack.bytes() / ARCH_PAGE_SIZE).release_value();
delete thread_to_reap;
thread_to_reap = next_thread;
}
}
kernel_sleep(250);
}
} }
Result<void> init() Result<void> init()
@ -67,6 +96,7 @@ Result<void> init()
TRY(Scheduler::new_kernel_thread(async_thread)); TRY(Scheduler::new_kernel_thread(async_thread));
TRY(Scheduler::new_kernel_thread(heap_thread)); TRY(Scheduler::new_kernel_thread(heap_thread));
TRY(Scheduler::new_kernel_thread(reap_thread));
CPU::platform_finish_init(); CPU::platform_finish_init();

View File

@ -29,6 +29,8 @@ namespace Scheduler
Stack idle_stack{idle_stack_vm, ARCH_PAGE_SIZE}; Stack idle_stack{idle_stack_vm, ARCH_PAGE_SIZE};
g_idle.set_sp(idle_stack.top()); g_idle.set_sp(idle_stack.top());
g_idle.stack = idle_stack;
kinfoln("CREATED IDLE THREAD: id %lu with ip %lx and sp %lx", g_idle.id, g_idle.ip(), g_idle.sp()); kinfoln("CREATED IDLE THREAD: id %lu with ip %lx and sp %lx", g_idle.id, g_idle.ip(), g_idle.sp());
g_current = &g_idle; g_current = &g_idle;
@ -56,6 +58,8 @@ namespace Scheduler
Stack thread_stack{thread_stack_vm, ARCH_PAGE_SIZE * 4}; Stack thread_stack{thread_stack_vm, ARCH_PAGE_SIZE * 4};
thread->set_sp(thread_stack.top()); thread->set_sp(thread_stack.top());
thread->stack = thread_stack;
g_threads.append(thread); g_threads.append(thread);
kinfoln("CREATED THREAD: id %lu with ip %lx and sp %lx", thread->id, thread->ip(), thread->sp()); kinfoln("CREATED THREAD: id %lu with ip %lx and sp %lx", thread->id, thread->ip(), thread->sp());
@ -163,6 +167,32 @@ namespace Scheduler
if (!g_current->ticks_left) switch_task(regs); if (!g_current->ticks_left) switch_task(regs);
} }
DoublyLinkedList<Thread> check_for_dying_threads()
{
DoublyLinkedList<Thread> result;
Thread* thread_to_remove = nullptr;
g_threads.for_each([&](Thread* thread) {
if (thread_to_remove)
{
g_threads.remove(thread_to_remove);
result.append(thread_to_remove);
}
if (thread->state == ThreadState::Dying) { thread_to_remove = thread; }
else { thread_to_remove = nullptr; }
});
if (thread_to_remove)
{
g_threads.remove(thread_to_remove);
result.append(thread_to_remove);
}
return result;
}
} }
void kernel_sleep(u64 ms) void kernel_sleep(u64 ms)
@ -170,4 +200,11 @@ void kernel_sleep(u64 ms)
g_current->sleep_ticks_left = ms; g_current->sleep_ticks_left = ms;
g_current->state = ThreadState::Sleeping; g_current->state = ThreadState::Sleeping;
kernel_yield(); kernel_yield();
}
[[noreturn]] void kernel_exit()
{
g_current->state = ThreadState::Dying;
kernel_yield();
unreachable();
} }

View File

@ -17,7 +17,10 @@ namespace Scheduler
void switch_task(Registers* regs); void switch_task(Registers* regs);
void invoke(Registers* regs); void invoke(Registers* regs);
DoublyLinkedList<Thread> check_for_dying_threads();
} }
extern "C" void kernel_yield(); extern "C" void kernel_yield();
void kernel_sleep(u64 ms); void kernel_sleep(u64 ms);
[[noreturn]] void kernel_exit();

View File

@ -2,6 +2,7 @@
#include <luna/LinkedList.h> #include <luna/LinkedList.h>
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/Stack.h>
#ifdef ARCH_X86_64 #ifdef ARCH_X86_64
#include "arch/x86_64/CPU.h" #include "arch/x86_64/CPU.h"
@ -13,7 +14,8 @@ enum class ThreadState
{ {
Idle, Idle,
Runnable, Runnable,
Sleeping Sleeping,
Dying
}; };
struct Thread : public DoublyLinkedListNode<Thread> struct Thread : public DoublyLinkedListNode<Thread>
@ -29,6 +31,8 @@ struct Thread : public DoublyLinkedListNode<Thread>
u64 ticks_left; u64 ticks_left;
u64 sleep_ticks_left; u64 sleep_ticks_left;
Stack stack;
ThreadState state = ThreadState::Runnable; ThreadState state = ThreadState::Runnable;
bool is_idle() bool is_idle()

View File

@ -3,6 +3,7 @@
struct Stack struct Stack
{ {
Stack() = default;
Stack(u64 base, usize bytes); Stack(u64 base, usize bytes);
u64 bottom() u64 bottom()