Fixing scheduling bug
This commit is contained in:
parent
a7fd9ac224
commit
7706e629c6
2 changed files with 30 additions and 27 deletions
|
|
@ -22,6 +22,7 @@ struct thread {
|
|||
proc_state state;
|
||||
uint16_t pid;
|
||||
struct context *context;
|
||||
char name[8];
|
||||
};
|
||||
|
||||
void scheduler_init();
|
||||
|
|
|
|||
|
|
@ -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->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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue