Linux核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是中断频率。举例来说,HZ为1000,代表每秒有1000次timer interrupts。
Jiffies为Linux核心变数(unsigned long),它被用来记录系统自开机以来,已经过了多少tick。每发生一次timer interrupt,Jiffies变数会被加一。以前的Linux,HZ是100,从2.6.0开始,HZ是1000。所以jiffies增加1的时间是1ms。那么问题来了,如何实现微秒级的延时usecs_to_jiffies呢?
When in doubt, read the code!
-
#define USEC_TO_HZ_MUL32 U64_C(0x8637bd06)
-
#define USEC_TO_HZ_ADJ32 U64_C(0x3ffef39085f)
-
#define USEC_TO_HZ_SHR32 42
-
-
unsigned long usecs_to_jiffies(const unsigned int u)
-
{
-
if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) // 防止jiffies溢出
-
return MAX_JIFFY_OFFSET;
-
#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
-
return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); // 比jiffies短,而且是整数倍,换算成jiffies,向上取整
-
#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
-
return u * (HZ / USEC_PER_SEC); // 反之
-
#else
-
return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32) // 放大N倍计算除法
-
>> USEC_TO_HZ_SHR32;
-
#endif
-
}
可以看出,jiffies的精度1ms并达不到微秒级。
阅读(2100) | 评论(0) | 转发(0) |