diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index 882d86b..9e20ad6 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -6,6 +6,7 @@ #include #include #include +#include void thread_function() { @@ -36,9 +37,9 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) debug_ok("Boot \"Complete\"\n"); - new_thread(thread_function); - new_thread(thread_function); - new_thread(thread_function); + ready(new_thread(thread_function)); + ready(new_thread(thread_function)); + ready(new_thread(thread_function)); yield(); PANIC("Reached end of kernel main function\n"); diff --git a/src/kernel/include/scheduler.h b/src/kernel/include/scheduler.h new file mode 100644 index 0000000..6566cd7 --- /dev/null +++ b/src/kernel/include/scheduler.h @@ -0,0 +1,4 @@ +#pragma once + +void ready(struct thread *th); +struct thread *scheduler_next(); diff --git a/src/kernel/include/thread.h b/src/kernel/include/thread.h index df1b6fe..9886517 100644 --- a/src/kernel/include/thread.h +++ b/src/kernel/include/thread.h @@ -7,6 +7,7 @@ struct tcb uintptr_t stack_ptr; uint64_t tid; uint64_t state; + struct thread *next; }; #define TCB_OFFSET (PAGE_SIZE - sizeof(struct tcb)) @@ -31,12 +32,10 @@ struct thread struct tcb tcb; }; -extern struct thread *threads[]; -int current_tid; +struct thread *current_thread; +#define CURRENT_THREAD() (current_thread) -#define CURRENT_THREAD() (threads[current_tid]) - -struct thread *new_thread(void (*function)()); +struct thread *new_thread(void (*function)(void)); void yield(); int get_tid(); diff --git a/src/kernel/proc/scheduler.c b/src/kernel/proc/scheduler.c new file mode 100644 index 0000000..f27bff9 --- /dev/null +++ b/src/kernel/proc/scheduler.c @@ -0,0 +1,26 @@ +#include + +struct { + struct thread *first; + struct thread *last; +} readyQ = {0,0}; + +void ready(struct thread *th) +{ + if(!readyQ.last) + { + th->tcb.next = 0; + readyQ.first = readyQ.last = th; + } else { + readyQ.last->tcb.next = th; + readyQ.last = th; + } +} + +struct thread *scheduler_next() +{ + struct thread *th = readyQ.first; + if(!(readyQ.first = th->tcb.next)) + readyQ.last = 0; + return th; +} diff --git a/src/kernel/proc/thread.c b/src/kernel/proc/thread.c index 7a9957d..52e59c4 100644 --- a/src/kernel/proc/thread.c +++ b/src/kernel/proc/thread.c @@ -1,14 +1,13 @@ #include - -struct thread *threads[8]; -int current_tid = -1; -int tid = 0; +#include struct thread dummy; +struct thread *current_thread = 0; -struct thread *new_thread(void (*function)()) +uint64_t tid = 1; +struct thread *new_thread(void (*function)(void)) { - struct thread *th = threads[tid] = P2V(pmm_alloc()); + struct thread *th = P2V(pmm_alloc()); th->tcb.tid = tid++; th->RBP = (uint64_t)&th->RBP2; @@ -20,22 +19,20 @@ struct thread *new_thread(void (*function)()) void switch_thread(struct thread *old, struct thread *new) { + current_thread = new; swtch(&old->tcb.stack_ptr, &new->tcb.stack_ptr); } void yield() { struct thread *old, *new; - if(current_tid == -1) - old = &dummy; + + old = current_thread; + if(old) + ready(old); else - old = threads[current_tid]; - - current_tid++; - if(current_tid == tid) - current_tid = 0; - - new = threads[current_tid]; + old = &dummy; + while(!(new = scheduler_next())); switch_thread(old, new); }