From f8deaed26a1a629ea9f109a3c39ba8724f476c76 Mon Sep 17 00:00:00 2001 From: Kevin Lange Date: Fri, 4 Apr 2014 21:30:14 -0700 Subject: [PATCH] Dirty hack to fix breakage when nothing is running --- kernel/include/process.h | 2 ++ kernel/sys/process.c | 36 ++++++++++++++++++++++++++++++++++++ kernel/sys/task.c | 23 ++--------------------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/kernel/include/process.h b/kernel/include/process.h index 53d7997e..134a396c 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -112,6 +112,7 @@ extern void initialize_process_tree(void); extern process_t * spawn_process(volatile process_t * parent); extern void debug_print_process_tree(void); extern process_t * spawn_init(void); +extern process_t * spawn_kidle(void); extern void set_process_environment(process_t * proc, page_directory_t * directory); extern void make_process_ready(process_t * proc); extern void make_process_reapable(process_t * proc); @@ -131,6 +132,7 @@ extern void wakeup_sleepers(unsigned long seconds, unsigned long subseconds); extern void sleep_until(process_t * process, unsigned long seconds, unsigned long subseconds); extern volatile process_t * current_process; +extern process_t * kernel_idle_task; extern list_t * process_list; typedef void (*tasklet_t) (void *, char *); diff --git a/kernel/sys/process.c b/kernel/sys/process.c index b352a64b..10daaf83 100644 --- a/kernel/sys/process.c +++ b/kernel/sys/process.c @@ -19,6 +19,7 @@ list_t * reap_queue; /* Processes to reap */ list_t * sleep_queue; list_t * recently_reaped; volatile process_t * current_process = NULL; +process_t * kernel_idle_task = NULL; static uint8_t volatile reap_lock; static uint8_t volatile tree_lock; @@ -82,6 +83,9 @@ void debug_print_process_tree(void) { * @return A pointer to the next process in the queue. */ process_t * next_ready_process(void) { + if (!process_available()) { + return kernel_idle_task; + } node_t * np = list_dequeue(process_queue); assert(np && "Ready queue is empty."); process_t * next = np->value; @@ -142,6 +146,38 @@ void delete_process(process_t * proc) { spin_unlock(&tree_lock); } +static void _kidle(void) { + while (1) { + IRQ_RES; + PAUSE; + } +} + +/* + * Spawn the idle "process". + */ +process_t * spawn_kidle(void) { + process_t * idle = malloc(sizeof(process_t)); + memset(idle, 0x00, sizeof(process_t)); + idle->id = -1; + idle->name = strdup("[kidle]"); + idle->is_tasklet = 1; + + idle->image.stack = (uintptr_t)malloc(KERNEL_STACK_SIZE) + KERNEL_STACK_SIZE; + idle->thread.eip = &_kidle; + idle->thread.esp = idle->image.stack; + idle->thread.ebp = idle->image.stack; + + idle->started = 1; + idle->running = 1; + idle->wait_queue = list_create(); + idle->shm_mappings = list_create(); + idle->signal_queue = list_create(); + + set_process_environment(idle, current_directory); + return idle; +} + /* * Spawn the initial process. * diff --git a/kernel/sys/task.c b/kernel/sys/task.c index 36a9f960..c0061f2a 100644 --- a/kernel/sys/task.c +++ b/kernel/sys/task.c @@ -180,6 +180,7 @@ void tasking_install(void) { initialize_process_tree(); /* Spawn the initial process */ current_process = spawn_init(); + kernel_idle_task = spawn_kidle(); /* Initialize the paging environment */ #if 0 set_process_environment((process_t *)current_process, current_directory); @@ -411,20 +412,6 @@ void switch_task(uint8_t reschedule) { /* Tasking is not yet installed. */ return; } - if (!process_available()) { - /* There is no process available in the queue, do not bother switching */ - if (!current_process->running) { - while (1) { - IRQ_RES; - PAUSE; - } - } - if (!reschedule) { - pause_after = 1; - } else { - return; - } - } if (!current_process->running) { switch_next(); } @@ -467,7 +454,7 @@ void switch_task(uint8_t reschedule) { /* Save floating point state */ switch_fpu(); - if (reschedule) { + if (reschedule && current_process != kernel_idle_task) { /* And reinsert it into the ready queue */ make_process_ready((process_t *)current_process); } else if (pause_after) { @@ -490,12 +477,6 @@ void switch_task(uint8_t reschedule) { void switch_next(void) { uintptr_t esp, ebp, eip; /* Get the next available process */ - while (!process_available()) { - /* Uh, no. */ - IRQ_RES; - PAUSE; - return; - } current_process = next_ready_process(); /* Retreive the ESP/EBP/EIP */ eip = current_process->thread.eip;