diff options
| author | Ada Christine <adachristine18@gmail.com> | 2026-05-23 15:08:09 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2026-05-23 15:08:09 +0000 |
| commit | bcf31cb0ae9edc136de6e6069bfefbd8f144e5d9 (patch) | |
| tree | dbc88987f956b72cae372dce7bfda6f244d10145 /kc/core | |
| parent | 6fbb95277b736e3f271c9586a59a500f2a5ba48a (diff) | |
thread waiting works now
Diffstat (limited to 'kc/core')
| -rw-r--r-- | kc/core/task.c | 111 | ||||
| -rw-r--r-- | kc/core/task.h | 8 |
2 files changed, 90 insertions, 29 deletions
diff --git a/kc/core/task.c b/kc/core/task.c index 9e0e549..5eaa3fb 100644 --- a/kc/core/task.c +++ b/kc/core/task.c @@ -103,6 +103,7 @@ bool thread_queue_any(struct thread_queue queue) static struct thread_queue ready_queue; static struct thread_queue sleep_queue; +static struct thread_queue wait_queue; static volatile atomic_uint_fast64_t preempt_switch_count = 0; static volatile atomic_bool preempt_switch_flag = false; @@ -138,33 +139,9 @@ static void *sleepy_thread_entry(void *p) return nullptr; } -static uint64_t scheduler_flags; -noreturn void task_init(void) -{ - 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(); - kprintf( - "starting task management, timesource delta %luns\n", - timesource->nanoseconds_delta()); - - idle_thread = create_thread(idle_thread_entry, nullptr); - struct kc_thread *sleepy_thread = create_thread(sleepy_thread_entry, (void *)3000000000); - struct kc_thread *sleepy_thread2 = create_thread(sleepy_thread_entry, (void *)5000000000); - thread_queue_push(&ready_queue, sleepy_thread); - thread_queue_push(&ready_queue, sleepy_thread2); - __asm__ volatile ("movq %%rsp, %0" : "=g"(boot_thread.kernel_stack_pointer) :); - thread_queue_push(&ready_queue, 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); -} +static uint64_t scheduler_flags; static inline bool check_preempt_count() { @@ -292,7 +269,6 @@ static void set_thread(struct kc_thread *thread) current_thread->status = RUNNING; arch_swap_thread(previous_thread, current_thread); - } static void block_thread(enum kc_thread_status reason) @@ -394,8 +370,32 @@ static void terminate_action(void *result) union kc_thread_result *result_value = result; current_thread->result = *result_value; current_thread->kernel_stack_pointer = current_thread->kernel_stack_head; - // TODO: wake threads waiting - // TODO: write waitng thread code + + struct thread_queue queue = wait_queue; + + lock_preempt(); + + wait_queue = (struct thread_queue) { nullptr, nullptr }; + + { + struct kc_thread *t; + while((t = thread_queue_pop(&queue)) != nullptr) + { + if (t->wait_target == current_thread) + { + t->wait_target = nullptr; + t->status = READY; + thread_queue_push_back(&ready_queue, t); + } + else + { + thread_queue_push(&wait_queue, t); + } + } + } + + unlock_preempt(); + block_thread(TERMINATED); } @@ -404,3 +404,58 @@ void kct_terminate(union kc_thread_result result) with_locked_scheduler(terminate_action, &result); } +union kc_thread_result kct_wait(struct kc_thread *target) +{ + current_thread->wait_target = target; + thread_queue_push_back(&wait_queue, current_thread); + block_thread(WAITING); + return target->result; +} + +static void *waited_thread_test(void *) +{ + kprintf("worker thread, sleeping for some time...\n"); + sleep_thread(30000000000); + return (void *)1; +} + +static void *waiting_thread_test(void *) +{ + kprintf("waiting thread\n"); + struct kc_thread *t = create_thread(waited_thread_test, nullptr); + t->status = READY; + thread_queue_push_back(&ready_queue, t); + union kc_thread_result r = kct_wait(t); + kprintf("waited thread terminated result: %d\n", r); + return nullptr; +} + +noreturn void task_init(void) +{ + 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(); + kprintf( + "starting task management, timesource delta %luns\n", + timesource->nanoseconds_delta()); + + idle_thread = create_thread(idle_thread_entry, nullptr); + struct kc_thread *sleepy_thread = create_thread(sleepy_thread_entry, (void *)3000000000); + struct kc_thread *sleepy_thread2 = create_thread(sleepy_thread_entry, (void *)5000000000); + struct kc_thread *waiting_thread = create_thread(waiting_thread_test, nullptr); + thread_queue_push(&ready_queue, sleepy_thread); + thread_queue_push(&ready_queue, sleepy_thread2); + thread_queue_push_back(&ready_queue, waiting_thread); + __asm__ volatile ("movq %%rsp, %0" : "=g"(boot_thread.kernel_stack_pointer) :); + thread_queue_push(&ready_queue, 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); +} + + diff --git a/kc/core/task.h b/kc/core/task.h index eae38bb..5d9f39f 100644 --- a/kc/core/task.h +++ b/kc/core/task.h @@ -10,6 +10,7 @@ enum kc_thread_status RUNNING, SLEEPING, BLOCKED, + WAITING, TERMINATED }; @@ -27,10 +28,15 @@ struct kc_thread union kc_thread_result result; enum kc_thread_status status; struct kc_thread *next; - uint64_t sleep_expiration; + union + { + uint64_t sleep_expiration; + struct kc_thread *wait_target; + }; }; void task_init(void); void kct_terminate(union kc_thread_result result); +union kc_thread_result kct_wait(struct kc_thread *target); |
