1 内核中的时间
内核必须借助硬件提供的系统定时器来管理时间, 系统定时器以某种频率自行触发时钟中断("hitting" or "popping")这个频率可以通过编程确定, 称为节拍率(tick rate)。内核靠计算时钟中断的间隔的方式来计算系统时间和墙上时间
2 节拍率
节拍率通过静态预处理定义, 系统启动时按照定义的节拍率对硬件进行设置(硬件为内核提供了系统定时器), 一些体系结构的节拍率如下所示:
2.1 高频的优劣
高 HZ 的优势:
- 更高的频率意味着更高的精度, 依赖定时执行的系统调用会有更高的精度。例如 poll() select()等会有更高的超时精度, 减少在等待时钟中断上的时间。
- 提高进程抢占的准确性(抢占行为不会在下一个时钟中断到来之前发生)
- 对诸如资源消耗和系统时间测量会有更好的解析度
高 HZ 的劣势:
- 时钟频率越高意味着系统需要花更多的时间来处理时钟中断, 减少了处理其他任务的时间, 频繁打乱处理器高速缓存, 增加系统能耗。
3 jiffies
全局变量jiffies 记录了从系统启动以来的节拍总数, 以无符号长整形存储(unsigned long)。当 jiffies 变量的值超过最大值时就会发生回绕 (wrap around), 内核提供了相应的宏来帮助比较节拍计数而且免除回绕的干扰:
4 时钟中断处理程序
时钟中断处理程序分为两部分 1. 体系相关部分 2. 体系无关部分
1) 体系相关部分作为中断处理程序注册到内核中, 并执行以下操作:
- 获得xtime_lock , 对访问 jiffies 和墙上时间 xtime 进行保护
- 需要时应答或重新设置系统时钟
- 周期性使用墙上时间更新 RTC
- 调用体系无关的时钟例程 tick_periodic()
2) 体系无关部分由 tick_periodic() 函数实现:
- 给 jiffies 变量加一
- 更新资源消耗的统计值
- 执行已经到期的动态定时器, 定时器作为软中断在下半部中执行
- 执行scheduler_tick() 函数
- 更新墙上时间 xtime
- 计算平均负载
tick_periodic() 例程分析 // TODO
5 定时器
定时器可以在设定的超时时间后执行指定的函数, 在超时后自动销毁.
时钟中断处理程序会执行 update_process_times() 函数, 该函数调用 run_local_timers() 函数:
run_timer_softirq() 函数处理软中断, 在当前处理器上运行所有的超时定时器.
所有的定时器以链表形式存放在一起, 按照超时时间分成五组, 尽量减少搜索超时定时器的负担.