Linux内部的时钟处理机制全面剖析(1)(5)
◆3、软件时钟处理
这里所说“软件时钟”指的是软件定时器Software Timers),是一个软件上的概念,是建立在硬件时钟基础之上的。它记录了未来某一时刻要执行的操作函数),并使得当这一时刻真正到来时,这些操作函数)能够被按时执行。举个例子说明:它就像生活中的闹铃,给闹铃设定振铃时间未来的某一时间)后,当时间相当于硬件时钟)更新到这个振铃时间后,闹铃就会振铃。这个振铃时间好比软件时钟的到期时间,振铃这个动作好比软件时钟到期后要执行的函数,而闹铃时间更新好比硬件时钟的更新。
实现软件时钟原理也比较简单:每一次硬件时钟中断到达时,内核更新的 jiffies ,然后将其和软件时钟的到期时间进行比较。如果 jiffies 等于或者大于软件时钟的到期时间,内核就执行软件时钟指定的函数。
接下来的几节会详细介绍 Linux2.6.25 是怎么实现软件时钟的。
3.1 相关数据结构
- struct timer_list :软件时钟,记录了软件时钟的到期时间以及到期后要执行的操作。具体的成员以及含义见表3-1。
- struct tvec_base :用于组织、管理软件时钟的结构。在 SMP 系统中,每个 CPU 有一个。具体的成员以及含义参见表3-2。
表3-1 struct timer_list 主要成员
域名 | 类型 | 描述 |
entry | struct list_head | 所在的链表 |
expires | unsigned long | 到期时间,以 tick 为单位 |
function | void (*)(unsigned long) | 回调函数,到期后执行的操作 |
data | unsigned long | 回调函数的参数 |
base | struct tvec_base * | 记录该软件时钟所在的 struct tvec_base 变量 |
表3-2 struct tvec_base 类型的成员
域名 | 类型 | 描述 |
lock | spinlock_t | 用于同步操作 |
running_timer | struct timer_list * | 正在处理的软件时钟 |
timer_jiffies | unsigned long | 当前正在处理的软件时钟到期时间 |
tv1 | struct tvec_root | 保存了到期时间从 timer_jiffies 到 timer_jiffies + 之间包括边缘值)的所有软件时钟 |
tv2 | struct tvec | 保存了到期时间从 timer_jiffies + 到 timer_jiffies +之间包括边缘值)的 所有软件时钟 |
tv3 | struct tvec | 保存了到期时间从 timer_jiffies +到 timer_jiffies +之间包括边缘值)的所有软件时钟 |
tv4 | struct tvec | 保存了到期时间从 timer_jiffies +到 timer_jiffies +之间包括边缘值)的所有软件时钟 |
tv5 | struct tvec | 保存了到期时间从 timer_jiffies +到 timer_jiffies +之间包括边缘值)的所有软件时钟 |
注:一个 tick 表示的时间长度为两次硬件时钟中断发生时的时间间隔
其中 tv1 的类型为 struct tvec_root ,tv 2~ tv 5的类型为 struct tvec ,清单3-1显示它们的定义清单3-1 struct tvec_root 和 struct tvec 的定义
struct tvec { struct list_head vec[TVN_SIZE]; }; struct tvec_root { struct list_head vec[TVR_SIZE]; } |
可见它们实际上就是类型为 struct list_head 的数组,其中 TVN_SIZE 和 TVR_SIZE 在系统没有配置宏 CONFIG_BASE_SMALL 时分别被定义为64和256。
评论暂时关闭