更新時間片 -- scheduler_tick()
時鐘中斷處理程序中會調用函數scheduler_tick():
函數scheduler_tick()更新當前進程的time_slice;並根據time_slice的使用情況(剩餘還是耗盡),來做進一步處理.scheduler_tick( ) Keeps the time_slice counter of current up-to-date
void scheduler_tick(void)
{
int cpu = smp_processor_id();
runqueue_t *rq = this_rq();
task_t *p = current;
unsigned long long now = sched_clock();
update_cpu_clock(p, rq, now);
更新運行隊列的最新時鐘中斷時間戳爲當前時間
|----------------------------------|
| rq->timestamp_last_tick = now; |
|----------------------------------|
如果當前進程爲本地CPU的swapper進程
|-------------------------------------------|
| if (p == rq->idle) { |
| if (wake_priority_sleeper(rq)) |
| goto out; |
| rebalance_tick(cpu, rq, SCHED_IDLE);|
| return; |
| } |
|-------------------------------------------|
如果當前進程不是活躍(active)進程
|---------------------------------|
| if (p->array != rq->active) { |
| set_tsk_need_resched(p); |
| goto out; |
| } |
|---------------------------------|
spin_lock(&rq->lock);
如果當前進程是實時進程;如果調度策略爲SCHED_RR,並且其時間片已經耗盡;爲該進程重新計算時間片;清除first_time_slice域;設置task_struct.thread_info.flags域;將該任務插入其所在活躍隊列的尾部.
|----------------------------------------------------------|
| if (rt_task(p)) { |
| if ((p->policy == SCHED_RR) && !--p->time_slice) { |
| p->time_slice = task_timeslice(p); |
| p->first_time_slice = 0; |
| set_tsk_need_resched(p); |
| requeue_task(p, rq->active); |
| } |
| goto out_unlock; |
| } |
|----------------------------------------------------------|
當前進程爲普通進程,如果其時間片已經耗盡;將該進程從活躍隊列中刪除;設置task_struct.thread_info.flags域;重新計算動態優先級prio;重新計算時間片;清除first_time_slice域;如果過期隊列爲空,將更新 runqueue.expired_timestamp;Inserts the current process either in the active set or in the expired set
|------------------------------------------------------------|
| if (!--p->time_slice) { |
| 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)) { |
| enqueue_task(p, rq->expired); |
| if (p->static_prio < rq->best_expired_prio) |
| rq->best_expired_prio = p->static_prio; |
| } else |
| enqueue_task(p, rq->active); |
|------------------------------------------------------------|
如果時間片沒有耗盡,並且剩餘時間片過長;則將該進程插入其所在隊列的尾部;並設置task_struct.thread_info.flags域
if the time quantum is not exhausted (current->time_slice is not zero), checks whether the remaining time slice of the current process is too long.
|-----------------------------------------------------------------------------|
| } else { |
| 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); |
| } |
| } |
|-----------------------------------------------------------------------------|
out_unlock:
spin_unlock(&rq->lock);
out:
rebalance_tick(cpu, rq, NOT_IDLE);
}
函數scheduler_tick()更新當前進程的time_slice;並根據time_slice的使用情況(剩餘還是耗盡),來做進一步處理.scheduler_tick( ) Keeps the time_slice counter of current up-to-date
void scheduler_tick(void)
{
int cpu = smp_processor_id();
runqueue_t *rq = this_rq();
task_t *p = current;
unsigned long long now = sched_clock();
update_cpu_clock(p, rq, now);
更新運行隊列的最新時鐘中斷時間戳爲當前時間
|----------------------------------|
| rq->timestamp_last_tick = now; |
|----------------------------------|
如果當前進程爲本地CPU的swapper進程
|-------------------------------------------|
| if (p == rq->idle) { |
| if (wake_priority_sleeper(rq)) |
| goto out; |
| rebalance_tick(cpu, rq, SCHED_IDLE);|
| return; |
| } |
|-------------------------------------------|
如果當前進程不是活躍(active)進程
|---------------------------------|
| if (p->array != rq->active) { |
| set_tsk_need_resched(p); |
| goto out; |
| } |
|---------------------------------|
spin_lock(&rq->lock);
如果當前進程是實時進程;如果調度策略爲SCHED_RR,並且其時間片已經耗盡;爲該進程重新計算時間片;清除first_time_slice域;設置task_struct.thread_info.flags域;將該任務插入其所在活躍隊列的尾部.
|----------------------------------------------------------|
| if (rt_task(p)) { |
| if ((p->policy == SCHED_RR) && !--p->time_slice) { |
| p->time_slice = task_timeslice(p); |
| p->first_time_slice = 0; |
| set_tsk_need_resched(p); |
| requeue_task(p, rq->active); |
| } |
| goto out_unlock; |
| } |
|----------------------------------------------------------|
當前進程爲普通進程,如果其時間片已經耗盡;將該進程從活躍隊列中刪除;設置task_struct.thread_info.flags域;重新計算動態優先級prio;重新計算時間片;清除first_time_slice域;如果過期隊列爲空,將更新 runqueue.expired_timestamp;Inserts the current process either in the active set or in the expired set
|------------------------------------------------------------|
| if (!--p->time_slice) { |
| 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)) { |
| enqueue_task(p, rq->expired); |
| if (p->static_prio < rq->best_expired_prio) |
| rq->best_expired_prio = p->static_prio; |
| } else |
| enqueue_task(p, rq->active); |
|------------------------------------------------------------|
如果時間片沒有耗盡,並且剩餘時間片過長;則將該進程插入其所在隊列的尾部;並設置task_struct.thread_info.flags域
if the time quantum is not exhausted (current->time_slice is not zero), checks whether the remaining time slice of the current process is too long.
|-----------------------------------------------------------------------------|
| } else { |
| 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); |
| } |
| } |
|-----------------------------------------------------------------------------|
out_unlock:
spin_unlock(&rq->lock);
out:
rebalance_tick(cpu, rq, NOT_IDLE);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.