周期性调度器scheduler_tick
周期性调度器由中断实现,系统定时产生一个中断,然后启动周期性调度器,周期性调度器执行过程中要关闭中断, 周期性调度器执行完毕后再打开中断(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的更多相关文章
- Linux CFS调度器之task_tick_fair处理周期性调度器--Linux进程的管理与调度(二十九)
1. CFS如何处理周期性调度器 周期性调度器的工作由scheduler_tick函数完成(定义在kernel/sched/core.c, line 2910), 在scheduler_tick中周期 ...
- Linux核心调度器之周期性调度器scheduler_tick--Linux进程的管理与调度(十八)
我们前面提到linux有两种方法激活调度器:核心调度器和 周期调度器 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测是否有必要 因 ...
- 调度器的实现、schedule、switch_context、switch_to
根据<深入Linux内核架构>和Linux-3.10.1内核源码,记一些调度过程的主体工作. 调度器任务:CPU数目比要运行的进程数目少,需要程序之间共享CPU时间,创造并行执行的错觉.分 ...
- Linux进程核心调度器之主调度器schedule--Linux进程的管理与调度(十九)
主调度器 在内核中的许多地方, 如果要将CPU分配给与当前活动进程不同的另一个进程, 都会直接调用主调度器函数schedule, 从系统调用返回后, 内核也会检查当前进程是否设置了重调度标志TLF_N ...
- linux cfs调度器
在抽象模型中vruntime决定了进程被调度的先后顺序,在真实模型中决定被调度的先后顺序的参数是由函数entity_key决定的. static inline s64 entity_key(str ...
- linux cfs调度器_模型实现
调度器真实模型的主要成员变量及与抽象模型的对应关系 I.cfs_rq结构体 a) struct sched_entity *curr 指向当前正在执行的可调度实体.调度器的调度单位 ...
- linux cfs调度器_理论模型
参考资料:<调度器笔记>Kevin.Liu <Linux kernel development> <深入Linux内核架构> version: 2.6.32.9 下 ...
- 第一次作业:基于Linux 4.5的进程模型与调度器分析
1.操作系统是怎么组织进程的? 1.1什么是线程,什么是进程: 刚接触时可能经常会将这两个东西搞混.简单一点的说,进程是一个大工程,线程则是这个大工程中每个小地方需要做的东西(在linux下看作&qu ...
- Linux进程管理 (2)CFS调度器
关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...
随机推荐
- JAVA-JSP内置对象之application对象
相关资料:<21天学通Java Web开发> application对象1.application对象用来取得和设置Servlet的相关信息.2.application对象的生命周期是从服 ...
- thinkphp继承高级model后的乐观锁运用(测试中)
<?php class IndexAction extends Action { private $d_user; private $user; private $arr; public fun ...
- [note]Why I haven’t quit my corporate job (yet)
Why I haven't quit my corporate job (yet)html, body {overflow-x: initial !important;}html { font-siz ...
- [git]git project仓库迁移
转自:https://segmentfault.com/q/1010000000124379 如果你想从别的 Git 托管服务那里复制一份源代码到新的 Git 托管服务器上的话,可以通过以下步骤来操作 ...
- pthread_mutex_timedlock
函数pthread_mutex_timedlock 当线程试图获取一个已加锁的互斥变量时,pthread_mutex_timedlock互斥量原语允许绑定线程 阻塞的时间.pthread_mutex_ ...
- linux异步IO--aio
简述 linux下异步方式有两种:异步通知和异步IO(AIO),异步通知请参考:linux异步通知 Linux的I/O机制经历了一下几个阶段的演进: 1. 同步阻塞I/O: 用户进程进行I/O操作,一 ...
- js 控制输入文字个数(换行不算)
如题,换行符在textarea中是要当成一个字符的.用普通的maxlength属性就不行了,于是想到通过事件来控制输入文字的长度. 注意哦,回车换行不能算成字符.这样的话,普通的substring等方 ...
- gclient多源码管理工具 DEPS文件
gclient来管理源码的checkout, update等. gclient是google专门为这种多源项目编写的脚本,它可以将多个源码管理系统中的代码放在一起管理.甚至包括将Git和svn代码放在 ...
- SpringMVC深度探险(四) —— SpringMVC核心配置文件详解
在上一篇文章中,我们从DispatcherServlet谈起,最终为读者详细分析了SpringMVC的初始化主线的全部过程.整个初始化主线的研究,其实始终围绕着DispatcherServlet.We ...
- 解决android studio上“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65935”问题
我是在更换应用的一个jar包时发生的这个错误,网上查到说是因为同时在工程中引入了多个第三方jar包,导致调用的方法数超过了android设定的65935个(DEX 64K problem),进而导致d ...