加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

浅析Linux中的时间编程和实现原理(四)Linux 内核的工作

发布时间:2016-01-16 04:12:36 所属栏目:Linux 来源:网络整理
导读:回顾 近年来,随着 Linux 的广泛使用,对时间编程提出了更高的要求。实时应用、多媒体软件对时钟和定时器的精度要求不断提高,在早期 Linux 内核中,定时器所能
副标题[/!--empirenews.page--]

回顾

近年来,随着 Linux 的广泛使用,对时间编程提出了更高的要求。实时应用、多媒体软件对时钟和定时器的精度要求不断提高,在早期 Linux 内核中,定时器所能支持的最高精度是一个 tick。为了提高时钟精度,人们只能提高内核的 HZ 值 (一个内核参数,代表内核时钟中断的频率)。更高的 HZ 值,意味着时钟中断更加频繁,内核要花更多的时间进行时钟处理。而内核的任何工作对于应用来说纯粹是无益的开销。当 HZ 值提高到 1000 之后,如果继续提高,Linux 的可用性将下降。

另外一方面,我们已看到,类似 HPET(High Precision Event Timer) 等系统硬件已经能够提供纳秒级别的时钟中断,如何利用这些高精度时钟硬件来提供更高精度的定时服务是这一部分的主要话题。

2.6.16 以来的新变化

在 2.6.16 之前,Linux 开发人员花了很多的努力试图在原有代码体系结构下实现高精度时钟,但这种努力被证明是徒劳的。

因此从 2.6.16 开始,RedHat 公司的 Ingo Molar 和 Thomas Gleixner 对时间系统进行了比较大的重构。引入了以下几个新的模块:

Generic Timer Framework

早期 Linux 内核也需要支持众多不同的时钟硬件设备,但内核本身对这些设备的使用相对简单。内核将硬件的不同操作封装在 Arch 层里面。比如 x86 体系结构下,设置 PIT(Programmable Interrupt Timer) 是在 8259 芯片初始化时完成的,调用的 API 名字叫做 setup_pit_timer(),而在其他体系结构中,没有 8259,其初始化 time_init()中的具体实现又有所不同,会采用不同的 API 命名和不同的表示 Timer 硬件的数据结构。因为早期 Linux 上只需要做一次时钟初始化,操作具体硬件的次数有限,因此这种不同体系结构用不同实现细节的做法没有什么问题。

新的内核能够支持 tickless 模式,即当内核空闲时为了省电而关闭时钟中断。为此,内核需要频繁操作 Timer 硬件,在这种情况下,采用统一的抽象层有助于代码的维护。这便是 Generic Timer Frame,它将各种不同硬件抽象为三个统一的数据结构:

Clock Source,由 struct clocksource 表示。这个数据结构主要用来抽象那些能够提供计时功能的系统硬件,比如 RTC(Real Time Clock)、TSC(Time Stamp Counter) 等。

Clock Event Device,由 struct clock_event_device 表示。这个数据结构主要用来封装和抽象那些能提供定时中断能力的系统硬件,比如 HPET 等。

Tick Device,由 struct tick_device 表示。这个数据结构建立在 clock event device 之上,专门用来表示产生 tick 的设备。tick 是一个定时中断。因此归根结底需要一个 Clock Event Device 来完成,但 Clock Event Device 不仅可以用来提供 tick,在高精度 Timer 模式下,还用来提供其他功能。

Generic Timer Frame 把各种不同时间硬件的区别同上层软件隔离开来,使得时间系统能够方便地支持新的时钟硬件,而无需大量修改硬件无关代码。

高精度定时器 hrtimer(High Resolution Timer)

高精度时钟不能建立在已有的时间轮算法上,虽然时间轮是一种有效的管理数据结构,但其 cascades 操作有不可预料的延迟。它更适于被称为"timeout”类型的低精度定时器,即不等触发便被取消的 Timer。这种情况下,cascades 可能造成的时钟到期延误不会有任何不利影响,因为根本等不到 cascades,换句话说,多数 Timer 都不会触发 cascades 操作。而高精度定时器的用户往往是需要等待其精确地被触发,执行对时间敏感的任务。因此 cascades 操作带来的延迟是无法接受的。所以内核开发人员不得不放弃时间轮算法,转而寻求其他的高精度时钟算法。最终,开发人员选择了内核中最常用的高性能查找算法红:黑树来实现 hrtimer。

在描述 hrtimer 的实现之前,先了解其使用方法是必要的。

hrtimer 的编程接口和方法

使用 hrtimer 之需要了解三个 API:

用 hrtimer_init() 初始化一个 Timer 对象,用 hrtimer_start() 设定到期时间和到期操作,并添加启动该 Timer。remove_hrtimer() 删除一个 Timer。

Hrtimer 的实现

高精度定时器和低精度定时器的实现有以下两个主要的不同点:

高精度定时器由红黑树管理,而非时间轮。

Hrtimer 与系统时钟 tick 无关,不使用 jiffies,用纳秒作为计时单位。

所有的 hrtimer 实例都被保存在红黑树中,添加 Timer 就是在红黑树中添加新的节点;删除 Timer 就是删除树节点。红黑树的键值为到期时间。

Timer 的触发和设置管理不在定期的 tick 中断中进行,而是动态调整:当前 Timer 触发后,在中断处理的时候,将高精度时钟硬件的下次中断触发时间设置为红黑树中最早到期的 Timer 的时间。时钟到期后从红黑树中得到下一个 Timer 的到期时间,并设置硬件,如此循环反复。

图 1 显示了内核中用来管理 hrtimer 的数据结构及他们之间的关系。

图 1. 数据结构

浅析Linux中的时间编程和实现原理(四)Linux 内核的工作

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读