Overview
- 高分辨率定时器按时间在一颗红黑数上排序
- 独立于时钟周期,采用纳秒时间戳
数据结构
- 高分辨率时钟可以基于两种时钟:CLOCK_MONOTONIC和CLOCK_REALTIME,前一种是单调递增的,后一种可以发生跳变
- 对于系统中的每个CPU,都提供了一个包含两种时钟基础的数据结构,每个时钟基础都有一个红黑树,来排序所有待处理的高分辨率定时器
stuct hrtimer_cpu_base {
struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES];
#ifdef CONFIG_HIGH_RES_TIMERS
ktime_t expires_next;
int hres_active;
struct list_head cb_pending;
unsigned long nr_events
#endif
}
- HRTIMER_MAX_CLOCK_BASES : 2,对应CLOCK_MONOTONIC和CLOCK_REALTIME
- expires_next : 将要到期的下一个事件的绝对时间
- hres_active : 表示高分辨率模式是否启用
- cb_pengding : 通过软中断HRTIMER_SOFTIRQ处理的定时器
- nr_events : 记录时钟中断的总数
struct hrtimer_clock_base {
struct hrtimer_cpu_base *cpu_base;
clockid_t index;
struct rb_root active;
struct rb_node *first;
ktime_t resolution;
ktime_t (*get_time)(void);
ktime_t (*get_softirq_time)(void);
ktime_t softirq_time;
#ifdef CONFIG_HIGH_RES_TIMERS
ktime_t offset;
int (*reprogram)(struct hrtime *t
struct hrtime_clock_base *b,
ktime_t n);
#endif
}
- hrtimer_cpu_base : 指向该时钟基础所属的per-CPU时钟结构
- index : 区分CLOCK_MONOTONIC和CLOCK_REALTIME
- rb_root : 红黑树根,用来排序活动的定时器
- rb_first : 第一个要到期的定时器
- softirq_time : HRTIMER_SOFTIRQ发出的时间,用来处理高分辨率定时器
- get_time : 读取细粒度时间,对于CLOCK_MONOTONIC直接返回时钟源的值,对于CLOCK_REALTIME需要转换为实际的系统时间
- resolution : 该时钟基础对应时钟源的分辨率
- offest : 在调整实时时钟时,会造成存储在CLOCK_REALTIME时钟基础上的定时器的过期时间和当前实际时间之间的差值
- reprogram : 对给定的定时器事件进行重新编程
struct hrtimer {
struct rb_node node;
ktime_t expires;
enum hrtimer_restart (*function)(struct hrtimer*);
struct hrtimer_clock_base *base;
unsigned long state;
#ifdef CONFIG_HIGH_RES_TIMERS
struct hrtimer_cb_mode cb_mode;
struct list_head cb_entry;
#endif
}
- node : 将定时器链接到时钟基础的红黑树中
- expires : 到期时间
- function : 定时器对应的处理函数
- base : 执行对应的时钟基础: CLOCK_MONOTONIC或者CLOCK_REALTIME
- cb_entry : 将定时器链接到以hrtimer_cpu_base->pending为表头的链表中
- cb_mode
- HRTIMER_CB_SOFTIRQ : 必须中软中断上下文执行
- HRTIMER_CB_IRQSAFE : 可能在硬件中断上下文中执行
- HRTIMER_CB_IRQSAFE_NO_RESTART : 可能在中断上下文执行,不会重启定时器
- HRTIMER_CB_NO_SOFTIRQ : 必须在中断上下文执行
- state :
- HRTIMER_STATE_INACTIVE : 不活动的定时器
- HRTIMER_STATE_ENQUEUED : 在时钟基础上排队,等待到期的定时器
- HRTIMER_STATE_CALLBACK : 正在执行回调的定时器
- HRTIMER_STATE_PENDING : 定时器已经到期,正在回调链表上等待执行
- enum hrtimer_restart
- HRTIMER_NORESTART : 不重启定时器
- HRTIMER_RESTART : 重启定时器
struct hrtimer_sleeper {
struct hrtimer timer;
stuct task_struct *task;
}
- timer : 定时器
- task : 睡眠的进程
API
void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
enum hrtimer_mode mode);
int hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode);
int hrtimer_cancel(struct hrtimer *timer)
int hrtimer_try_to_cancel(struct hrtimer *timer)
int hrtimer_restart(struct hrtimer *timer)
- hrtimer_mode
- HRTIMER_MODE_ABS
- HRTIMER_MODE_REL
实现
- 高分辨率模式下的高分辨率定时器
- 低分辨率模式下的高分辨率定时器
-
切换到高分辨率模式
- hrtimer_run_queues ⇒ tick_check_oneshot_change ⇒ hrtimer_switch_to_hres
⇒ tick_init_highres ⇒ tick_switch_to_oneshot(hrtimer_interrupt) ⇒ dev->event_handler = handler;
- hrtimer_run_queues ⇒ tick_check_oneshot_change ⇒ hrtimer_switch_to_hres
-
周期时钟仿真
- 由tick_setup_sched_timer函数设置,追加一个hrtimer,按照固定时间间隔触发,hrtimer对应的处理函数为:tick_sched_timer