Fixing scheduling bug

This commit is contained in:
ssimnb 2026-02-20 09:45:49 +01:00
parent a7fd9ac224
commit 7706e629c6
2 changed files with 30 additions and 27 deletions

View file

@ -22,6 +22,7 @@ struct thread {
proc_state state;
uint16_t pid;
struct context *context;
char name[8];
};
void scheduler_init();

View file

@ -11,6 +11,7 @@
#include <scheduler/sched.h>
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;
@ -72,6 +70,7 @@ struct thread *alloc_thread(void){
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;
@ -115,26 +114,23 @@ 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(prev->state == ZOMBIE){
kprintf("we are freeing allocated thread 0x{x}\n", prev);
ma_cache_dealloc(prev);
}else{
prev->state = READY;
}
struct thread *prev = cpu->current_process;
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 = cpu->head;
cpu->head = cpu->head->next;
}
if(prev->state == ZOMBIE){
ma_cache_dealloc(prev);
}else{
prev->state = READY;
}
cpu->current_process->state = RUNNING;
@ -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;
add_thread((uint64_t*)test_task);
kprintf("og scheduler context: 0x{x}\n", cpu->scheduler_context);
add_thread((uint64_t *)best_task);
struct thread *t1 = add_thread((uint64_t*)test_task);
memcpy(t1->name, "testt", 6);
// Initialize scheduler -> we will now get timer interrupts to switch us into sched()
cpu->scheduler_initialized = true;
struct thread *t2 = add_thread((uint64_t *)best_task);
memcpy(t2->name, "bestt", 6);
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);
}