09:26-10:4020p
处理器特定的寄存器
损失可移植性,提高时间精度
获知当前时间
内核一般通过jiffies值来获取当前时间。
驱动程序一般不需要知道墙鈡时间,即年月日时分秒。
有一个内核函数转变一个墙上时钟时间到一个jiffies 值, 是:
#include<linux/time.h>
unsigned long mktime(unsigned int year, unsigned int mon,
unsigned int day, unsigned int hour,
unsigned int min, unsigned int sec);
重复:直接在驱动中处理墙上时钟时间往往是一个在实现策略的信号,并且应当因此而被置疑.
在内核空间中处理绝对时间. 为此,<linux/time.h> 输出了 do_gettimeofday 函数. 当被调用时, 它填充一个 struct timeval 指针 --和在 gettimeofday 系统调用中使用的相同 -- 使用类似的秒和毫秒值. do_gettimeofday 的原型是:
#include <linux/time.h>
void do_gettimeofday(struct timeval *tv);
内核提供了实用函数current_kernel_time:
#include<linux/time.h>
struct timespeccurrent_kernel_time(void);
用来以各种方式获取当前时间的代码
延后执行
比时钟嘀哒长的延时没问题,可以直接利用系统时钟. 每个比时钟滴答还短的延时通常必须使用软件循环来实现。
长延时
忙等待
非常不推荐。因为在忙等待期间,cpu什么也不做,就像死了一样。非常影响性能。
让出处理器
一旦一个进程使用调度来释放处理器, 无法保证进程将于何时拿回处理器。
超时
如果你的驱动使用一个等待队列来等待某些其他事件,但是你也想确保它在一个确定时间段内运行, 可以使用 wait_event_timeout 或者wait_event_interruptible_timeout:
#include<linux/wait.h>
longwait_event_timeout(wait_queue_head_t q, condition, long timeout);
longwait_event_interruptible_timeout(wait_queue_head_t q, condition, long timeout);
短延迟
内核函数 ndelay, udelay, 以及 mdelay 对于短延时好用,它们的原型是:
#include<linux/delay.h>
void ndelay(unsignedlong nsecs);
void udelay(unsignedlong usecs);
void mdelay(unsignedlong msecs);
内核定时器
如果我们需要在将来的某个时间点执行某个动作,同时在改时间点到来之前不想阻塞当前进程,则可以使用内核定时器。
因为内核定时器,不阻塞当前进程,所以类似于持有自旋锁的情形, 你必须遵守下列规则:
- 不允许存取用户空间.
- 不允许使用 current 指针,它在原子态没有意义
- 不能进行休眠或者调度.
通过调用函数in_interrupt(),内核代码能够告知它是否在中断上下文中运行。,
一个和 in_interrupt()相关的函数是 in_atomic(). 调度被禁止时,它的返回值是非零。
定时器是竞态的潜在来源。任何通过定时器函数访问的数据结构都应该针对并发访问而进行保护。
定时器API