linux 时钟处理机制

上传人:第*** 文档编号:38761840 上传时间:2018-05-07 格式:PDF 页数:17 大小:420.97KB
返回 下载 相关 举报
linux 时钟处理机制_第1页
第1页 / 共17页
linux 时钟处理机制_第2页
第2页 / 共17页
linux 时钟处理机制_第3页
第3页 / 共17页
linux 时钟处理机制_第4页
第4页 / 共17页
linux 时钟处理机制_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《linux 时钟处理机制》由会员分享,可在线阅读,更多相关《linux 时钟处理机制(17页珍藏版)》请在金锄头文库上搜索。

1、 Linux 时钟处理机制级别: 初级赵 健博 (), 硕士, 中国科学院计算技术研究所 2008 年 9 月 11 日在 Linux 操作系统中,很多活动都和时间有关,例如:进程调度和网络处理等等。所以说,了解 Linux 操作系统中的时钟处理机制有助于更好地了解 Linux 操作系统的运作方式。本文分析了 Linux 2.6.25 内核的时钟处理机制,首先介绍了在计算机系统中的一些硬件计时器,然后重点介 绍了 Linux 操作系统中的硬件时钟和软件时钟的处理过程以及软件时钟的应用。最后对全文进行 了总结。1 计算机系统中的计时器计算机系统中的计时器在计算机系统中存在着许多硬件计时器,例如

2、Real Timer Clock ( RTC )、Time Stamp Counter ( TSC ) 和 Programmable Interval Timer ( PIT ) 等等。这部分内容不是本文的中点,这里仅仅简单介绍几种,更多内容参见参考文献:Real Timer Clock ( RTC ): 独立于整个计算机系统(例如: CPU 和其他 chip ) 内核利用其获取系统当前时间和日期 Time Stamp Counter ( TSC ): 从 Pentium 起,提供一个寄存器 TSC,用来累计每一次外部振荡器产生的时钟信号 通过指令 rdtsc 访问这个寄存器 比起 PIT,T

3、SC 可以提供更精确的时间测量 Programmable Interval Timer ( PIT ): 时间测量设备 内核使用的产生时钟中断的设备,产生的时钟中断依赖于硬件的体系结构,慢的为 10 ms 一次, 快的为 1 ms 一次High Precision Event Timer ( HPET ): PIT 和 RTC 的替代者,和之前的计时器相比,HPET 提供了更高的时钟频率(至少10 MHz )以 及更宽的计数器宽度(64位)一个 HPET 包括了一个固定频率的数值增加的计数器以及3到32个独立的计时器,这每一个计时 器有包涵了一个比较器和一个寄存器(保存一个数值,表示触发中断的

4、时机)。每一个比较器都 比较计数器中的数值和寄存器中的数值,当这两个数值相等时,将产生一个中断2 硬件时钟处理硬件时钟处理这里所说的硬件时钟处理特指的是硬件计时器时钟中断的处理过程。2.1 数据结构数据结构和硬件计时器(本文又称作硬件时钟,区别于软件时钟)相关的数据结构主要有两个:struct clocksource :对硬件设备的抽象,描述时钟源信息 struct clock_event_device :时钟的事件信息,包括当硬件时钟中断发生时要执行那些操作(实际上保 存了相应函数的指针)。本文将该结构称作为“时钟事件设备”。上述两个结构内核源代码中有较详细的注解,分别位于文件 clocks

5、ource.h 和 clockchips.h 中。需要特别注意 的是结构 clock_event_device 的成员 event_handler ,它指定了当硬件时钟中断发生时,内核应该执行那些 操作,也就是真正的时钟中断处理函数。 在2.3节“时钟初始化”部分会介绍它真正指向哪个函数。Page 1 of 17Linux 时钟处理机制2010-1-4http:/ by Foxit PDF Creator Foxit Software http:/ For evaluation only.Linux 内核维护了两个链表,分别存储了系统中所有时钟源的信息和时钟事件设备的信息。这两个链表的表头 在

