linux 使用 jiffies 计数器

linux 使用 jiffies 计数器,第1张

概述这个计数器和来读取它的实用函数位于 <linux/jiffies.h>, 尽管你会常常只是包含 <linux/sched.h>, 它会自动地将 jiffies.h 拉进来. 不用说, jiffies 和 jiffies_64 必须当作只读的.   无论何时你的代码需要记住当前的 jiffies 值, 可以简单地存取这个 unsigned long 变 量, 它被声明做 volatile 来告知编译

这个计数器和来读取它的实用函数位于 <linux/jiffIEs.h>,尽管你会常常只是包含

<linux/sched.h>,它会自动地将 jiffIEs.h 拉进来. 不用说,jiffIEs 和 jiffIEs_64 必须当作只读的.

 

无论何时你的代码需要记住当前的 jiffIEs 值,可以简单地存取这个 unsigned long 变 量,它被声明做 volatile 来告知编译器不要优化内存读. 你需要读取当前的计数器,无 论何时你的代码需要计算一个将来的时间戳,如下面例子所示:

 

#include <linux/jiffIEs.h>

unsigned long j,stamp_1,stamp_half,stamp_n;

 

j = jiffIEs; /* read the current value */ 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 之后的一个时间时,取值为真,第二个 当 时间 a 在时间 b 之前时取值为真,以及最后 2 个比较"之后或相同"和"之前或相同". 这个代码工作通过转换这个值为 signed long,减它们,并且比较结果. 如果你需要以一 种安全的方式知道 2 个 jiffIEs 实例之间的差,你可以使用同样的技巧: diff = (long)t2 - (long)t1;.

 

你可以转换一个 jiffIEs 差为毫秒,一般地通过: msec = diff * 1000 / HZ;

有时,但是,你需要与用户空间程序交换时间表示,它们打算使用 struct timeval 和 struct timespec 来表示时间. 这 2 个结构代表一个精确的时间量,使用 2 个成员: seconds 和 microseconds 在旧的流行的 struct timeval 中使用,seconds 和 nanoseconds 在新的 struct timespec 中使用. 内核输出 4 个帮助函数来转换以 jiffIEs 表达的时间值,到和从这些结构:

 

#include <linux/time.h>

unsigned long timespec_to_jiffIEs(struct timespec *value);

voID jiffIEs_to_timespec(unsigned long jiffIEs,struct timespec *value); unsigned long timeval_to_jiffIEs(struct timeval *value);

 

voID jiffIEs_to_timeval(unsigned long jiffIEs,struct timeval *value);

 

存取这个 64-位 jiffy 计数值不象存取 jiffIEs 那样直接. 而在 64-位 计算机体系上,这 2 个变量实际上是一个,存取这个值对于 32-位 处理器不是原子的. 这意味着你可能 读到错误的值如果这个变量的两半在你正在读取它们时被更新. 极不可能你会需要读取这 个 64-位 计数器,但是万一你需要,你会高兴地得知内核输出了一个特别地帮助函数,为你完成正确地加锁:

 

#include <linux/jiffIEs.h> u64 get_jiffIEs_64(voID);

 

在上面的原型中,使用了 u64 类型. 这是一个定义在 <linux/types.h> 中的类型,在 11 章中讨论,并且表示一个 unsigned 64-位 类型.

 

如果你在奇怪 32-位 平台如何同时更新 32-位 和 64-位 计数器,读你的平台的连接脚 本( 查找一个文件,它的名子匹配 valinux*.lds*). 在那里,jiffIEs 符号被定义来存 取这个 64-位 值的低有效字,根据平台是小端或者大端. 实际上,同样的技巧也用在 64-位 平台上,因此这个 unsigned long 和 u64 变量在同一个地址被存取.

 

最后,注意实际的时钟频率几乎完全对用户空间隐藏. 宏 HZ 一直扩展为 100 当用户空 间程序包含 param.h,并且每个报告给用户空间的计数器都对应地被转换. 这应用于 clock(3),times(2),以及任何相关的函数. 对 HZ 值的用户可用的唯一证据是时钟中断 多快发生,如在 /proc/interrupts 所显示的. 例如,你可以获得 HZ,通过用在

/proc/uptime 中报告的系统 uptime 除这个计数值.

总结

以上是内存溢出为你收集整理的linux 使用 jiffies 计数器全部内容,希望文章能够帮你解决linux 使用 jiffies 计数器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1019093.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存