Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12883
  • 博文数量: 9
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 47
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-02 10:18
个人简介

从事SSD Firmware,PCIe SSD Linux管理软件开发

文章分类

全部博文(9)

分类: LINUX

2015-03-04 13:56:36

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!

点击(此处)折叠或打开

  1. #define USEC_TO_HZ_MUL32 U64_C(0x8637bd06)
  2. #define USEC_TO_HZ_ADJ32 U64_C(0x3ffef39085f)
  3. #define USEC_TO_HZ_SHR32 42

  4. unsigned long usecs_to_jiffies(const unsigned int u)
  5. {
  6.     if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) // 防止jiffies溢出
  7.         return MAX_JIFFY_OFFSET;
  8. #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
  9.     return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); // 比jiffies短,而且是整数倍,换算成jiffies,向上取整
  10. #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
  11.     return u * (HZ / USEC_PER_SEC); // 反之
  12. #else
  13.     return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32) // 放大N倍计算除法
  14.         >> USEC_TO_HZ_SHR32;
  15. #endif
  16. }


可以看出,jiffies的精度1ms并达不到微秒级。
阅读(2001) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~