Linux 内核定时器

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 的设置、时间推移以及到期回调。

猜你喜欢

转载自blog.csdn.net/linuxweiyh/article/details/79129207