From edc42358664e9d70227e274273321ab032394a7e Mon Sep 17 00:00:00 2001 From: Ada Christine Date: Wed, 20 May 2026 23:04:06 +0000 Subject: new thread code works fine --- kc/core/task.c | 122 +++++++++++++++++++++------------------------------------ 1 file changed, 44 insertions(+), 78 deletions(-) (limited to 'kc/core/task.c') diff --git a/kc/core/task.c b/kc/core/task.c index 3e0288d..aa5d179 100644 --- a/kc/core/task.c +++ b/kc/core/task.c @@ -14,9 +14,7 @@ #include #include -static const size_t INTERRUPT_STACK_SIZE = 4096; -static const size_t THREAD_SIZE = 16834; -static const enum vm_alloc_flags ALLOC_FLAGS = VM_ALLOC_ANY|VM_ALLOC_ANONYMOUS; +#include "arch_thread.h" extern uint64_t *get_tss_rsp0(void); @@ -27,7 +25,7 @@ static void unlock_preempt(void); static void update_time(void); -static struct kc_thread *create_thread(void (*thread_entry)(void)); +static struct kc_thread *create_thread(void *(*thread_f)(void *), void *p); static void destroy_thread(struct kc_thread *thread); static void set_thread(struct kc_thread *thread); static void block_thread(enum kc_thread_status reason); @@ -57,24 +55,26 @@ static struct kc_thread *sleeping_threads; static volatile atomic_uint_fast64_t preempt_switch_count = 0; static volatile atomic_bool preempt_switch_flag = false; -static void idle_thread_entry(void) +static void *idle_thread_entry(void *) { kprintf("idle thread started\n"); - unlock_scheduler(); - - __asm__ ("sti"); + __asm__ ("sti"); + + while (true) { __asm__ ("hlt;"); } + + return nullptr; } #define PS2INPUT 0x60 #define PS2STATUS 0x64 #define PS2STATUS_IBF 0x1 -static void keyboard_input_loop(void) +static void keyboard_input_loop() { bool has_bytes = true; while (has_bytes) @@ -91,7 +91,7 @@ static void keyboard_input_loop(void) } } -static void sleepy_thread_entry(void) +static void *sleepy_thread_entry(void *) { int thread_slept_count = 0; @@ -99,22 +99,21 @@ static void sleepy_thread_entry(void) { sleep_thread(1000000000); thread_slept_count++; - //keyboard_input_loop(); + keyboard_input_loop(); } (void)thread_slept_count; + return nullptr; } -static void create_interrupt_stack(size_t size) -{ - char *rsp0 = vm_alloc(size, ALLOC_FLAGS); - memset(rsp0, 0, size); - *get_tss_rsp0() = (uintptr_t)rsp0 + size; -} +static uint64_t scheduler_flags; noreturn void task_init(void) { - lock_scheduler(); + struct kc_thread boot_thread; + boot_thread.status = RUNNING; + current_thread = &boot_thread; + timesource = &pit8253_timer_source; timesource->append_callback(sleeping_thread_callback); timesource->start(); @@ -122,21 +121,14 @@ noreturn void task_init(void) "starting task management, timesource delta %luns\n", timesource->nanoseconds_delta()); - // XXX: unfuck this mess at some point - // XXX: make this also not demand-allocated or it's gonna fail - create_interrupt_stack(INTERRUPT_STACK_SIZE); - - // initalize static threads - idle_thread = create_thread(idle_thread_entry); - struct kc_thread *sleepy_thread = create_thread(sleepy_thread_entry); - - current_thread = idle_thread; - ready_thread_push_back(sleepy_thread); - - idle_thread->status = RUNNING; - cpu_set_thread(&idle_thread->state, NULL, get_tss_rsp0()); - + idle_thread = create_thread(idle_thread_entry, nullptr); + struct kc_thread *sleepy_thread = create_thread(sleepy_thread_entry, nullptr); + ready_thread_push(sleepy_thread); + __asm__ volatile ("movq %%rsp, %0" : "=g"(boot_thread.kernel_stack_pointer) :); + ready_thread_push(idle_thread); + block_thread(BLOCKED); // shouldn't ever get here + kprintf("the idle thread exited somehow. we're back in the boot thread. this is not good.\n"); PANIC(DEAD_END); } @@ -173,7 +165,6 @@ void task_schedule(void) } } -static uint64_t scheduler_flags; static void lock_scheduler(void) { @@ -220,42 +211,21 @@ void update_time(void) } } -static struct kc_thread *create_thread(void (*thread_f)(void)) -{ - char *task_bottom = vm_alloc(16384, ALLOC_FLAGS); - struct kc_thread *thread = - (struct kc_thread *)(task_bottom + 16384 - sizeof(*thread)); - - thread->next = NULL; - - thread->time_elapsed = 0; - thread->sleep_expiration = 0; - - thread->state.stack = (uintptr_t)thread; - thread->state.stack_top = *get_tss_rsp0(); - thread->state.page_map = mmu_get_map(); +#define KC_THREAD_SIZE 0x3000 - // set up the expected stack values for the state - struct task_register_state - { - uint64_t rbp; - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t rbx; - uint64_t rip; - } - *register_state = - (struct task_register_state *) - (thread->state.stack -= sizeof(*register_state)); +static struct kc_thread *create_thread(void *(*thread_f)(void *), void *p) +{ + void *buffer = vm_alloc(KC_THREAD_SIZE, VM_ALLOC_ANONYMOUS|VM_ALLOC_ANY); + memset(buffer, 0, KC_THREAD_SIZE); - memset(register_state, 0, sizeof(*register_state)); + uintptr_t stack_head = (uintptr_t)buffer + KC_THREAD_SIZE; + struct kc_thread *thread = (struct kc_thread *)(stack_head -= sizeof(*thread)); - register_state->rip = (uint64_t)thread_f; - register_state->rbp = thread->state.stack; + thread->kernel_stack_head = (void *)stack_head; + thread->kernel_stack_pointer = (void *)stack_head; + thread->status = READY; - thread->status = READY; + arch_create_thread(thread, thread_f, p); return thread; } @@ -282,12 +252,9 @@ static void set_thread(struct kc_thread *thread) ready_thread_push(previous_thread); } - cpu_set_thread( - ¤t_thread->state, - &previous_thread->state, - get_tss_rsp0()); - current_thread->status = RUNNING; + arch_swap_thread(previous_thread, current_thread); + } static void block_thread(enum kc_thread_status reason) @@ -332,8 +299,8 @@ static void sleep_thread_until(uint64_t nanoseconds) return; } -// kprintf("time elapsed is now %ld\r\n", timesource->nanoseconds_elapsed()); -// kprintf("thread will now sleep until %ld\r\n", nanoseconds); + //kprintf("time elapsed is now %ld\r\n", timesource->nanoseconds_elapsed()); + //kprintf("thread will now sleep until %ld\r\n", nanoseconds); current_thread->sleep_expiration = nanoseconds; current_thread->next = sleeping_threads; sleeping_threads = current_thread; @@ -398,7 +365,7 @@ static int sleeping_thread_callback(uint64_t nanoseconds) if (this_thread->sleep_expiration <= nanoseconds) { - //kprintf("thread awakened: %p\n", this_thread); + kprintf("thread awakened: %p\n", this_thread); this_thread->sleep_expiration = 0; unblock_thread(this_thread); } @@ -409,11 +376,10 @@ static int sleeping_thread_callback(uint64_t nanoseconds) } } - unlock_preempt(); - - lock_scheduler(); - task_schedule(); - unlock_scheduler(); + unlock_preempt(); + lock_scheduler(); + task_schedule(); + unlock_scheduler(); return 0; } -- cgit v1.3.1-1-g115d