Linux内核分析之软定时器笔记
定时器是一种软件功能,即允许在将来的某个时刻,函数在给定的时间间隔用完时被调用。超时表示与定时器相关的时间间隔已经用完的那个时刻。
linux上考虑两种类型的定时器,即动态定时和间隔定时器。第一种类型由内核使用,而间隔定时器由进程在用户态创建。
动态定时器
动态定时的主要数据结构是一个叫做tvec_bases的per cpu变量,他包含NR_CPUS个元素,系统中每个CPU都有一个。每个元素是一个tvec_base_t类型的数据结构,他包含相应CPU中处理动态定时器需要的所有数据。
- struct tvec_base {
- spinlock_t lock;
- struct timer_list *running_timer;
- unsigned long timer_jiffies;
- unsigned long next_timer;
- struct tvec_root tv1;
- struct tvec tv2;
- struct tvec tv3;
- struct tvec tv4;
- struct tvec tv5;
- } ____cacheline_aligned;
字段tv1的数据解雇为tvec_root_t类型,包含一个vec数组,这个数组由256个list_head元素组成(即256个动态定时器链表组成)。这个结构包含了在紧接着到来的255个节拍内将要到期的所有动态定时器。
字段tv2,tv3和tv4的数据结构都是tvec_t类型,该类型有一个数组vec。这些链表包含在紧接着到来的2^14-1/2^20-1以及2^26-1个节拍内将要到期的所有动态定时器。
字段tv5与前面的字段几乎相同,但唯一区别就是vec数组的最后一项是一个大expires字段值得动态定时器链表。tv5从不需要从其他的数组补充。
动态定时器编程
1,申请timer_list结构并对其初始化,其中必须初始化的有expires,function
- struct timer_list {
- struct list_head entry;
- unsigned long expires;
- void (*function)(unsigned long);
- unsigned long data;
- struct tvec_base *base;
- #ifdef CONFIG_TIMER_STATS
- void *start_site;
- char start_comm[16];
- int start_pid;
- #endif
- #ifdef CONFIG_LOCKDEP
- struct lockdep_map lockdep_map;
- #endif
- };
2,调用init_timer函数初始化
该函数最终调用下面函数
- static void __init_timer(struct timer_list *timer,
- const char *name,
- struct lock_class_key *key)
- {
- timer->entry.next = NULL;
- timer->base = __raw_get_cpu_var(tvec_bases);
- #ifdef CONFIG_TIMER_STATS
- timer->start_site = NULL;
- timer->start_pid = -1;
- memset(timer->start_comm, 0, TASK_COMM_LEN);
- #endif
- lockdep_init_map(&timer->lockdep_map, name, key, 0);
- }
可看到初始化的几个相关变量。
相关推荐
IT之家 2020-03-11
graseed 2020-10-28
zbkyumlei 2020-10-12
SXIAOYI 2020-09-16
jinhao 2020-09-07
impress 2020-08-26
liuqipao 2020-07-07
淡风wisdon大大 2020-06-06
yoohsummer 2020-06-01
chenjia00 2020-05-29
baike 2020-05-19
扭来不叫牛奶 2020-05-08
hxmilyy 2020-05-11
黎豆子 2020-05-07
xiongweiwei00 2020-04-29
Cypress 2020-04-25
冰蝶 2020-04-20