时钟中断由定时硬件以周期性的间隔产生,这个间隔由内核根据HZ值设定,HZ是一个与体系结构有关的常数,定义在<linux/param.h>或者该文件包含的某个子平台相关的文件中。
可以通过修改HZ值来改变系统时钟中断发生的频率,但必须重新编译内核以及所有模块。
每次当时钟中断发生时,内核内部计数器的值就增加1,这个计数器的值在系统引导时被初始化为0。这个计数器是64位的,称为jiffies_64,但驱动程序开发者通常访问的是jiffies变量,它是unsigned
long型变量,要么和jiffies_64相同,要和是其低32位。通常首选jiffies,比较快。
使用jiffies计数器
该计数器和读取计数器的工具函数包含在<linux/jiffies.h>中,但通常只需包含<linux/sched.h>后者会自动放入jiffies.h。jiffies和jiffies_64是只读变量。
jiffies快照比较:
#include<linux/jiffies.h>
int
time_after(unsigned long a, unsigned long b); //a比b靠后返回真
int
time_before(unsigned long a, unsigned long b);
int
time_after_eq(unsigned long a, unsgined long b);
int
time_before_eq(unsigned long a, unsigned long b);
这些宏会将计数器值转换为signed
long,相减,然后比较结果。如果需要以安全的方式计算两个jiffies实例的差,也可以使用相同的技巧:
diff=(long)t2-(long)t1;
转换为毫秒值:
msec=diff*1000/HZ;
与用户空间timeval和timespec的转换:
#include<linux/time.h>
unsigned
long timespec_to_jiffies(struct timespec *value);
void
jiffies_to timespec(unsigned long jiffies, struct timespec *value);
unsigned
long timeval_to jiffies(struct timeval *value);
void
jiffies_to_timeval(unsigned long jiffies, struct timeval *value);
在32处理器上访问64位不是原子的,直接读取jiffies_64是很靠不住的。使用:
#include<linux/jiffies.h>
u64
get_jiffies_64(void);
实际的时钟频率对用户空间来讲几乎是完全不可见的。当用户空间程序访问包含param.h,HZ宏始终被拓展为100。要想获得确切值,可以通过/proc/interrupts获得计数值,除以/proc/uptime报告的系统运行时间。