1、定时器的分析徐骏 王峥嵘 第 1 页 2019/8/71一 概述何为定时器?定时器(timer)是 unix 中提供的一种定时服务的机制。它所起的作用是在某个特定的时间唤醒某个进程来做一些工作。用到定时器的 unix 指令有 sleep, at, etc.在windows 95,windows 98 中也有类似的机制。在硬件中,有一个系统时钟,可以称为硬时钟。同时,linux 还维护一个软件时钟称为软时钟。软时钟使用 jiffies 这个全程变量来维持服务。使用两套时钟的原因是因为硬时钟的读取太麻烦。所消耗的时间太长。Os 通过跟踪软时钟来提供定时服务。并在每次开机时,软时钟读取一次硬时钟,此
2、后各不相关。定时器服务过程简介。定时器的初始化过程在开机时就初始化完毕。 (详细分析见后)要求软件定时服务的进程(如 sleep,at)申请 timer 资源,申请成功后它将它所对应的timer 加入到 timer_list 链表中,并把这个定时器的 timeout 值交给 timer-expires,timer-*fn()对应与该进程的定时服务程序。随着时钟硬中断的发生,timer-expires 越来越小,当 expires time_init 初始化工作setup_x86_irq(0,mark_bh 的作用是将 bh_active 的第 nr 位置位,由前面的讨论可知,它表明 botto
3、m half的 bh_baseTIMER_BH被激活,应立即执行 timer_bh()函数。 timer_bh()函数流程很简单,在 kernel/sched.c 中定义如下:static void timer_bh(void)update_times();run_old_timers();run_timer_list();update_times()重新设置与系统计时所用的一些参数,与定时服务程序没有直接关系,这儿,相关的是 run_old_timers()与 run_timer_list()函数。 if (bh_active extern int del_timer(struct time
4、r_list * timer);extern inline void init_timer(struct timer_list * timer)void mod_timer(struct timer_list *timer, unsigned long expires);extern void it_real_fn(unsigned long);static inline void run_timer_list(void)函数的作用。 Add_timer(),del_timer()的作用就是维护双向链表,负责向链表中加,减,timer. mod_timer(a,b) 是更新一个活动定时器的 e
5、xpire 段的一个更有效的方法(如果该定时器没有活动,它将被激活。 )否则,得用del_timer(a);a-expires = b;add_timer(a)来代替 mod_timer(a,b). Timer_list 在实际中有一个 timer_head定时器的分析徐骏 王峥嵘 第 9 页 2019/8/79The head for the timer-list has a “expires“ field of MAX_UINT,and the sorting routine counts on this.函数的流程1Add_timer()设信号量 flags / save_flags(f
6、lags)关中断 / cli()以 expires 为 keywork 顺序查找。找到位置,向双向链表中加入 timer.释放信号量 flags / restore_flags(flags); 返回。2Del_timer()设信号量 flags / save_flags(flags)关中断 / cli()以 expires 为 keywork 顺序查找。找到位置,在双向链表中删除 timer.释放信号量 flags / restore_flags(flags); 返回。3Init_timer()初始化 timer ,使 timer 的前后指针为 null.4Run_old_timer()在前面
7、的分析中,我提到过 timer_active 的设置。timer_active |= (1expires jiffies 将得到服务的 timer 置为无效,并调用处理程序。 (tp-fn()) 开中断。5Run_timer_list() 进入程序。 关中断 进入 while 循环:如果 timer 存在。/(timer = timer_head.next )!= & timer_head)(如果 head.next 指向 head,说明 timer_list 中没有 timer.)并且 timer 的引发时间到了(timer-expires=jiffies )就为该 timer 的定时服务程
8、序做准备,并且把该 timer 从 timer_list 中删除。 Timer_list 指针下下移一格。 开中 / 为了让定时服务程序 fn(data)执行时。可以响应中断。 调用定时服务程序 fn(data)。 关中断。 / 以便循环 while 退出 while 循环后,关中断并返回。定时器的辅助数据结构及其作用。Bottom_half 机制。Bottom_half 机制是一个中断响应的缓冲机制,当中断服务程序较长时(因为可以由用户指定的处理函数可能会很长。 )就把该服务程序加入缓冲区,在恰当的时间交由 cpu 重新调度。以便中断处理程序可以快速返回。Bottom Half 是一个队列,它最多可保存 32 种不同的 Bottom Half 句柄,它使某些设备驱动程序或者其它的 Linux 内核可以排队保存下来,以待晚些时候执行,下面是 Bottom Half 的数据结构图:bh_base0 Bottom Half handlers31 0bh_active (timers)