在Linux单处理器系统中,定时器中断与系统处于内核模式还是用户模式无关?
系统处于内核模式时,定时器中断有什么不同的行为吗?
在Linux单处理器系统中,定时器中断与系统处于内核模式还是用户模式无关?
系统处于内核模式时,定时器中断有什么不同的行为吗?
简单的答案是硬件时钟中断服务程序的执行和动态定时器处理程序的调度都不受硬件时钟中断之前系统所处的模式的影响。原因是时钟定时器中断是一个立即服务的硬件中断,不管执行是在内核还是用户上下文(假设定时器中断是启用的),而时钟定时器中断的中断服务程序它本身会引发运行动态定时器处理程序的软件中断。
警告:1)我实际上并没有通过经验证明这一点。2) 这不适用于无滴答内核或高分辨率计时器。
Linux 内核代码使用“计时器”这个词来表示几个不同的东西:
硬件时钟或滴答计时器
在使用硬件时钟提供“滴答声”的系统上,时钟定时器中断是一个依赖于架构的硬件中断。例如,在arch/powerpc/kernel/head_booke.h中查找“timer_interrupt” ,然后在arch/powerpc/kernel/time.ctimer_interrupt
中查看中断服务例程 (ISR)实现。此 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
to设置处理程序tick_handle_periodic
和为TIMER_SOFTIRQ
.
调用raise_softirq(TIMER_SOFTIRQ)
生成一个立即服务的软件中断。中断的 ISR 运行动态定时器队列。计时器处理程序在 softirq 上下文中运行,并启用了硬件中断。当 ISR 返回时,调度程序被调用。这意味着如果设置了很多计时器,那么运行队列中的下一个进程将被延迟。
如果有丢失的滴答声,则定时器处理程序的执行可能会延迟,但是,延迟不取决于运行时钟定时器中断之前的执行情况。
关于动态定时器精度的注意事项
“......内核无法确保计时器函数在其到期时间正确启动。它只能确保它们在适当的时间或延迟最多几百毫秒后执行。” 了解 Linux 内核,播威和 Cesati,第 3 版,O'reilly。
因此,如果您需要更好的计时器精度,则需要使用高分辨率计时器。
参考:软件中断和实时