linux3.3.7的pick_next_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.h_nr_running)) {
p = fair_sched_class.pick_next_task(rq);
if (likely(p))
return p;
}
for_each_class(class) {
p = class->pick_next_task(rq);
if (p)
return p;
}
BUG(); /* the idle class will always have a runnable task */
}
仔细分析该代码,发现在rq->nr_running==0的时候,并不是最优的代码,fair_sched_class.pick_next_task会被执行两次,stop_sched_class.pick_next_task以及rt_sched_class.pick_next_task会各被执行一次,最后才能执行到idle_sched_class.pick_next_task。那么如何进行优化呢?
static inline struct task_struct *
pick_n