LDD3 第7章 Time,Delays and Deferred Work

处理时间委托包括如下任务,按复杂度依次上升:

  • 测量时间流失和比较时间
  • 知道当前时间
  • 指定时间量的延时操作
  • 调度异步函数在之后的时间发生

一、测量时间流失

系统定时硬件规律的产生定时器中断,在内核启动阶段,根据Hz的值,设置这个间隔时间。

HZ的值各不相同,不同平台硬件的参数也不一样,即便你知道HZ的值,在编程时也不应该依赖它。

1.1 使用jiffies计数器

  • 计数器头文件位于<linux/jiffies.h>,但是你更经常使用<linux/sched.h>
  • jiffies和jiffies_64必须是当作只读的

有时代码需要计算一个将来的时间戳,这个代码不用考虑溢出问题:

#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 stamp

有了上面的时间戳,下面是比较函数:

#include <linux/jiffies.h>
int time_after(unsigned long a, unsigned long b);
int time_before(unisgned 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);
time compare

上面的函数其实可以替换为:

diff = (long)t2 - (long)t1;

然后通过转换一个jiffies差为毫秒:

msec = diff * 1000 / HZ
  • 有时内核需要和用户空间交换时间表示,用户空间使用的是struct timeval和struct timespec来表示时间。
#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);
timespec和timeval切换jiffies

在32位系统中,读取64位jiffies有同步的问题,所以内核直接给了函数:

#include <linux/jiffies.h>
u64 get_jiffies_64(void);
获取jiffies_64

1.2  处理器特定的寄存器

如果你要测量时间间隔非常短,或者精度要求非常高,那么放弃移植性

猜你喜欢

转载自www.cnblogs.com/ch122633/p/9635791.html