diff options
Diffstat (limited to 'kernel/l0/thread.c')
-rw-r--r-- | kernel/l0/thread.c | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/kernel/l0/thread.c b/kernel/l0/thread.c index 1a67f6c..bd40cc8 100644 --- a/kernel/l0/thread.c +++ b/kernel/l0/thread.c @@ -99,23 +99,20 @@ void run_scheduler() { } } -static void run_thread(void (*entry)(void*)) { +static void run_thread(void (*entry)(void*), void* data) { ASSERT(current_thread->state == T_STATE_RUNNING); - ASSERT(current_thread->has_result); switch_pagedir(get_kernel_pagedir()); - current_thread->has_result = false; - asm volatile("sti"); - entry(current_thread->result); + entry(data); current_thread->state = T_STATE_FINISHED; // TODO : add job for deleting the thread, or whatever yield(); // expected never to return! ASSERT(false); } -thread_t *new_thread(entry_t entry) { +thread_t *new_thread(entry_t entry, void* data) { thread_t *t = (thread_t*)kmalloc(sizeof(thread_t)); if (t == 0) return 0; @@ -138,13 +135,12 @@ thread_t *new_thread(entry_t entry) { t->stack_region = find_region(stack); t->ctx.esp = (uint32_t*)(t->stack_region->addr + t->stack_region->size); + *(--t->ctx.esp) = (uint32_t)data; // push second argument : data *(--t->ctx.esp) = (uint32_t)entry; // push first argument : entry point *(--t->ctx.esp) = 0; // push invalid return address (the run_thread function never returns) t->ctx.eip = (void(*)())run_thread; - t->state = T_STATE_WAITING; - t->result = 0; - t->has_result = false; + t->state = T_STATE_PAUSED; t->current_pd_d = get_kernel_pagedir(); @@ -165,10 +161,10 @@ void threading_setup(entry_t cont, void* arg) { set_pit_frequency(TASK_SWITCH_FREQUENCY); idt_set_irq_handler(IRQ0, irq0_handler); - thread_t *t = new_thread(cont); + thread_t *t = new_thread(cont, arg); ASSERT(t != 0); - resume_thread_with_result(t, arg, false); + resume_thread(t, false); run_scheduler(); // never returns ASSERT(false); @@ -182,35 +178,25 @@ void yield() { if (current_thread == 0) { // might happen before threading is initialized // (but should not...) - dbg_printf("Warning: probable deadlock."); + dbg_printf("Warning: probable deadlock.\n"); } else { save_context_and_enter_scheduler(¤t_thread->ctx); } } -void* wait_for_result() { +void pause() { bool st = disable_interrupts(); - if (!current_thread->has_result) { - current_thread->state = T_STATE_WAITING; - save_context_and_enter_scheduler(¤t_thread->ctx); - } - ASSERT(current_thread->has_result); - current_thread->has_result = false; - - void *result = current_thread->result; + current_thread->state = T_STATE_PAUSED; + save_context_and_enter_scheduler(¤t_thread->ctx); resume_interrupts(st); - return result; } -void resume_thread_with_result(thread_t *thread, void* data, bool run_at_once) { +void resume_thread(thread_t *thread, bool run_at_once) { bool st = disable_interrupts(); - thread->has_result = true; - thread->result = data; - - if (thread->state == T_STATE_WAITING) { + if (thread->state == T_STATE_PAUSED) { thread->state = T_STATE_RUNNING; enqueue_thread(thread, false); } |