diff --git a/include/scheduler/sched.h b/include/scheduler/sched.h index 975c1a0..4c468f3 100644 --- a/include/scheduler/sched.h +++ b/include/scheduler/sched.h @@ -22,6 +22,7 @@ struct thread { proc_state state; uint16_t pid; struct context *context; + char name[8]; }; void scheduler_init(); diff --git a/src/scheduler/sched.c b/src/scheduler/sched.c index 25dcf24..13551d4 100644 --- a/src/scheduler/sched.c +++ b/src/scheduler/sched.c @@ -11,6 +11,7 @@ #include extern void switch_context(struct context **old, struct context *new); +extern void sched_enter(void *a); struct ma_cache *thread_cache; struct thread *idle; @@ -27,30 +28,27 @@ void idle_task(){ void test_task(){ kprintf("Hello world from scheduled task!\n"); - //for(;;); + for(;;); } void best_task(){ kprintf("Hello world I am best\n"); - //for(;;); + for(;;); } void thread_exit(){ + asm("cli"); cpu_state *cpu = get_cpu_struct(); struct thread *p = cpu->current_process; - if(p == p->next){ + if(p == p->next || p->prev == p){ // If this is the only thread in the queue then set cpu->head to NULL, so scheduler knows to idle cpu->head = NULL; }else{ // Remove process from circular linked list p->next->prev = p->prev; p->prev->next = p->next; - - if(p == cpu->head){ - //cpu->head = p->next; - } - + cpu->head = p->next; } p->state = ZOMBIE; @@ -71,6 +69,7 @@ struct thread *alloc_thread(void){ t->pid = next_pid++; uint64_t *sp = (uint64_t*)((uint64_t)t->kstack + 8 * 4096); + // Push the exit function (the thread will return to it when it finishes) *--sp = (uint64_t)thread_exit; @@ -80,7 +79,7 @@ struct thread *alloc_thread(void){ t->context = (struct context*)sp; t->context->rbp = (uint64_t)sp; - + return t; } @@ -115,28 +114,25 @@ struct thread *add_thread(uint64_t *entry){ [[noreturn]] void sched(){ + cpu_state *cpu = get_cpu_struct(); for(;;){ asm("cli"); // we sti at the end of switch_context - cpu_state *cpu = get_cpu_struct(); + struct thread *prev = cpu->current_process; + if(cpu->head == NULL){ + cpu->current_process = idle; + }else{ + cpu->current_process = cpu->head; + cpu->head = cpu->head->next; + } + if(prev->state == ZOMBIE){ - kprintf("we are freeing allocated thread 0x{x}\n", prev); ma_cache_dealloc(prev); }else{ prev->state = READY; } - if(cpu->head == NULL){ - cpu->current_process = idle; - }else{ - if(prev->next){ - cpu->current_process = prev->next; - }else{ - cpu->current_process = cpu->head; - } - } - cpu->current_process->state = RUNNING; switch_context(&(get_cpu_struct()->scheduler_context), get_cpu_struct()->current_process->context); } @@ -153,26 +149,32 @@ void scheduler_init(){ } idle = alloc_thread(); - idle->context->rip = (uint64_t)idle; + idle->context->rip = (uint64_t)idle_task; assert(idle != NULL && "Failed to allocate idle task!"); cpu->current_process = idle; cpu->scheduler_stack = kzalloc(4096); - cpu->scheduler_context = (struct context*)((uint64_t)cpu->scheduler_stack + 4096); + cpu->scheduler_context = (struct context*)((uint64_t)cpu->scheduler_stack + 4096 - sizeof(struct context)); cpu->scheduler_context->rbp = (uint64_t)cpu->scheduler_context; cpu->scheduler_context->rip = (uint64_t)sched; + + kprintf("og scheduler context: 0x{x}\n", cpu->scheduler_context); - add_thread((uint64_t*)test_task); + struct thread *t1 = add_thread((uint64_t*)test_task); + memcpy(t1->name, "testt", 6); - add_thread((uint64_t *)best_task); + struct thread *t2 = add_thread((uint64_t *)best_task); + memcpy(t2->name, "bestt", 6); - // Initialize scheduler -> we will now get timer interrupts to switch us into sched() - cpu->scheduler_initialized = true; + cpu->scheduler_initialized = true; // Allow us to get interrupts that schedule us + + for(;;); } void yield(){ + asm("cli"); switch_context(&get_cpu_struct()->current_process->context, get_cpu_struct()->scheduler_context); } \ No newline at end of file