- 1、本文档共4页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
7.1. 测量时间流失
7.1. 测量时间流失
7.1. 测量时间流失
内核通过定时器中断来跟踪时间的流动. 中断在第 10 章详细描述.
定时器中断由系统定时硬件以规律 间隔产⽣; 这个间隔在启动时由内核根据 HZ 值
来编程, HZ 是⼀个体系依赖的值, 在 中定义或者它所包含的⼀个⼦平台⽂件中. 在发布
的内核源码中的缺省值在真实硬件上从 50 到 1200 嘀哒每秒, 在软件模拟器中往下到
24 . ⼤部分平台运⾏在 100 或者 1000 中断每秒; 流⾏的 x86 PC 缺省是 1000 , 尽管它在
以前版本上( 向上直到并且包括 2.4)常常是 100 . 作为⼀个通⽤的规则, 即便如果你知道
HZ 的值, 在编程时你应当从不依赖这个特定值.
可能改变 HZ 的值, 对于那些要系统有⼀个不同的时钟中断频率的⼈. 如果你在头⽂件
中改变 HZ 的值, 你需要使⽤新的值重编译内核和所有的模块. 如果你愿意付出额外的
时间中断的代价来获得你的⽬标, 你可能想提升 HZ 来得到你的异步任务的更细粒度的
精度. 实际上, 提升 HZ 到 1000 在使⽤ 2.4 或 2.2 内核版本的 x86 ⼯业系统中是相当普
遍的. 但是, 对于当前版本, 最好的⽅法是保持 HZ 的缺省值, 由于我们完全信任内核开
发者, 他们肯定已经选择了最好的值. 另外, ⼀些内部计算当前实现为只为从 12 到 1535
范围的 HZ (见 和 RFC-1589) .
每次发⽣⼀个时钟中断, ⼀个内核计数器的值递增. 这个计数器在系统启动时初始化为
0 , 因此它代表从最后⼀次启动以来的时钟嘀哒的数⽬. 这个计数器是⼀个 64-位 变量(
即便在 32-位的体系上)并且称为 jiffies_64 . 但是, 驱动编写者正常 存取 jiffies 变量, ⼀
个 unsi ned lon , 或者和 jiffies_64 是同⼀个或者它的低有效位. 使⽤ jiffies 常常是⾸选,
因为它更快, 并且再所有的体系上存取 64-位的 jiffies_64 值不必要是原⼦的.
除了低精度的内核管理的 jiffy 机制, ⼀些 CPU 平台特有⼀个⾼精度的软件可读的计数
器. 尽管它的实际使⽤有些在各个平台不同, 它有时是⼀个⾮常有⼒的⼯具.
7.1.1. 使⽤ jiffies 计数器
这个计数器和来读取它的实⽤函数位于 , 尽管你会常常只是包含 , 它会⾃动 将
jiffies.h 拉进来. 不⽤说, jiffies 和 jiffies_64 必须当作只读的.
⽆论何时你的代码需要记住当前的 jiffies 值, 可以简单 存取这个 unsi ned lon 变量,
它被声明做 volatile 来告知编译器不要优化内存读. 你需要读取当前的计数器, ⽆论何
时你的代码需要计算⼀个将来的时间戳, 如下⾯例⼦所⽰:
#include linux/jiffies.h
unsigned long j, stamp_1, stamp_half, stamp_n;
j = jiffies; /* read the current alue */
stamp_1 = j + HZ; /* 1 second in the future */
stamp_half = j + HZ/2; /* half a second */
stamp_n = j + n * HZ / 1000; /* n milliseconds */
这个代码对于 jiffies 回绕没有问题, 只要不同的值以正确的⽅式进⾏⽐较. 尽管在 32-
位 平台上当 HZ 是 1000 时, 计数器只是每 50 天回绕⼀次, 你的代码应当准备⾯对这个
事件. 为⽐较你的被缓存的值( 象上⾯的 stamp_ 1 ) 和当前值, 你应当使⽤下⾯⼀个宏定
义:
#include linux/jiffies.h
int time_after(unsigned long a, unsigned long b);
int time_before(unsigned long a, unsigned long b);
int time_after_eq(unsigned long a, unsigned long b);
int time_before_eq(unsigned long a, unsigned long b);
第⼀个当 a, 作为⼀个 jiffies 的快照, 代表 b
文档评论(0)