Chinaunix首页 | 论坛 | 博客
  • 博客访问: 924457
  • 博文数量: 63
  • 博客积分: 568
  • 博客等级: 中士
  • 技术积分: 3435
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-05 11:44
文章分类
文章存档

2016年(4)

2015年(6)

2014年(3)

2013年(27)

2012年(23)

分类: LINUX

2012-12-02 22:43:57

8. 时钟中断中的调度

时钟中断对于调度系统来说就是一种驱动力。在时钟中断中,调度相关的一些时间计数量会被更新。同时会检查一下目前运行的进程运行时间是不是超过了一个slice,如果超过了这个间隔,就会设置重新调度标记。会在schedule函数中完成调度并完成进程切换。如果没有小于这个slice量,那就不会触发重新调度。为什么这么做呢?因为时钟中断触发频率是很高的,每秒有1000tick,如果一个tick就重新调度一次,那么cpu将忙于进程切换,将大量的cpu白白浪费掉了,所以进程切换的频率必须掌握一个度。

看到这里,我们应该明白时钟中断对于调度的重要性了,如果不是有时钟中断,那么进程切换就都得仰仗进程自己自觉地调度schedule函数了,这是多么不靠谱的事情。这就好比别人占着的茅坑,即便他没有在拉屎,也不知道什么时候能让出来,常言道占着茅坑不拉屎嘛!

wps_clip_image-4139

 
/*
* Preempt the current task with a newly woken task if needed:
*/ 
static void 
check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
{
    unsigned long ideal_runtime, delta_exec;
 
    ideal_runtime = sched_slice(cfs_rq, curr);
    delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
    if (delta_exec > ideal_runtime)
    {
        resched_task(rq_of(cfs_rq)->curr);
        /*
         * The current task ran long enough, ensure it doesn't get
         * re-elected due to buddy favours.
         */ 
        clear_buddies(cfs_rq, curr);
    }
}
 

上面的过程比较简单,需要主要的是ideal_runtime = sched_slice(cfs_rq, curr)这个时间是如何计算出来的呢?大概的公式就是4msec * 进程数目 *进程loadrunqueue总共的load的比重。目测一下,一个进程被调度一次的持续运行的时间(ideal time)也就是4msec左右。

 
/*
* The idea is to set a period in which each task runs once.
*
* When there are too many tasks (sysctl_sched_nr_latency) we have to stretch
* this period because otherwise the slices get too small.
*
* p = (nr <= nl) ? l : l*nr/nl
*/ 
static u64 __sched_period(unsigned long nr_running)
{
    u64 period = sysctl_sched_latency;
    unsigned long nr_latency = sched_nr_latency;
 
    if (unlikely(nr_running > nr_latency))
    {
        period = sysctl_sched_min_granularity;
        period *= nr_running;
    }
 
    return period;
}
 

阅读(3042) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~