6、内核中分别是 clocksource_list 和 clockevent_devices 。图2-1显示了这两个链表。图图2-1 时钟源链表和时钟事件链表时钟源链表和时钟事件链表 2.2 通知链技术(通知链技术( notification chain )在时钟处理这部分中,内核用到了所谓的“通知链( notification chain )”技术。所以在介绍时钟处理过程之前 先来了解下“通知链”技术。在 Linux 内核中,各个子系统之间有很强的相互关系,一些被一个子系统生成或者被探测到的事件,很可能是 另一个或者多个子系统感兴趣的,也就是说这个事件的获取者必须能够通知所有对该事件感兴趣的子系

7、统, 并且还需要这种通知机制具有一定的通用性。基于这些, Linux 内核引入了“通知链”技术。2.2.1 数据结构:数据结构:通知链有四种类型,原子通知链( Atomic notifier chains ):通知链元素的回调函数(当事件发生时要执行的函数)只能在 中断上下文中运行,不允许阻塞1.可阻塞通知链( Blocking notifier chains ):通知链元素的回调函数在进程上下文中运行,允许阻塞2. 原始通知链( Raw notifier chains ):对通知链元素的回调函数没有任何限制,所有锁和保护机制都由 调用者维护3.SRCU 通知链( SRCU notifier

8、chains ):可阻塞通知链的一种变体4.所以对应了四种通知链头结构:struct atomic_notifier_head :原子通知链的链头 struct blocking_notifier_head :可阻塞通知链的链头Page 2 of 17Linux 时钟处理机制2010-1-4http:/ by Foxit PDF Creator Foxit Software http:/ For evaluation only.注:本文中所有代码均来自于 Linux2.6.25 源代码struct raw_notifier_head :原始通知链的链头 struct srcu_notifier

9、_head : SRCU 通知链的链头通知链元素的类型:struct notifier_block :通知链中的元素,记录了当发出通知时,应该执行的操作(即回调函数)链头中保存着指向元素链表的指针。通知链元素结构则保存着回调函数的类型以及优先级,参见 notifier.h 文 件。2.2.2 运作机制运作机制通知链的运作机制包括两个角色:被通知者:对某一事件感兴趣一方。定义了当事件发生时,相应的处理函数,即回调函数。但需要事先 将其注册到通知链中(被通知者注册的动作就是在通知链中增加一项)。1.通知者:事件的通知者。当检测到某事件,或者本身产生事件时,通知所有对该事件感兴趣的一方事件 发生。他

10、定义了一个通知链,其中保存了每一个被通知者对事件的处理函数(回调函数)。通知这个过 程实际上就是遍历通知链中的每一项,然后调用相应的事件处理函数。2.包括以下过程:通知者定义通知链1. 被通知者向通知链中注册回调函数2. 当事件发生时,通知者发出通知(执行通知链中所有元素的回调函数)3.整个过程可以看作是“发布订阅”模型(参见参考资料)被通知者调用 notifier_chain_register 函数注册回调函数,该函数按照优先级将回调函数加入到通知链中 。注 销回调函数则使用 notifier_chain_unregister 函数,即将回调函数从通知链中删除。2.2.1节讲述的4种通知链

11、各有相应的注册和注销函数,但是他们最终都是调用上述两个函数完成注册和注销功能的。有兴趣的读者可 以自行查阅内核代码。通知者调用 notifier_call_chain 函数通知事件的到达,这个函数会遍历通知链中所有的元素,然后依次调用每 一个的回调函数(即完成通知动作)。2.2.1节讲述的4种通知链也都有其对应的通知函数,这些函数也都是最 终调用 notifier_call_chain 函数完成事件的通知。更多关于通知链的内容,参见参考文献。由以上的叙述,“通知链”技术可以概括为:事件的被通知者将事件发生时应该执行的操作通过函数指针方式保 存在链表(通知链)中,然后当事件发生时通知者依次执行链

12、表中每一个元素的回调函数完成通知。2.3 时钟初始化时钟初始化内核初始化部分( start_kernel 函数)和时钟相关的过程主要有以下几个:tick_init()1. init_timers()2. hrtimers_init()3. time_init()4.其中函数 hrtimers_init() 和高精度时钟相关(本文暂不介绍这部分内容)。下面将详细介绍剩下三个函数。2.3.1 tick_init 函数函数函数 tick_init() 很简单,调用 clockevents_register_notifier 函数向 clockevents_chain 通知链注册元素: tick_no

13、tifier。这个元素的回调函数指明了当时钟事件设备信息发生变化(例如新加入一个时钟事件设备等 等)时,应该执行的操作,该回调函数为 tick_notify (参见2.4节)。2.3.2 init_timers 函数函数函数 init_timers() 的实现如清单2-1(省略了部分和主要功能无关的内容,以后代码同样方式处理)Page 3 of 17Linux 时钟处理机制2010-1-4http:/ by Foxit PDF Creator Foxit Software http:/ For evaluation only.清单清单2-1 init_timers 函数函数 void _ini

14、t init_timers(void) int err = timer_cpu_notify( register_cpu_notifier( open_softirq(TIMER_SOFTIRQ,run_timer_softirq, NULL); 代码解释:初始化本 CPU 上的软件时钟相关的数据结构,参见3.2节 向 cpu_chain 通知链注册元素 timers_nb ,该元素的回调函数用于初始化指定 CPU 上的软件时钟相关 的数据结构初始化时钟的软中断处理函数2.3.3 time_init 函数函数函数 time_init 的实现如清单2-2清单清单2-2 time_init 函数函

15、数 void _init time_init(void) init_tsc_clocksource(); late_time_init = choose_time_init(); 函数 init_tsc_clocksource 初始化 tsc 时钟源。choose_time_init 实际是函数 hpet_time_init ,其代码清单2-3清单清单2-3 hpet_time_init 函数函数 void _init hpet_time_init(void) if (!hpet_enable() setup_pit_timer(); setup_irq(0, 函数 hpet_enable 检测系统是否可以使用 hpet 时钟,如果可以则初始化 hpet 时钟。否则初始化 pit 时钟。最 后设置硬件时钟发生时的处理函数(参见2.4节)。初始化硬件时钟这个过程主要包括以下两个过程(参见 hpet_enable 的实现):初始化时钟源信息( struct cloc

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 其它中学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号