Linux时间子系统一——时间子系统综述

硬件timer


Timer在硬件上是一个非常简单的东西(这里不考虑虚拟化,安全相关的问题),一般来说timer都会支持两种模式,一是periodic模式和free running模式,前者周期性的产生中断,后者一直往前累加到配置的最大值,报一次中断,称为one shot。

软件抽象


软件上将timer抽象成clocksource和clockevent,从名字大概就猜得出来,clocksource是提供时间信息的,如当前的系统时间;而clockevent是提供事件信息的,就是在未来某个时间点提醒CPU某个事件需要处理了,比如定时器超时了,或者一个新的tick的到来。

TICK


现代操作系统基本都是分时操作系统,也就是说多任务分时共享CPU,而分时的基础就是timer,所以timer驱动是操作系统基础架构性质的驱动,从timer的角度去理解操作系统,会对操作系统有一个更加宏观和具体化的认识。
Timer之所以可以让多进城轮动起来,是因为它会周期性的产生中断,如CONFIG_HZ配置为250,意味着每4毫秒产生一次中断,而每次中断来的时候jiffs会增加一,所以jiffs是一个内核里面很重要的计时单位。在中断处理函数里面判断当前进程的时间片是否用完,如果用完的话就选择另外一个进程,这是分时复用最核心的逻辑。
CONFIG_HZ并不是越大越好,也不是越小越好,如果CONFIG_HZ太大,会导致频繁的产生中断,中断的软件栈会消耗过多的CPU资源,如果CONFIG_HZ过小,进程之间的切换频率较低,可能会导致某些高优先级进程响应速度慢。

Timer


timer分高精度timer和低精度timer,前者是基于硬件timer频率的,所以精度很高,而后者是基于jiffs的,所以精度比较低。这里简单介绍下原理:
前面说过,硬件timer支持periodic模式和free running模式,当工作在periodic模式时,timer只能按固定周期才生中断事件,这其实是有很大限制的,如CONFIG_HZ设置为250,那么timer只能每4ms才生一次中断,那么定时器定时时间只能是timer的整数倍,所以精度非常低,称为低优先级定时器,除此以外,低优先级定时器运行在软中断上下文,所以是可以被中断抢占的,此外如果软中断线程话,其精度将更低。
如果要使用高精度定时器,就必须使用free running模式,free running模式又可以成为one shot模式,也就是说每次定时只会才生一次中断,要想产生下一次中断,则需要重新配置定时器。这样开起来虽然麻烦了一点,但是却更加灵活,它想什么时候才生中断就什么时候产生中断,再也不会受限于CONFIG_HZ的配置,当然one shot模式需要统一定时器和tick事件,本质上他们都要求以固定的周期发生中断事件,只不过它们所要求的周期不一样,所以需要在每次中断发生后,要将最近的一次超时时间配置到timer中去。

Time


时间怎么办?一个timer是怎么既做clocksource又做clockevent的呢?话句话说,系统是如何基于一个随时可能被重新赋值的timer来维护持续向前的系统时间的呢?答案其实很简单,OFFSET。硬件timer并非一直往前计数,但是我们可以分步累加offset,来维护持续向前的系统时间。
简单来说,就是每次timer中断事件中,会将上次更新系统时间到现在经历的时间加到系统时间上去,而每次获取时间的时候,也会同样将上次更新系统时间到现在经历的时间加到系统时间上去,作为现在的系统时间。

你可能感兴趣的:(linux时间子系统)