/*
* 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)) { //如果nr_running==cfs.nr_running,则说明当前rq队列中是没有rt任务的,
//rt任务不在cfs队列中,它的优先级的设置和cfs不一样。
p = fair_sched_class.pick_next_task(rq); //在cfs队列中挑选即将被切换进去的进程,核心函数,我们下文会详细讲解。
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 */
}
当CPU中没有rt任务时,那么从cfs队列中挑选合适的进程以待切换进CPU,因为是cfs调度类,所以最终调度的函数是pick_next_task_fair:
来看一下pick_next_entity:static struct task_struct *pick_next_task_fair(struct rq *rq) { struct task_struct *p; struct cfs_rq *cfs_rq = &rq->cfs; struct sched_entity *se; if (!cfs_rq->nr_running) return NULL; do { se = pick_next_entity(cfs_rq); //挑选下一个调度实体,详解见下文 set_next_entity(cfs_rq, se); // cfs_rq = group_cfs_rq(se); } while (cfs_rq); //如果被调度的进程仍属于当前组,那么选取下一个可能被调度的任务,以保证组间调度的公平性??? p = task_of(se); hrtick_start_fair(rq, p); return p; }
/* * Pick the next process, keeping these things in mind, in this order: * 1) keep things fair between processes/task groups 1. 首先要确保任务组之间的公平,这也是设置组的原因之一; * 2) pick the "next" process, since someone really wants that to run 2. 其次,挑选下一个合适的(优先级比较高的)进程,因为它确实需要马上运行; * 3) pick the "last" process, for cache locality 3. 如果没有找到条件2中的进程,那么为了保持良好的局部性,则选中上一次执行的进程; * 4) do not run the "skip" process, if something else is available 4. 只要有任务存在,就不要让CPU空转,也就是让CPU运行idle进程。 */ static struct sched_entity *pick_next_entity(st