周期性调度器由中断实现,系统定时产生一个中断,然后启动周期性调度器,周期性调度器执行过程中要关闭中断, 周期性调度器执行完毕后再打开中断(handle_IRQ_event,  IRQF_DISABLED)

周期性调度器主要做两个工作:
a)更新相关统计量
b)检查进程执行的时间是否超过了它对应的ideal_runtime,如果超过了,则告诉系统,需要启动主调度器(schedule)进行进程切换。(注意thread_info:preempt_count、thread_info:flags (TIF_NEED_RESCHED))

周期性调度器
|---->do_timer() 更新jiffies_64
|---->update_process_times()
|---->scheduler_tick()
|---->update_rq_clock() 更新当前调度队列rq的clock
|---->curr->sched_class->task_tick()
          |         对于普通进程,即task_tick_fair()
| task_struct: struct sched_class *sched_class
update_rq_clock()----delta = sched_clock_cpu(cpu_of(rq)) - rq->clock
|-----两次相邻两次周期性调度器运行的时间差
|----rq->clock += delta; 更新运行队列上的时钟
|---->update_rq_clock_task(rq, delta)
| 即rq->clock_task += delta

普通进程

task_tick_fair()---->entity_tick()   没有考虑组调度
|---->update_curr() 更新相关统计量
|---->check_preempt_tick()
| 检查进程本次获得CPU使用权的执行时间是否超过了
| 它对应的ideal_runtime值,如果超过了,则将当前进
| 程的TIF_NEED_RESCHED标志位置位 update_curr()
  |----delta_exec = (unsigned long)(now - curr->exec_start);
| exec_start当前进程开始获得
| cpu使用权时的时间戳;
| 进程本次所获得的CPU执行权的时间;
|---->__update_curr(cfs_rq, curr, delta_exec);
|---->curr->sum_exec_runtime += delta_exec;
| 更新该进程获得CPU执行权总时间
|
|---->curr->vruntime += delta_exec_weighted;
| 更新该进程获得CPU执行权的虚拟时间
|
|---->update_min_vruntime()
| 更新cfs_rq->min_vruntime
|
|---->curr->exec_start = now
| 更新进程下次运行起始时间
| (如果被抢占,下次被调度时将会更新) check_preempt_tick()
|----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);
| 把当前进程的TIF_NEED_RESCHED标志位置位
|----else
| delta = curr->vruntime - se->vruntime; //这是什么?
| if (delta > ideal_runtime)
| resched_task(rq_of(cfs_rq)->curr);
| 把当前进程的TIF_NEED_RESCHED标志位置位

实时进程

task_tick_rt()
    |---->update_curr_rt();
|---->if (p->policy != SCHED_RR) return; SCHED_FIFO只有主动放弃CPU使用权
|---->rt.timeslice值减一,若没有运行完时间则直接返回,
| 否则再次分配时间片,加入队列尾部,设置TIF_NEED_RESCHED update_curr_rt()
   |----delta_exec = rq->clock - curr->se.exec_start; //本次运行时间
|----curr->se.sum_exec_runtime += delta_exec; //更新总得运行时间
|----curr->se.exec_start = rq->clock; //更新下次进程运行的起始时间
|----if (sched_rt_runtime(rt_rq) != RUNTIME_INF)
|-------{
| rt_rq->rt_time += delta_exec;
| if (sched_rt_runtime_exceeded(rt_rq))
| resched_task(curr);
| }

周期性调度器scheduler_tick的更多相关文章

  1. Linux CFS调度器之task_tick_fair处理周期性调度器--Linux进程的管理与调度(二十九)

    1. CFS如何处理周期性调度器 周期性调度器的工作由scheduler_tick函数完成(定义在kernel/sched/core.c, line 2910), 在scheduler_tick中周期 ...

  2. Linux核心调度器之周期性调度器scheduler_tick--Linux进程的管理与调度(十八)

    我们前面提到linux有两种方法激活调度器:核心调度器和 周期调度器 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测是否有必要 因 ...

  3. 调度器的实现、schedule、switch_context、switch_to

    根据<深入Linux内核架构>和Linux-3.10.1内核源码,记一些调度过程的主体工作. 调度器任务:CPU数目比要运行的进程数目少,需要程序之间共享CPU时间,创造并行执行的错觉.分 ...

  4. Linux进程核心调度器之主调度器schedule--Linux进程的管理与调度(十九)

    主调度器 在内核中的许多地方, 如果要将CPU分配给与当前活动进程不同的另一个进程, 都会直接调用主调度器函数schedule, 从系统调用返回后, 内核也会检查当前进程是否设置了重调度标志TLF_N ...

  5. linux cfs调度器

    在抽象模型中vruntime决定了进程被调度的先后顺序,在真实模型中决定被调度的先后顺序的参数是由函数entity_key决定的.   static inline s64 entity_key(str ...

  6. linux cfs调度器_模型实现

    调度器真实模型的主要成员变量及与抽象模型的对应关系 I.cfs_rq结构体    a) struct sched_entity *curr        指向当前正在执行的可调度实体.调度器的调度单位 ...

  7. linux cfs调度器_理论模型

    参考资料:<调度器笔记>Kevin.Liu <Linux kernel development> <深入Linux内核架构> version: 2.6.32.9 下 ...

  8. 第一次作业:基于Linux 4.5的进程模型与调度器分析

    1.操作系统是怎么组织进程的? 1.1什么是线程,什么是进程: 刚接触时可能经常会将这两个东西搞混.简单一点的说,进程是一个大工程,线程则是这个大工程中每个小地方需要做的东西(在linux下看作&qu ...

  9. Linux进程管理 (2)CFS调度器

    关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...

随机推荐

  1. Node.js学习笔记(4)--简单路由,老师学生id

    说明(2017-5-2 17:57:23): 1. foo.js var http = require("http"); var url = require("url&q ...

  2. struts学习笔记

    ------struts in action 读书笔记 1. ActionServlet:Struts 的ActionServlet控制导航流.当ActionServlet从容器接到一个请求,它使用U ...

  3. 基于HTML5手机上下滑动翻页特效

    基于HTML5手机上下滑动翻页特效.这是一款手机移动端触屏滑动翻页代码下载.效果图如下: 在线预览   源码下载 实现的代码. html代码: <section class="u-al ...

  4. CentOS 7 下安装 Nginx(转)

    转载自:http://www.linuxidc.com/Linux/2016-09/134907.htm 安装所需环境 Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Wi ...

  5. java框架篇---struts实现拦截器

    Struts2的拦截器和Servlet过滤器类似.在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept ...

  6. 腾讯云CentOS升级JDK1.8

    1.查看CentOS自带JDK是否已安装. yum list installed |grep java. 2.卸载原有JDK yum -y remove java-1.5.0-gcj.i686 3.查 ...

  7. 宇宙最强spacemacs

    这个标题背后的潜台词其实是:逼格是什么炼成的? 此处省略一万字. Emacs就不多说了,神之编辑器,但其快捷键实在是....Evil.好啦,现在来了Spacemacs,结合Vim与Emacs二者的优点 ...

  8. git——添加远程库

    添加远程库 阅读: 406682 现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以 ...

  9. String Format for Double [C#]

    转载:http://www.csharp-examples.net/string-format-double/ he following examples show how to format flo ...

  10. winform上控件的拖拽小结

    这里罗列出几个相关的事件和属性,具体的实现介绍已有非常优秀的文章了,文章末尾我将会给出,大家可以去参考. 属性: AllowDrop: 目标控件必须设定为true,才能接受拖拽来的东西. 事件: It ...