Linux 内核使用全局变量 jiffies 来记录系统从启动以来的系统节拍数,系统启动的时候会将 jiffies 初始化为 0,jiffies 定义在文include/linux/jiffies.h 中,定义如下:
extern u64 __jiffy_data jiffies_64; // 64位的jiffies_64
extern unsigned long volatile __jiffy_data jiffies; // 32位的jiffies
当我们访问 jiffies 的时候其实访问的是 jiffies_64 的低 32 位,使用 get_jiffies_64 这个函数可以获取 jiffies_64 的值。
在 32 位的系统上读取 jiffies 的值。
在 64 位的系统上 jiffes 和 jiffies_64表示同一个变量,因此也可以直接读取 jiffies 的值。所以不管是 32 位的系统还是 64 位系统,都可以使用jiffies。
HZ 表示每秒的节拍数,jiffies 表示系统运行的 jiffies 节拍数,所以 jiffies/HZ 就是系统运行时间,单位为秒。
当我们希望时间延时10毫秒的时候,就可以写成:
timeout = jiffies + HZ * 10 / 1000;
// 忙等待10毫秒,占用CPU的一个核心,期间不执行调度
while(time_before(jiffies,timeout)) {
}
不管是 32 位还是 64 位的 jiffies,都有溢出的风险,溢出以后会重新从 0 开始计数,相当于绕回来了,因此有些资料也将这个现象也叫做绕回。
假如 HZ 为最大值 1000 的时候:
32 位的 jiffies 只需要 4294967295(0xFFFFFFFF)/1000/3600/24 = 49.7 天就发生了绕回
对于 64 为的 jiffies 来说大概需要5.8 亿年才能绕回,因此 jiffies_64 的绕回忽略不计。
处理 32 位 jiffies 的绕回显得尤为重要,