内核通过定时器中断来跟踪时间流。时钟中断由系统定时硬件以周期性的间隔产生,这个间隔由内核根据HZ的值设定,HZ是一个与体系结构有关的常数。
jiffies计数器
头文件<linux/jiffies.h>,通常只需包含<linux/sched.h>。jiffies和jiffies_64应被看为只读变量。
j = jiffies; //读取当前值
j + HZ; //未来的1秒
j + HZ/2; //半秒
j + n * HZ /1000; //n毫秒
比较jiffies缓存值和当前值:
int time_after(unsigned long a, unsigned long b);//a比b的时间靠后,返回真
int time_before(unsigned long a, unsigned long b);//a比b的时间靠前,返回真
int time_after_eq(unsigned long a, unsigned long b);//a比b的时间靠后或相等,返回真
int time_before_eq(unsigned long a, unsigned long b);//a比b的时间靠前或相等,返回真
用户空间的时间表述和内核的表述进行转换:
<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);
对jiffies_64的访问不像对jiffies访问那样直接,在64位处理器上,这两个变量是同一个,但在32位处理器上,对jiffies_64的访问不是原子的。
对jiffies_64的访问:
u64 get_jiffies_64(void);
用户空间获取定时器中断的HZ值:
将/proc/interrupts获得的计数值除以/proc/uptime文件报告的系统运行时间即为HZ值。
计数寄存器
最有名的计数器寄存器就是TSC(时间戳计数器),64位的寄存器,记录CPU的时钟周期数,从内核空间和用户空间都可以读取它:
头文件<asm/msr.h>
rdtsc(low32, high32);//原子性地把64位的数值读到两个32位变量中
rdtscl(low32);//把寄存器的低半部分读到一个32位变量中
rdtscll(var64);//将64位读到一个long long型变量中
与体系结构无关的函数可以代替rdtsc:
头文件<linux/timex.h>
cycles_t get_cycles(void);
在各种平台都可以调用这个函数,在没有时钟周期计数寄存器的平台返回0。