全局变量jiffies用来记录自系统启动以来产生的节拍的总数。启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值。一秒内时钟中断的次数等于Hz,所以jiffies一秒内增加的值也就是Hz。

系统运行时间以秒为单位,等于jiffies/Hz。

注意,jiffies类型为无符号长整型(unsigned long),其他任何类型存放它都不正确。

将以秒为单位的时间转化为jiffies:

seconds * Hz

将jiffies转化为以秒为单位的时间:

jiffies / Hz

相比之下,内核中将秒转换为jiffies用的多些。

* jiffies的内部表示

jiffies定义于文件中:

1. /*
2. * The 64-bit value is not atomic - you MUST NOT read it
3. * without sampling the sequence number in xtime_lock.
4. * get_jiffies_64() will do this for you as appropriate.
5. */
6. extern u64 __jiffy_data jiffies_64;
7. extern unsigned long volatile __jiffy_data jiffies;

ld(1)脚本用于连接主内核映像(在x86上位于arch/i386/kernel/vmlinux.lds.S中),然后用jiffies_64变量的初值覆盖jiffies变量。因此jiffies取整个jiffies_64变量的低32位。

访问jiffies的代码只会读取jiffies_64的低32位,通过get_jiffies_64()函数就可以读取整个64位的值。在64位体系结构上,jiffies_64和jiffies指的是同一个变量。

1. #if (BITS_PER_LONG < 64)
2. u64 get_jiffies_64(void);
3. #else
4. static inline u64 get_jiffies_64(void)
5. {
6. return (u64)jiffies;
7. }
8. #endif

1. 在
2. #if (BITS_PER_LONG < 64)
3. u64 get_jiffies_64(void)
4. {
5. unsigned long seq;
6. u64 ret;
7.
8. do {
9. seq = read_seqbegin(&xtime_lock);
10. ret = jiffies_64;
11. } while (read_seqretry(&xtime_lock, seq));
12. return ret;
13. }

* jiffies的回绕wrap around

当jiffies的值超过它的最大存放范围后就会发生溢出。对于32位无符号长整型,最大取值为(2^32)-1,即429496795。如果节拍计数达到了最大值后还要继续增加,它的值就会回绕到0。