接下来看一下函数 __run_timers 都作了些什么,如清单3-9
清单3-9 __run_timers函数
static inline void __run_timers(struct tvec_base *base)
{
……
spin_lock_irq(&base->lock);
while (time_after_eq(jiffies, base->timer_jiffies)) {
……
int index = base->timer_jiffies & TVR_MASK;
if (!index &&
(!cascade(base, &base->tv2, INDEX(0))) &&
(!cascade(base, &base->tv3, INDEX(1))) &&
!cascade(base, &base->tv4, INDEX(2)))
cascade(base, &base->tv5, INDEX(3));
++base->timer_jiffies;
list_replace_init(base->tv1.vec + index, &work_list);
while (!list_empty(head)) {
……
timer = list_first_entry(head, struct timer_list,entry);
fn = timer->function;
data = timer->data;
……
set_running_timer(base, timer);
detach_timer(timer, 1);
spin_unlock_irq(&base->lock);
{
int preempt_count = preempt_count();
fn(data);
……
}
spin_lock_irq(&base->lock);
}
}
set_running_timer(base, NULL);
spin_unlock_irq(&base->lock);
}
代码解释:
获得 base 的同步锁
如果 jiffies 大于等于 timer_jiffies (当前正要处理的软件时钟的到期 时间,说明可能有软件时钟到期了),就一直运行3~7,否则跳转至8
计算得到 tv1 的索引,该索引指明当前到期的软件时钟所在 tv1 中的链表 (结构参见3.2节),代码:
int index = base->timer_jiffies & TVR_MASK;
调用 cascade 函数对软件时钟进行必要的调整(稍后会介绍调整的过程)
使得 timer_jiffies 的数值增加1
取出相应的软件时钟链表
遍历该链表,对每个元素进行如下操作
设置当前软件时钟为 base 中正在运行的软件时钟(即保存当前软件时钟到 base-> running_timer 成员中)
将当前软件时钟从链表中删除,即卸载该软件时钟
释放锁,执行软件时钟处理程序
再次获得锁
设置当前 base 中不存在正在运行的软件时钟
释放锁 (编辑:应用网_阳江站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|