Beispiel #1
0
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);
		}
	}
}
Beispiel #2
0
/* 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(&current_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, &current_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
	}
    }