Linux单处理器系统中,定时器中断与系统处于内核模式还是用户模式无关?

系统处于内核模式时,定时器中断是否有任何不同的行为?

解决方法:

简单的答案是硬件时钟中断服务程序的执行以及动态定时器处理程序的调度都不受系统在硬件时钟中断之前所处的模式的影响.原因是时钟定时器中断是一个立即服务的硬件中断,无论执行是在内核还是用户上下文中(假设启用了定时器中断),以及时钟定时器的中断服务程序中断本身会引发运行动态定时器处理程序的软件中断.


警告:1)我实际上并没有凭经验证明这一点. 2)这不适用于无滴答内核或高阶定时器.

Linux内核代码使用“timer”这个词来表示几个不同的东西:

硬件定时器或时钟中断,为内核提供“滴答声”
动态定时器 – 内核和驱动程序使用的软件定时器
间隔计时器 – (setitimer和警报系统调用)用户模式进程的软件计时器

硬件时钟或滴答计时器

在使用硬件时钟提供“滴答”的系统上,时钟定时器中断是依赖于体系结构的硬件中断.例如,在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的处理程序设置为tick\_handle\_periodic的初始化,以及TIMER\_SOFTIRQ的处理程序.

对raise\_softirq(TIMER\_SOFTIRQ)的调用会生成一个立即处理的软件中断.中断的ISR运行动态定时器队列.定时器处理程序在softirq上下文中运行,并启用硬件中断.当ISR返回时,调用调度程序.这意味着如果设置了很多计时器,则运行队列中接下来的任何进程都将被延迟.

如果丢失了滴答,则可以延迟定时器处理程序的执行,但是,延迟不依赖于在运行时钟定时器中断之前的执行的执行.

注意动态计时器的准确性

“…内核无法确保定时器功能在其到期时间内正常启动.它只能确保它们在适当的时间执行,或者在延迟达到几百毫秒之后执行.”了解Linux Kernel,Bovet和Cesati,第3版,O’reilly.

因此,如果您需要更好的计时器精度,则需要使用高位计时器.

参考文献:Software interrupts and realtime

标签: linux, linux-kernel, linux-device-driver

相关文章推荐

添加新评论,含*的栏目为必填