aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/include/thread.h12
-rw-r--r--kernel/l0/kmain.c4
-rw-r--r--kernel/l0/thread.c40
3 files changed, 20 insertions, 36 deletions
diff --git a/kernel/include/thread.h b/kernel/include/thread.h
index 03277a2..4c5f337 100644
--- a/kernel/include/thread.h
+++ b/kernel/include/thread.h
@@ -5,8 +5,8 @@
#include <region.h>
#define T_STATE_RUNNING 1
-#define T_STATE_FINISHED 2
-#define T_STATE_WAITING 3
+#define T_STATE_PAUSED 2
+#define T_STATE_FINISHED 3
#define KPROC_STACK_SIZE 0x8000 // 8Kb
@@ -22,8 +22,6 @@ typedef struct thread {
pagedir_t *current_pd_d;
uint32_t state;
- void* result;
- bool has_result;
region_info_t *stack_region;
@@ -35,13 +33,13 @@ typedef struct thread {
typedef void (*entry_t)(void*);
void threading_setup(entry_t cont, void* data); // never returns
-thread_t *new_thread(entry_t entry); // thread is PAUSED, and must be resume_thread_with_result'ed
+thread_t *new_thread(entry_t entry, void* data); // thread is PAUSED, and must be resume_thread'ed
extern thread_t *current_thread;
void yield();
-void* wait_for_result();
+void pause();
-void resume_thread_with_result(thread_t *thread, void* data, bool run_at_once);
+void resume_thread(thread_t *thread, bool run_at_once);
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/kernel/l0/kmain.c b/kernel/l0/kmain.c
index f0ce014..826fa14 100644
--- a/kernel/l0/kmain.c
+++ b/kernel/l0/kmain.c
@@ -156,8 +156,8 @@ void kernel_init_stage2(void* data) {
test_hashtbl_1();
test_hashtbl_2();
- thread_t *tb = new_thread(test_thread);
- resume_thread_with_result(tb, 0, false);
+ thread_t *tb = new_thread(test_thread, 0);
+ resume_thread(tb, false);
for (int i = 0; i < 120; i++) {
dbg_printf("a");
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);
}