在Linux单处理器系统中,定时器中断与系统是处于内核模式还是用户模式无关?
当系统处于内核模式时,定时器中断是否有任何不同的行为?
简单的答案是硬件时钟中断服务程序的执行以及动态定时器处理程序的调度都不受硬件时钟中断之前系统所处的模式的影响。 原因在于时钟定时器中断是一个立即服务的硬件中断,无论执行是在内核还是在用户上下文中(假设定时器中断被使能),以及时钟定时器的中断服务程序中断本身会引发运行动态定时器处理程序的软件中断。
警告:1)我没有实际证明这个经验。 2)这不适用于无滴内核或高定时器。
Linux内核代码使用单词“计时器”来表示几个不同的东西:
硬件时钟或滴答定时器
在使用硬件时钟来提供“滴答”的系统上,时钟定时器中断是一种依赖于架构的硬件中断。 例如,在arch / powerpc / kernel / head_booke.h中查找“timer_interrupt”,然后在arch / powerpc / kernel / time.c中查看中断服务程序(ISR) timer_interrupt
实现。 当定时器中断发生时,ISR立即执行,无论当前的执行上下文如何。 这个硬件中断不同于其他硬件中断,因为当它返回时,处理不会返回到前一个上下文。 相反,进入调度程序。
对于每秒钟产生1000个时钟中断的系统,当其他中断服务时,时钟中断有时会被掩盖。 这通常被称为“丢失的蜱”问题。 没有补偿丢失的蜱,一个负载系统可能会有一个缓慢的时间感。 在一些体系结构中,内核通过使用更细粒度的硬件增量计数器来补偿丢失的计时器,其中每个时钟计时器中断读取和记录数值。 通过比较当前时间点的增量计数器值与前一个时间点的增量计数器值,内核可以判断是否已经丢失了时间点。
软件定时器
已经过期的动态定时器的动态定时器处理程序(您用linux/timer.h
设置的类型)的列表在时钟定时器中断结束时设置,在它返回之前。 序列是(近似):
[arch dependent]:timer_interrupt( ) kernel/time/tick-common.c:tick_handle_periodic( ) kernel/time/tick-common.c:tick_periodic( ) kernel/timer.c:update_process_times( ) kernel/timer.c:run_local_timers( ) kernel/softirq.c:raise_softirq(TIMER_SOFTIRQ)
我省略了将timer_interrupt
的处理程序设置为TIMER_SOFTIRQ
的初始化,以及tick_handle_periodic
的处理程序。
调用raise_softirq(TIMER_SOFTIRQ)
生成一个立即被服务的软件中断。 中断的ISR运行动态定时器队列。 定时器处理程序在softirq上下文中运行,并启用硬件中断。 当ISR返回时,调度程序被调用。 这意味着如果设置了很多定时器,那么运行队列中的下一个进程将被延迟。
如果丢失了时钟,那么定时器处理器的执行可能会延迟,但是延迟并不取决于运行时钟定时器中断之前的执行竞争。
关于动态计时器准确度
“…内核不能确保定时器功能在其到期时间开始,只能确保它们在正确的时间或延迟几百毫秒后执行。 了解Linux内核 ,Bovet和Cesati,第3版,O'reilly。
所以,如果你需要更好的定时器精度,你需要使用高分辨率定时器。
参考文献: 软件中断和实时