Linux 内核定时器 软件意义上的定时器最终依赖硬件定时器实现,内核在时钟中断发生后检测各定时器是否到期,到期后的定时器处理函数将作为软中断在底半部执行。实质上,时钟中断处理程序会唤起 TIMER_SOFTIRQ 软中断,运行当前处理器当上到期的所有定时器。 1. timer_list 在 Linux 内核中,timer_list 结构体的一个实例对应一个定时器,代码如下所示:
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
* same cacheline
*/
struct hlist_node entry;
unsigned long expires; /* 要到达的jiffies */
void (*function)(unsigned long); /* 当定时器期满后,该函数将被执行 */
unsigned long data; /* 上面函数传入的参数 */
u32 flags;
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
定义一个定时器: struct timer_list my_timer; 2. 初始化定时器 (1)初始化定时器使用 init_timer() 函数,它的本质是一个宏,等价于: void init_timer(struct timer_list * timer); (2)初始化定时器还可以使用 TIMER_INITIALIZER(_function, _expires, _data) 宏 (3)定时并初始化定时器:DEFINE_TIMER(_name, _function, _expires, _data) (4)setup_timer() 也可以用于初始化定时器并赋值其成员 3. 增加定时器 void add_timer(struct timer_list * timer); 上述函数用于注册内核定时器,并将定时器加入到内核动态定时器链表中。 4. 删除定时器 int del_timer(struct timer_list * timer); 上述函数用于删除定时器。 注:del_timer_sync() 是 del_timer() 的同步版,在删除一个定时器时需等待期被处理完,因此该函数的调用不能发生在中断上下文中。 5. 修改定时器的 expire int mod_timer(struct timer_list *timer, unsigned long expires); 上述函数用于修改定时器的到期时间,在新的被传入的 expires 到来后才会执行定时器函数。
Linux 内核高精度定时器 Linux 内核支持 tickless 和 NO_HZ 模式后,内核也包含对 hrtimer(高精度定时器)的支持,它可以支持到微妙级别的精度。内核也定义了 hrtimer 结构体,hrtimer_set_expires()、hrtimer_start_expires()、hrtimer_forward_now()、hrtimer_restart() 等类似的 API 来完成 hrtimer 的设置、时间推移以及到期回调。
|