Linux内核编程中的计时工具

内核中经常需要把握时间过了多长。这篇文章就是大概介绍一下内核中的计时方法。
jiffies, HZ
Hz物理上的意义是频率的单位,在Linux内核中,HZ是系统计时器频率值的常量,即一秒钟系统计时器增加几次
X86体系架构下,在2.4内核中HZ被默认的设置为100,2.6中是1000,但是2.6.13中却是250. ARM体系架构下,2.6内核中HZ被设置为100.
jiffies是自开机以来系统计时器增加的总次数。所以jiffies的值是与HZ的值直接相关的。
HZ是多少,则jiffies的值每一秒就增加多少。比如说当HZ是100的时候,jiffies的值每一秒就增加100。
有一点注意:jiffies是一个32位无符号整型数。当HZ值是1000的时候,一秒钟增加1000则jiffies会在49.7天这样的时候就溢出了。而一台服务器开启的时间往往会远超于这个时间。所以内核提供了这样一个变量jiffies_64, 这是一个64位无符号整型数。这样就会处理很长很长的时间了。
注意:在32位机上,jiffies_64其实是由两个32位无符号整型数组合起来的,它的低32位部分就是jiffies,这样就造成了读取jiffies_64不是一个原子操作。所以在读取jiffies_64时建议不要直接使用jiffies_64, 而是使用get_jiffies_64()这样一个内核辅助函数。
现在来看在代码中如何使用这个计时工具。
下面的代码判断某一些工作是否在1秒钟之内完成:
unsigned long timeout = jiffies + HZ;
/* ..do something.. */
if(time_after(jiffies, timeout)) /*超过1秒钟*/
下面的代码忙等1秒钟时间:
unsigned long timeout = jiffies + HZ;
while(time_before(jiffies, timeout)) continue;
这样的忙等法当然不好,看下面的代码会让出CPU1秒不执行自己的代码之后再回来继续自己的执行:
unsigned long timeout = jiffies + HZ;
schedule_timeout(timeout);