Dirty hack to fix breakage when nothing is running

This commit is contained in:
Kevin Lange 2014-04-04 21:30:14 -07:00
parent 5277e3ce64
commit f8deaed26a
3 changed files with 40 additions and 21 deletions

View File

@ -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 *);

View File

@ -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.
*

View File

@ -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;