From a39fdcf3ce137faf900ac69e1ee69f06264eed6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Thu, 29 Mar 2018 12:28:10 +0200 Subject: [PATCH] Adding a scheduler function and cleanup --- src/kernel/boot/kmain.c | 5 +-- src/kernel/include/thread.h | 6 ++-- src/kernel/proc/thread.c | 71 +++++++++++++++++-------------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index 42e2a01..b060e62 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -10,7 +10,7 @@ void thread_function() { - int thread_id = current_thread()->tid; + int thread_id = thread()->tid; while(1) { @@ -40,7 +40,8 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) ready(new_thread(thread_function)); ready(new_thread(thread_function)); ready(new_thread(thread_function)); - yield(); + + start_scheduler(); PANIC("Reached end of kernel main function\n"); for(;;); diff --git a/src/kernel/include/thread.h b/src/kernel/include/thread.h index 0bf316c..397019c 100644 --- a/src/kernel/include/thread.h +++ b/src/kernel/include/thread.h @@ -5,15 +5,17 @@ struct thread { - uintptr_t stack_ptr; uint64_t tid; + void *stack_ptr; uint64_t state; QUEUE_SPOT(runQ); + uint8_t stack[]; }; +struct thread *thread(); struct thread *new_thread(void (*function)(void)); void yield(); -struct thread *current_thread(); +void start_scheduler(); void switch_stack(void *old_ptr, void *new_ptr); diff --git a/src/kernel/proc/thread.c b/src/kernel/proc/thread.c index 21877f9..1e3bd9b 100644 --- a/src/kernel/proc/thread.c +++ b/src/kernel/proc/thread.c @@ -2,12 +2,8 @@ #include #include -#define TCB_OFFSET (PAGE_SIZE - sizeof(struct thread)) -#define SWTCH_STACK_SIZE (0x8*8) - -struct thread_stack +struct swtch_stack { - uint8_t stack[TCB_OFFSET-SWTCH_STACK_SIZE]; uint64_t RBP; uint64_t RBX; uint64_t R12; @@ -16,56 +12,55 @@ struct thread_stack uint64_t R15; uint64_t RBP2; uint64_t ret; - - struct thread tcb; }__attribute__((packed)); -#define thread_stack(th) (struct thread_stack *)((uintptr_t)th - TCB_OFFSET) - -struct thread boot_thread; -struct thread *_current_thread = 0; +struct thread *sched_th = 0; +struct thread *_thread = 0; uint64_t next_tid = 1; struct thread *new_thread(void (*function)(void)) { - struct thread_stack *stk = P2V(pmm_alloc()); - struct thread *th = &stk->tcb; - + struct thread *th = P2V(pmm_calloc()); th->tid = next_tid++; + th->stack_ptr = incptr(th, PAGE_SIZE - sizeof(struct swtch_stack)); + struct swtch_stack *stk = th->stack_ptr; stk->RBP = (uint64_t)&stk->RBP2; stk->ret = (uint64_t)function; - th->stack_ptr = (uint64_t)&stk->RBP; return th; } -struct thread *current_thread() +struct thread *thread() { - return _current_thread; -} - -void set_current_thread(struct thread *th) -{ - _current_thread = th; -} - -void switch_thread(struct thread *old, struct thread *new) -{ - set_current_thread(new); - switch_stack(&old->stack_ptr, &new->stack_ptr); + return _thread; } void yield() { - struct thread *old, *new; - - old = current_thread(); - if(old) - ready(old); - else - old = &boot_thread; - while(!(new = scheduler_next())); - - switch_thread(old, new); + switch_stack(&_thread->stack_ptr, &sched_th->stack_ptr); +} + +void scheduler() +{ + while(1) + { + struct thread *new = 0; + while(!(new = scheduler_next())); + + _thread = new; + switch_stack(&sched_th->stack_ptr, &new->stack_ptr); + + ready(_thread); + _thread = 0; + } +} + +void start_scheduler() +{ + sched_th = new_thread(scheduler); + sched_th->tid = (uint64_t)-1; + + uint64_t stack; + switch_stack(&stack, &sched_th->stack_ptr); }