linux 使用 jiffies 计数器
这个计数器和来读取它的实用函数位于 <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简介
在LINUX的时钟中断中涉及至二个全局变量一个是xtime,它是timeval数据结构变量,另一个则是jiffies,首先看timeval结构struct timeval{time_t tv_sec; ...
- linux下jiffies定时器和hrtimer高精度定时器【转】
本文转载自:http://blog.csdn.net/dosculler/article/details/7932315 一.jiffies定时器,HZ=100,精度只能达到10ms. 注:采用jif ...
- Linux内核引用计数器kref结构
1.前言 struct kref结构体是一个引用计数器,它被嵌套进其它的结构体中,记录所嵌套结构的引用计数.引用计数用于检测内核中有多少地方使用了某个对象,每当内核的一个部分需要某个对象所包含的信息时 ...
- linux 时间管理——概念、注意点(一)【转】
转自:http://www.cnblogs.com/openix/p/3324243.html 参考:1.http://bbs.eyeler.com/thread-69-1-1.html ...
- Linux 设备驱动 Edition 3
原文网址:http://oss.org.cn/kernel-book/ldd3/index.html Linux 设备驱动 Edition 3 By Jonathan Corbet, Alessand ...
- Linux内核入门到放弃-时间管理-《深入Linux内核架构》笔记
低分辨率定时器的实现 定时器激活与进程统计 IA-32将timer_interrupt注册为中断处理程序,而AMD64使用的是timer_event_interrupt.这两个函数都通过调用所谓的全局 ...
- Linux 驱动开发
linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...
- 5-3 Linux内核计时、延时函数与内核定时器【转】
转自:http://www.xuebuyuan.com/510594.html 5-3 Linux内核计时.延时函数与内核定时器 计时 1. 内核时钟 1.1 内核通过定时器(timer)中断来跟 ...
- [转载]linux内核中的HZ介绍
时钟中断由系统定时硬件以周期性的间隔产生,这个间隔由内核根据 HZ 值来设定,HZ 是一个体系依赖的值,在 <Linux/param.h>中定义或该文件包含的某个子平台相关文件中.作为通用 ...
随机推荐
- SQLServer数据库(二)
数据库设计:就是将数据库中的数据库实体及这些数据库实体之间的关系,进行规划和结构化的过程. 项目开发过程: 需求分析 概要设计 详细设计 代码编写 运行测试 打包发行 数据库的系统分析基本步骤:收集信 ...
- oracle Transactional
从shutdown transactional命令发布起, 禁止建立任何新的oracle连接. 从shutdown transactional命令发布起,禁止启动任何新的事务. 一旦数据库上所有的活动 ...
- scala2.11读取文件
1.读取行 要读取文件的所有行,可以调用scala.io.Source对象的getLines方法: import scala.io.Source val source = Source.fromFil ...
- 利用IDEA构建springboot应用
前提注意: 1.版本,java 1.8 maven 3.3.9 配置项目 项目版本 项目保存路径 在maven里面的conf里面的settings.xml里配置maven中央仓库 (阿里云) ...
- python 编码和解码
- [转]The Curse of Dimensionality(维数灾难)
原文章地址:维度灾难 - 柳枫的文章 - 知乎 https://zhuanlan.zhihu.com/p/27488363 对于大多数数据,在一维空间或者说是低维空间都是很难完全分割的,但是在高纬空间 ...
- 预警| Confluence 高危漏洞被大规模利用,阿里云WAF接入即可防护,支持免费应急服务
2019年4月4日,阿里云安全应急响应中心监测到Confluence 官方发布安全更新指出,Widget Connector 存在服务端模板注入漏洞,攻击者能利用此漏洞实现目录穿越遍历甚至远程命令执行 ...
- 配置 IO 时要记得换 Page
配置 IO 时要记得换 Page 在配置某些芯片时,配置 IO 时要记得换页,不然不生效. 注意查看 IO 的相关规格书说明,而且每个厂商是不一样的.
- 【批量添加】-拼接sql字符串 标签: 批量添加 2015-12-13 17:49 2070人阅读 评论(33)
现在做的一个项目需要用到批量添加,但是封装的底层没有这个方法,所以自食其力,自己来写.我们用的是拼接sql字符串的方法来实现功能. 具体实现流程:首先将需要的数据存储到实体的list中,然后将这个li ...
- oracle函数 LPAD(c1,n[,c2])
[功能]在字符串c1的左边用字符串c2填充,直到长度为n时为止 [参数]C1 字符串 n 追加后字符总长度 c2 追加字符串,默认为空格 [返回]字符型 [说明]如果c1长度大于n,则返回c1左边n个 ...