[LDD3速记]_内核定时器

一、用途

用于在未来某个特定的时间点(基于时钟滴答)调度执行某个函数,同时在时间点到来前不会阻塞当前进程。

eg:轮询设备状态、关闭软驱马达


二、特性

1. 是一个数据结构

2. 任务可重新运行(自己注册)

3. 只会在注册自己的处理器上运行

4. 异步执行,故在单处理器系统上,是竞态的潜在来源(定时器访问的数据结构需进行并发访问保护:原子变量或自旋锁)

5. 即使不是抢占式内核,且CPU忙于内核空间,定时器也会在正确的时间到期


三、接口

struct timer_list {
	/* ... */			//未列出字段,以下为公共字段
	unsigned long expires;		//期望定时器执行的jiffies值
	void (*function)(unsigned long);//到达jiffies值时,执行此函数
	unsigned long data;		//参数(参数的数据结构的指针强制转换成ulong格式)
}

使用方法:

1. 初始化:调用init_timer 或 将TIMER_INITIALIZER赋予某个静态结构

2. 修改三个公共字段,然后 add_timer

3. 定时器到期前可禁止:del_timer


其他接口:

int mod_timer(struct timer_list *timer, unsigned long expires);
/* 更新定时器到期时间 */

int del_timer_sync(struct timer_list *timer);
/* 确保返回时无CPU在运行定时器,在SMP系统上避免竞态
   注意:非原子上下文调用时可能会休眠,其他情况会进入忙等待
	 小心在拥有锁时调用
	 确保不发生重新注册(可用一个标志来实现) */

int timer_pending(const struct timer_list * timer);
/* 判断定时器是否在调度运行 */


四、内核实现

        timer_list结构的base字段包含一个指针,指向per-CPU数据结构。该指针告诉我们哪个CPU在运行定时器,若为NULL,则定时器未调度运行。

        注册定时器时(add_timer或mod_timer),最终会由internal_add_timer执行,该函数将新的定时器添加到与当前CPU关联的“级联表”(里面含有一个定时器双向链表)中。

        当__run_timers被激发时,会执行当前定时器滴答上的所有挂起的定时器。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值