国嵌内核驱动进阶班-5-2(LINUX进程调度)
-
//sched.c(kernel)
-
/*
-
* schedule() is the main scheduler function.
-
*/
-
asmlinkage void __sched schedule(void)
-
{
-
struct task_struct *prev, *next;
-
unsigned long *switch_count;
-
struct rq *rq;
-
int cpu;
-
-
need_resched:
-
preempt_disable();
-
cpu = smp_processor_id();
-
rq = cpu_rq(cpu);
-
rcu_sched_qs(cpu);
-
prev = rq->curr;
-
switch_count = &prev->nivcsw;
-
-
release_kernel_lock(prev);
-
need_resched_nonpreemptible:
-
-
schedule_debug(prev);
-
-
if (sched_feat(HRTICK))
-
hrtick_clear(rq);
-
-
spin_lock_irq(&rq->lock);
-
update_rq_clock(rq);
-
clear_tsk_need_resched(prev);
-
-
if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
-
if (unlikely(signal_pending_state(prev->state, prev)))
-
prev->state = TASK_RUNNING;
-
else
-
deactivate_task(rq, prev, 1);
-
switch_count = &prev->nvcsw;
-
}
-
-
pre_schedule(rq, prev);
-
-
if (unlikely(!rq->nr_running))
-
idle_balance(cpu, rq);
-
-
put_prev_task(rq, prev);
-
next = pick_next_task(rq);
-
-
if (likely(prev != next)) {
-
sched_info_switch(prev, next);
-
perf_event_task_sched_out(prev, next, cpu);
-
-
rq->nr_switches++;
-
rq->curr = next;
-
++*switch_count;
-
-
context_switch(rq, prev, next); /* unlocks the rq */
-
/*
-
* the context switch might have flipped the stack from under
-
* us, hence refresh the local variables.
-
*/
-
cpu = smp_processor_id();
-
rq = cpu_rq(cpu);
-
} else
-
spin_unlock_irq(&rq->lock);
-
-
post_schedule(rq);
-
-
if (unlikely(reacquire_kernel_lock(current) < 0))
-
goto need_resched_nonpreemptible;
-
-
preempt_enable_no_resched();
-
if (need_resched())
-
goto need_resched;
-
}
-
EXPORT_SYMBOL(schedule);
调度只从TASK_RUNNING状态的进程
Preempt vt.
先占;先取;以先买权获得
-
/*
-
* Pick up the highest-prio task:
-
*/
-
static inline struct task_struct *
-
pick_next_task(struct rq *rq)
-
{
-
const struct sched_class *class;
-
struct task_struct *p;
-
-
/*
-
* Optimization: we know that if all tasks are in
-
* the fair class we can call that function directly:
-
*/
-
if (likely(rq->nr_running == rq->cfs.nr_running)) {
-
p = fair_sched_class.pick_next_task(rq);
-
if (likely(p))
-
return p;
-
}
-
-
class = sched_class_highest;
-
for ( ; ; ) {
-
p = class->pick_next_task(rq);
-
if (p)
-
return p;
-
/*
-
* Will never be NULL as the idle class always
-
* returns a non-NULL p:
-
*/
-
class = class->next;
-
}
-
}
阅读(1048) | 评论(0) | 转发(0) |