aboutsummaryrefslogtreecommitdiff
path: root/kernel/l0/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/l0/thread.c')
-rw-r--r--kernel/l0/thread.c40
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(&current_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(&current_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(&current_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);
}