◆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 + 对象2之间包括边缘值)的所有软件时钟
tv2 struct tvec 保存了到期时间从 timer_jiffies + 对象3到 timer_jiffies +对象4之间包括边缘值)的 所有软件时钟
tv3 struct tvec 保存了到期时间从 timer_jiffies +对象5到 timer_jiffies +对象6之间包括边缘值)的所有软件时钟
tv4 struct tvec 保存了到期时间从 timer_jiffies +对象7到 timer_jiffies +对象8之间包括边缘值)的所有软件时钟
tv5 struct tvec 保存了到期时间从 timer_jiffies +对象9到 timer_jiffies +对象10之间包括边缘值)的所有软件时钟

注:一个 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。


相关内容