static void update_curr(struct cfs_rq *cfs_rq){
curr->sum_exec_runtime += delta_exec; // (1) 累计当前进程的实际运行时间
schedstat_add(cfs_rq, exec_clock, delta_exec);
curr->vruntime += calc_delta_fair(delta_exec, curr); // (2) 累计当前进程的vruntime
update_min_vruntime(cfs_rq);
}
void scheduler_tick(void)
{
if (!--p->time_slice) { // (1) 时间片用完
dequeue_task(p, rq->active); // (2) 退出actice队列
set_tsk_need_resched(p);
p->prio = effective_prio(p);
p->time_slice = task_timeslice(p);
p->first_time_slice = 0;
if (!rq->expired_timestamp)
rq->expired_timestamp = jiffies;
if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
enqueue_task(p, rq->expired); // (3) 普通进程进入expired队列
if (p->static_prio < rq->best_expired_prio)
rq->best_expired_prio = p->static_prio;
} else
enqueue_task(p, rq->active); // (4) 如果是交互式进程,重新进入active队列
}
}
2. rq->nr_running == 0, cfs_rq和rt_rq下的nr_running一定是0