Linux内部的时钟处理机制全面剖析(1)(4)
2.4 硬件时钟处理过程
由2.3.3可知硬件时钟中断的处理函数保存在静态变量 irq0 中,其定义如清单2-4
单2-4 变量irq0定义 static struct irqaction irq0 = { |
由定义可知:函数 timer_event_interrupt 为时钟中断处理函数,其定义如清单2-5
清单2-5 timer_event_interrupt 函数 static irqreturn_t timer_event_interrupt(int irq, void *dev_id) { add_pda(irq0_irqs, 1); global_clock_event->event_handler(global_clock_event); return IRQ_HANDLED; } |
为了说明这个问题,不妨假设系统中使用的是 hpet 时钟。由2.3.3节可知 global_clock_event 指向 hpet 时钟事件设备 hpet_clockevent )。查看 hpet_enable 函数的代码并没有发现有对 event_handler 成员的赋值。所以继续查看时钟事件设备加入事件的处理函数 tick_notify ,该函数记录了当时钟事件设备发生变化例如,新时钟事件设备的加入)时,执行那些操作参见2.3.1节),代码如清单2-6
清单2-6 tick_notify 函数 static int tick_notify(struct notifier_block *nb, unsigned long reason, void *dev) |
由代码可知:对于新加入时钟事件设备这个事件,将会调用函数 tick_check_new_device 。顺着该函数的调用序列向下查找。tick_set_periodic_handler 函数将时钟事件设备的 event_handler 成员赋值为 tick_handle_periodic 函数的地址。由此可知,函数 tick_handle_periodic 为硬件时钟中断发生时,真正的运行函数。
函数 tick_handle_periodic 的处理过程分成了以下两个部分:
- 全局处理:整个系统中的信息处理
- 局部处理:局部于本地 CPU 的处理
总结一下,一次时钟中断发生后, OS 主要执行的操作 tick_handle_periodic ):
- 全局处理仅在一个 CPU 上运行):
- 更新 jiffies_64
- 更新 xtimer 和当前时钟源信息等
- 根据 tick 计算 avenrun 负载
- 局部处理每个 CPU 都要运行):
- 根据当前在用户态还是核心态,统计当前进程的时间:用户态时间还是核心态时间
- 唤醒 TIMER_SOFTIRQ 软中断
- 唤醒 RCU 软中断
- 调用 scheduler_tick 更新进程时间片等等操作,更多内容参见参考文献)
- profile_tick 函数调用
以上就介绍完了硬件时钟的处理过程,下面来看软件时钟。
评论暂时关闭