在上面工作方式下,Linux 2.6.16 之前,内核软件定时器采用timer wheel多级时间轮的实现机制,维护操作系统的所有定时事件。timer wheel的触发是基于系统tick周期性中断。 所以说这之前,linux只能支持ms级别的时钟,随着时钟源硬件设备的精度提高和软件高精度计时的需求,有了高精度时钟的内核设计。 Linux 2.6.16 ,内核支持了高精度的时钟,内核采用新的定时器hrtimer,其实现逻辑和Linux 2.6.16 之前定时器逻辑区别:
hrtimer采用红黑树进行高精度定时器的管理,而不是时间轮;高精度时钟定时器不在依赖系统的tick中断,而是基于事件触发。旧内核的定时器实现依赖于系统定时器硬件定期的tick,基于该tick,内核会扫描timer wheel处理超时事件,会更新jiffies,wall time(墙上时间,现实时间),process的使用时间等等工作。 新的内核不再会直接支持周期性的tick,新内核定时器框架采用了基于事件触发,而不是以前的周期性触发。新内核实现了hrtimer(high resolution timer),hrtimer的设计目的,就是为了解决time wheel的缺点:
低精度;timer wheel只能支持ms级别的精度,hrtimer可以支持ns级别;Timer wheel与内核其他模块的高耦合性;新内核的hrtimer的触发和设置不像之前在定期的tick中断中进行,而是动态调整的,即基于事件触发,hrtimer的工作原理:通过将高精度时钟硬件的下次中断触发时间设置为红黑树中最早到期的 Timer 的时间,时钟到期后从红黑树中得到下一个 Timer 的到期时间,并设置硬件,如此循环反复。 在高精度时钟模式下,操作系统内核仍然需要周期性的tick中断,以便刷新内核的一些任务。前面可以知道,hrtimer是基于事件的,不会周期性出发tick中断,所以为了实现周期性的tick中断(dynamic tick):系统创建了一个模拟 tick 时钟的特殊 hrtimer,将其超时时间设置为一个tick时长,在超时回来后,完成对应的工作,然后再次设置下一个tick的超时时间,以此达到周期性tick中断的需求。
引入了dynamic tick,是为了能够在使用高精度时钟的同时节约能源,,这样会产生tickless 情况下,会跳过一些 tick。这里只是简单介绍,有兴趣可以读kernel源码。
