Linux内核-定时器篇
计算机中的许多活动都是由定时器来进行驱动的,如:每5ms一次的时钟中断、系统时间的更新、软定时器、进行调度中的时间片控制等等。
LInux内核中的内核定时功能主要分为两种:
1、维持系统时间,共time()、gettimeofday()等系统调用和内核使用。
2、维持一个定时器,以便通知内核某一时间间隔已经过去。
硬件定时系统
时钟和定时器的实现依赖于硬件的定时器电路,主要有以下几种:
1、RTC (Real Time Clock)时钟
存在于主板上,独立于CPU和其他电路,由单独的供电器。
RTC会在IRQ8上发出周期性的中断。
Linux只使用RTC获取时间和日期,可以通过对/dev/rtc进行操作,来对RTC进行编程。
2、TSC (Time Stamp Counter)TSC 时间戳计数器
TSC 包含在处理器内部,有一条clk的输入引脚,来记录外部时钟振荡器的周期数,在每个时钟信号到来时+1。
TSC 的值保存在寄存器中,通过汇编 rdtsc 可以获取寄存器的值。
TSC 的增加次数和 CPU频率有关,如果是1GHZ,那么每ns增加一次。
时钟信号的频率由Linux在初始化系统的时候进行确定。
3、PIT (Programmable Interval Timer)可编程间隔定时器
PIT 的作用类似于闹钟,存在于CPU内部,可在一个时间间隔以后发出时钟中断,用来产生系统的时钟中断。
PIT 的时间间隔是固定的,如 1ms。
4、CPU 本地定时器
在 CPU 的本地 APIC 中,还有一种定时测量设备。
CPU 本地定时器 和 PIT 有些区别:
- APIC计数器是32位,PIC是64位,这意味着PIT可以产生频率更低的中断(计数器中存放的是节拍数)。
- APIC的时钟信号基于总线,PIT内部有自己的时钟振荡器。
- APIC只把终端发给自己的CPU,而PIT产生全局性中断(这点在SMP系统中是有区别的)。
5、HPET 高精度事件定时器
Intel和Microsoft开发的新型定时芯片,使用不普遍。
包含8个计数器,每个计数器有自己的时钟信号驱动,是功能更强的硬件定时器。
UP 的计时体系结构
在单处理器系统上,所有与定时有关的活动都由PIT产生的中断触发。
SMP 的计时体系结构
在多处理器系统中,时钟中断源有两种:
- CPU本地定时器的中断,APIC
- 可编程定时器中断,PIT或HPET
PIT或HPET产生的时钟中断称为 全局时钟中断,负责不涉及具体CPU的活动,如:软定时器和系统时间的更新。
APIC产生的本地时钟中断触发涉及本地 CPU的活动:如监视进程的运行时间。
软定时器和延迟函数
定时器是一种软件功能,在未来的某个时刻进行函数的调用。
定时器的实现思路很简单,相关的数据结构中包含一个时刻,在时钟中断到来时,比较时刻 与 当前时刻 jiffies 的大小即可判断定时器是否到达时间。
动态定时器-多级时间轮
动态定时器的实现使用了多级时间轮的数据结构,不详细描述。
对软定时器的处理比较耗时,因此不在时钟中断处理例程中进行处理,而是被延迟到软中断中进行执行,这里是 TIMER_SOFTIRQ。
由于定时器的执行由 softirq 执行,其精度会有一定的影响,执行可能会被延迟几百毫秒。
延迟函数
当内核需要等待一个较短的时间间隔(几毫秒)时使用。
执行指令循环到目标时间。
相关系统调用
time() 和 gettimeofday()
time() 获取从1970.1.1以来的秒数
gettimeofday() 获取从1970.1.1以来的秒数 + 纳秒数
setitimer() 和 alarm()
omit.
Reference
[1] 深入理解LINUX内核