void do_schedule() { //printk("sched: cur=%x, next=%x, list=%x\n", current_task, current_task->next, task_list); if(current_task) { if(current_task->next) { switch_to_task(current_task->next); } else { switch_to_task(task_list); } } }
/* The scheduler; if possible, switch to the next task in the run queue. Note that the only reason to *ever* call this function is when the current task has suspended itself and needs to actually stop executing. Otherwise just set the `need_resched' flag to TRUE and the scheduler will be called as soon as is safe. Never ever *ever* call this from an interrupt handler! It should be safe to be called from an exception handler though. Also note that there are no `sliding' priority levels; tasks with high priority levels can totally block lower-priority tasks. */ void schedule(void) { u_long flags; save_flags(flags); cli(); #ifdef PARANOID if(intr_nest_count != 0) kprintf("schedule: Oops, being called with intr_nest_count=%d\n", intr_nest_count); #endif /* First reclaim any dead processes.. */ while(zombies) { struct task *zombie = (struct task *)zombie_tasks.head; remove_node(&zombie->node); reclaim_task(zombie); zombies--; } if((current_task->forbid_count > 0) && (current_task->flags & TASK_RUNNING)) { /* Non pre-emptible task. */ load_flags(flags); return; } need_resched = kernel_module.need_resched = FALSE; /* Now do the scheduling.. */ if(current_task->flags & TASK_RUNNING) { /* Task is still runnable so put it onto the end of the run queue (paying attention to priority levels). */ remove_node(¤t_task->node); enqueue_task(&running_tasks, current_task); } if(!list_empty_p(&running_tasks)) { struct task *next = (struct task *)running_tasks.head; if(next->time_left <= 0) next->time_left = next->quantum; if(current_task != next) { current_task->cpu_time += timer_ticks - current_task->last_sched; if(current_task->flags & TASK_ZOMBIE) { append_node(&zombie_tasks, ¤t_task->node); zombies++; } next->sched_count++; next->last_sched = timer_ticks; current_task = next; kernel_module.current_task = next; switch_to_task(next); #if 1 /* Currently we don't handle the math-copro *at all*; clearing this flag simply stops us getting dna exceptions.. */ asm volatile ("clts"); #endif } }