每日阅读1之内核设计与实现(第三版)4.5——linux调度实现之时间记账
来源:互联网 发布:seo排名优化是什么意思 编辑:程序博客网 时间:2024/09/21 06:36
前面讨论CFS调度算法的动机和内在逻辑,下面开始探索CFS是如何实现的。
相关代码位于kernel/sched_fair.c文件中。
主要包含四个组成部分:
(1)时间记账
(2)进程选择
(3)调度器入口
(4)睡眠与唤醒
今天,主要关注时间记账这个部分。。。
所有的调度器都必须对进程的运行时间进行记账,大多数unix系统采用为进程分配一个时间片,每当系统时钟节拍发生时,时间片减少一个节拍周期,当剩余时间片减少到0时,该进程被其它可运行进程抢占。
在现在的CFS调度中,没有了时间片的概念,但是仍然需要进行时间记账,以确保每个进程只在分配给它的处理器时间内运行,CFS使用调度器实体结构struct sched_entity(定义位于linux/sched.h中)来跟踪进程运行记账。。
struct sched_entity {
struct load_weightload; /* for load-balancing */
struct rb_noderun_node;
struct list_headgroup_node;
unsigned int on_rq;
u64 exec_start;
u64 sum_exec_runtime;//虚拟运行时间,以ns为单位,和定时器节拍不在相关
u64 vruntime;
u64 prev_sum_exec_runtime;
u64 last_wakeup;
u64 avg_overlap;
u64 nr_migrations;
u64 start_runtime;
u64 avg_wakeup;
u64 avg_running;
。。。。。。。。。。
}
调度器实体结构,实际上是一个成员变量se,嵌入在进程结构体中。
kernel/sched_fair.c中的update_curr()函数实现vruntime记账功能。
static void update_curr(struct cfs_rq *cfs_rq)
{
struct sched_entity *curr = cfs_rq->curr;
u64 now = rq_of(cfs_rq)->clock_task;
unsigned long delta_exec;
if (unlikely(!curr))
return;
/*
* Get the amount of time the current task was running
* since the last time we changed load (this cannot
* overflow on 32 bits):
*/
delta_exec = (unsigned long)(now - curr->exec_start);//该函数计算当前进程的执行时间,并放在delta_exec变量中,而后将该运行时间传递到__update
if (!delta_exec)
return;
__update_curr(cfs_rq, curr, delta_exec);
curr->exec_start = now;
if (entity_is_task(curr)) {
struct task_struct *curtask = task_of(curr);
trace_sched_stat_runtime(curtask, delta_exec, curr->vruntime);
cpuacct_charge(curtask, delta_exec);
account_group_exec_runtime(curtask, delta_exec);
}
好,一个好的开始,明天接着分析。。。
/*
* Update the current task's runtime statistics. Skip current tasks that
* are not in our scheduling class.
*/
static inline void
__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
unsigned long delta_exec)
{
unsigned long delta_exec_weighted;
schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max));
curr->sum_exec_runtime += delta_exec;
schedstat_add(cfs_rq, exec_clock, delta_exec);
delta_exec_weighted = calc_delta_fair(delta_exec, curr);
curr->vruntime += delta_exec_weighted; //__update_curr进行加权计算(根据可运行进程总数),最终值加入到当前进程的vruntime中去
update_min_vruntime(cfs_rq);
}
update_curr()是由系统定时器周期性调用(中断上下文?),无论进程处于运行态或阻塞态,根据这种方式vruntime可以准确的测定给定进程的运行时间。。
这句话看不懂,这里的系统定时器的工作层次在哪里?
下一节去研究一下,系统定时器。。
欲知后事如何,see U next paper!
- 每日阅读1之内核设计与实现(第三版)4.5——linux调度实现之时间记账
- 每日阅读3之内核设计与实现(第三版)4.5——linux调度实现之进程选择
- 每日阅读4之linux内核设计与实现——linux调度实现之调度器入口
- 每日阅读5之linux内核设计与实现——linux内核调度之睡眠与唤醒
- 每日阅读7之linux内核设计与实现——实时调度与调度系统调用
- 每日阅读6之linux内核设计与实现——抢占与上下文切换
- 每日阅读9之linux内核设计与实现——中断上半部与下半部
- 《linux内核设计与实现》阅读笔记 第三章 调度
- 每日阅读2之linux内核设计与实现11.7.1定时器的使用
- 每日阅读11之内核设计与实现——注册中断处理程序
- 每日月的8之linux内核设计与实现——中断与中断处理
- Linux内核设计与实现之进程调度
- 读书笔记之《Linux内核设计与实现》- 第二次阅读
- 再读《Linux内核设计与实现》之时间管理
- 《Linux内核设计与实现》——进程调度
- 《Linux内核设计与实现》笔记——进程调度
- 每日阅读12内核设计与实现——中断处理程序与中断上下文
- 《Linux内核设计与实现》--进程调度
- Mac10.8 Xcode 开启时没打开上次的项目
- 1328
- python sina 围脖登陆
- sqlserver2008附加数据库附加不上
- 华为C8650+浓颜V系列第二版正式发布,首次基于CM7深度第二次修订,强推~
- 每日阅读1之内核设计与实现(第三版)4.5——linux调度实现之时间记账
- Android的Handler总结
- android 颜色代码 常用RGB值及名称
- PHP学习笔记-数组
- 【linux】grub2
- Matlab画的玫瑰花
- 官方线刷
- 《Windows核心编程 5th》部分读书笔记----第10章 同步设备I/O与异步设备I/O
- 留个爪子,证明自己在学习!