更新时间片 -- scheduler_tick()
2012-09-08 15:00
225 查看
时钟中断处理程序中会调用函数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);
}
相关文章推荐
- Linux2.6内核进程调度系列--scheduler_tick()函数2.更新实时进程的时间片
- Linux2.6内核进程调度系列--scheduler_tick()函数3.更新普通进程的时间片
- MOOON-scheduler设计图更新
- vue nextTick深入理解-vue性能优化、DOM更新时机、事件循环机制
- Quartz Scheduler 更新任务触发器
- Linux2.6内核进程调度系列--scheduler_tick()函数1.总体思想
- Linux核心调度器之周期性调度器scheduler_tick--Linux进程的管理与调度(十八)
- Linux2.6内核进程调度系列2.更新实时进程的时间片
- Linux2.6内核进程调度系列3.更新普通进程的时间片
- vue nextTick深入理解-vue性能优化、DOM更新时机、事件循环机制
- scheduler_tick函数详解
- solr定时更新索引遇到的问题(SolrDataImportProperties Error loading DataImportScheduler properties java.lang.NullPointerException)
- vue nextTick深入理解---vue性能优化、DOM更新时机、事件循环机制
- scheduler_tick函数详解
- buy tickrt(线段树)单点更新应用变形
- sql server 的自定义split函数,用户更新纯真ip的startip和endip
- QuickPager asp.net 分页控件、表单控件等自定义控件下载 和介绍 【2009.05.15更新】
- linux常用命令(持续更新中)
- Eclipse不完全操作手册(自用 不定期更新)
- 秦时明月之万里长城下载(更新中)