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;
|
proc_state state;
|
||||||
uint16_t pid;
|
uint16_t pid;
|
||||||
struct context *context;
|
struct context *context;
|
||||||
|
char name[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
void scheduler_init();
|
void scheduler_init();
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <scheduler/sched.h>
|
#include <scheduler/sched.h>
|
||||||
|
|
||||||
extern void switch_context(struct context **old, struct context *new);
|
extern void switch_context(struct context **old, struct context *new);
|
||||||
|
extern void sched_enter(void *a);
|
||||||
|
|
||||||
struct ma_cache *thread_cache;
|
struct ma_cache *thread_cache;
|
||||||
struct thread *idle;
|
struct thread *idle;
|
||||||
|
|
@ -27,30 +28,27 @@ void idle_task(){
|
||||||
|
|
||||||
void test_task(){
|
void test_task(){
|
||||||
kprintf("Hello world from scheduled task!\n");
|
kprintf("Hello world from scheduled task!\n");
|
||||||
//for(;;);
|
for(;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
void best_task(){
|
void best_task(){
|
||||||
kprintf("Hello world I am best\n");
|
kprintf("Hello world I am best\n");
|
||||||
//for(;;);
|
for(;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_exit(){
|
void thread_exit(){
|
||||||
|
asm("cli");
|
||||||
cpu_state *cpu = get_cpu_struct();
|
cpu_state *cpu = get_cpu_struct();
|
||||||
struct thread *p = cpu->current_process;
|
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
|
// If this is the only thread in the queue then set cpu->head to NULL, so scheduler knows to idle
|
||||||
cpu->head = NULL;
|
cpu->head = NULL;
|
||||||
}else{
|
}else{
|
||||||
// Remove process from circular linked list
|
// Remove process from circular linked list
|
||||||
p->next->prev = p->prev;
|
p->next->prev = p->prev;
|
||||||
p->prev->next = p->next;
|
p->prev->next = p->next;
|
||||||
|
cpu->head = p->next;
|
||||||
if(p == cpu->head){
|
|
||||||
//cpu->head = p->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->state = ZOMBIE;
|
p->state = ZOMBIE;
|
||||||
|
|
@ -72,6 +70,7 @@ struct thread *alloc_thread(void){
|
||||||
|
|
||||||
uint64_t *sp = (uint64_t*)((uint64_t)t->kstack + 8 * 4096);
|
uint64_t *sp = (uint64_t*)((uint64_t)t->kstack + 8 * 4096);
|
||||||
|
|
||||||
|
|
||||||
// Push the exit function (the thread will return to it when it finishes)
|
// Push the exit function (the thread will return to it when it finishes)
|
||||||
*--sp = (uint64_t)thread_exit;
|
*--sp = (uint64_t)thread_exit;
|
||||||
|
|
||||||
|
|
@ -115,26 +114,23 @@ struct thread *add_thread(uint64_t *entry){
|
||||||
|
|
||||||
|
|
||||||
[[noreturn]] void sched(){
|
[[noreturn]] void sched(){
|
||||||
|
cpu_state *cpu = get_cpu_struct();
|
||||||
for(;;){
|
for(;;){
|
||||||
asm("cli"); // we sti at the end of switch_context
|
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){
|
struct thread *prev = cpu->current_process;
|
||||||
kprintf("we are freeing allocated thread 0x{x}\n", prev);
|
|
||||||
ma_cache_dealloc(prev);
|
|
||||||
}else{
|
|
||||||
prev->state = READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cpu->head == NULL){
|
if(cpu->head == NULL){
|
||||||
cpu->current_process = idle;
|
cpu->current_process = idle;
|
||||||
}else{
|
}else{
|
||||||
if(prev->next){
|
cpu->current_process = cpu->head;
|
||||||
cpu->current_process = prev->next;
|
cpu->head = cpu->head->next;
|
||||||
}else{
|
}
|
||||||
cpu->current_process = cpu->head;
|
|
||||||
}
|
if(prev->state == ZOMBIE){
|
||||||
|
ma_cache_dealloc(prev);
|
||||||
|
}else{
|
||||||
|
prev->state = READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->current_process->state = RUNNING;
|
cpu->current_process->state = RUNNING;
|
||||||
|
|
@ -153,26 +149,32 @@ void scheduler_init(){
|
||||||
}
|
}
|
||||||
|
|
||||||
idle = alloc_thread();
|
idle = alloc_thread();
|
||||||
idle->context->rip = (uint64_t)idle;
|
idle->context->rip = (uint64_t)idle_task;
|
||||||
|
|
||||||
assert(idle != NULL && "Failed to allocate idle task!");
|
assert(idle != NULL && "Failed to allocate idle task!");
|
||||||
|
|
||||||
cpu->current_process = idle;
|
cpu->current_process = idle;
|
||||||
|
|
||||||
cpu->scheduler_stack = kzalloc(4096);
|
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->rbp = (uint64_t)cpu->scheduler_context;
|
||||||
cpu->scheduler_context->rip = (uint64_t)sched;
|
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()
|
struct thread *t2 = add_thread((uint64_t *)best_task);
|
||||||
cpu->scheduler_initialized = true;
|
memcpy(t2->name, "bestt", 6);
|
||||||
|
|
||||||
|
cpu->scheduler_initialized = true; // Allow us to get interrupts that schedule us
|
||||||
|
|
||||||
|
for(;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void yield(){
|
void yield(){
|
||||||
|
asm("cli");
|
||||||
switch_context(&get_cpu_struct()->current_process->context, get_cpu_struct()->scheduler_context);
|
switch_context(&get_cpu_struct()->current_process->context, get_cpu_struct()->scheduler_context);
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue