2.3.6 O(1)调度器 - 时间分配
/* file: kernel/sched.c */
asmlinkage void __sched schedule(void) {
array = rq->active;
if (unlikely(!array->nr_active)) {
schedstat_inc(rq, sched_switch);
rq->active = rq->expired;
rq->expired = array;
array = rq->active;
rq->expired_timestamp = 0;
rq->best_expired_prio = MAX_PRIO;
}
}/* file: kernel/sched.c */
void scheduler_tick(void) {
/* 拿到当前CPU, 当前CPU 的runqueue, 以及当前正在运行的任务 */
int cpu = smp_processor_id();
runqueue_t *rq = this_rq();
task_t *p = current;
/* 每个tick将任务的运行时间减1, 如果运行时间已经耗尽,则需要单独处理 */
if (!--p->time_slice) {
/* 从 active 列表中剔除,后面根据任务的特点看是放入 active 还是 expired */
dequeue_task(p, rq->active);
/* 标记该任务需要调度了 */
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)) {
/* 非交互式任务,或者是交互式任务,但是已经奖励过了,乖乖到expired列表中去*/
enqueue_task(p, rq->expired);
if (p->static_prio < rq->best_expired_prio)
rq->best_expired_prio = p->static_prio;
} else
/* 交互式任务,奖励一下,继续呆在active中 */
enqueue_task(p, rq->active);
} else {
/* 防止交互式任务过长时间独占CPU */
if (TASK_INTERACTIVE(p) &&
!((task_timeslice(p) - p->time_slice) % TIMESLICE_GRANULARITY(p)) &&
(p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
(p->array == rq->active)) {
requeue_task(p, rq->active);
set_tsk_need_resched(p);
}
}
}Last updated