Linux 中的 时钟和定时测量 [email protected]. Linux Operating Systems Analysis2 举例.

36
Linux 中中 中中中中中中中 [email protected]
  • date post

    21-Dec-2015
  • Category

    Documents

  • view

    293
  • download

    1

Transcript of Linux 中的 时钟和定时测量 [email protected]. Linux Operating Systems Analysis2 举例.

Page 1: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

Linux中的时钟和定时测量

[email protected]

Page 2: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 2

举例

Page 3: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 3

定时测量 Linux内核提供两种主要的定时测量

获得当前的时间和日期 系统调用: time(), ftime()以及 gettimeofday()

维持定时器 settimer(), alarm()

定时测量是由基于固定频率振荡器和计数器的几个硬件电路完成的

Page 4: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 4

主要内容定时的硬件设备 Linux内核中与时间有关的程序实现 CPU分时、更新系统时间、维护软定时器

与定时测量相关的系统调用及相关服务例程

Page 5: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 5

硬时钟 80x86体系结构上,内核必须显式的与四种时钟打交道 实时时钟 Real time clock, RTC 时间戳计数器 Time stamp counter, TSC 可编程间隔定时器 Programmable interval timer, P

IT SMP系统上的本地 APIC定时器

用于跟踪当前时间

产生周期性的时钟中断,用于计时

Page 6: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 6

实时时钟 RTC

基本上所有的 PC都包含实时时钟 独立于 CPU与所有其他芯片 依靠一个独立的小电池供电给 RTC中的振荡器

即使关闭 PC电源,还会继续运转与 CMOS RAM往往集成在一个芯片内

例如:Motorala 146818能在 IRQ8上发出周期性的中断,频率在 2HZ

~8192之间 可以对其编程实现一个闹钟

Page 7: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 7

Linux本身只使用 RTC获得时间和日期对应的设备文件为 /dev/rtc

可以通过设备文件对其编程内核通过 0x70和 0x71两个端口访问 RTC系统管理员可以通过执行时钟程序设置时钟

Page 8: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 8

时间戳计数器 TSC

在 80x86微处理器中,有一个 CLK输入引线 接收外部振荡器的时钟信号

从 pentium开始,很多 80x86微处理器都引入了一个 TSC 一个 64位的、用作时间戳计数器的寄存器 它在每个时钟信号( CLK)到来时 +1

例如时钟频率 400MHz的微处理器, TSC每 2.5ns就+1

rdtsc指令用于读该寄存器

Page 9: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 9

与后面介绍的可编程间隔定时器相比, TSC可以获得更精确的时钟 为此, Linux在系统初始化的时候必须确定时钟信号 CLK的频率(即 CPU的实际频率)

calibrate_tsc 根据在一个相对较长的时间间隔内(约 50ms)所发生的 TSC计数的个数进行计算

那个间隔由可编程间隔定时器给出 由于只在系统初始化的时候运行一次,因此本程序可以执行较长时间,而不会引起问题

Page 10: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 10

可编程间隔定时器 PIT

经过适当编程后,可以周期性的给出时钟中断通常是 8254 CMOS芯片

使用 I/O端口 0x40~0x43 Linux将 PIT编程为:

100Hz 通过 IRQ0发出时钟中断

每 10ms产生一次时钟中断,即一个 tick

Page 11: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 11

Tick的长短短

优点:分辨率高 缺点:需要较多的 CPU时间处理,会导致用户程序运行变慢

适用于非常强大的机器,这种机器能够承担较大的系统开销

Tick的设置是一个折中,例如 在大多数惠普的 Alpha和 Intel的 IA-64上约 1ms产生一个 tick(每秒 1024个时钟中断)

Rawhide Alpha工作站采用更高( 1200tick/秒)

Page 12: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 12

在 Linux中,下列宏决定时钟中断频率

每秒钟时钟中断的个数,即每秒 tick的个数

8254芯片的内部振荡器频率,每秒多少次

对 8254分频,获得 HZ所需的时钟

Page 13: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 13

在 init_IRQ()中初始化时钟中断频率

此后,只要允许处理时钟中断,约每 10ms就会产生一个时钟中断1tick约为 10ms

Page 14: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 14

如何计算 CPU的时钟频率 CLK

Linux在初始化的时候,利用可编程间隔定时器获得 CPU的频率

观察 calibrate_tsc(),了解如何计算 CPU的频率 已知: PIT的频率 未知: CLK频率 方法:统计在 PIT已知的一段时间内( 50ms),

CLK发生了多少次;然后计算出 CLK频率(次数 /50ms)

Page 15: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 15

Linux的计时体系结构 Linux要周期性的执行一些任务,例如

更新系统自启动以来所经过的时间 更新时间和日期 确定进程运行了多久 检查每个软定时器是否已经到期

Page 16: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 16

在单处理器系统中,所有定时活动都由 IRQ0上的时钟中断触发,包括 在中断中立即执行的部分,和 作为下半部分延迟执行的部分

Page 17: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 17

PIT的时钟中断处理例程 Linux初始化时由 time_init()建立 IRQ0对应的中断处理函数

将 irq0作为 irq_desc的第一项的中断处理函数

Page 18: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 18

如果有 TSC,那么就得到时钟中断处理延迟,以给用户提供更精确的时钟

该函数会调用 do_timer进一步处理

Page 19: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 19

do_timer

全局变量,存放自系统启动以来的时钟节拍数32位约 497天会溢出(回归为 0)

检查当前进程对时间片的使用情况

激活下半部分

如果 tq_timer非空,还要激活相关的下半部分处理

Page 20: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 20

update_process_times

更新时间片视需要进行调度

统计当前进程对CPU时间的使用情况

Page 21: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 21

TIMER_BH下半部分当时钟中断处理例程运行结束并返回时,会立即处理下半部分

更新系统日期和时间,计算当前的系统负载

维护软定时器处理

Page 22: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 22

更新时间和日期用户程序从下面这个变量中获得当前时间和日期

存放从 1970年 1月 1日凌晨 0点以来经过的所有秒数

最后一秒已经过去的微秒数取值范围: 0~999999

Page 23: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 23

系统初始化时, time_init()初始化时间和日期

观察 get_cmos_time()

获得 coms时间一旦完成, Linux不再需要 RTC,依靠下半部分维护 xtime

Page 24: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 24

更新 xtime

上一次 xtime更新后的 jiffies

Page 25: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 25

软定时器定时器是一种软件功能,它允许在将来的某个时刻调用某个函数

大多数设备驱动程序利用定时器完成一些特殊工作 软盘驱动程序在软盘暂时不被访问时就关闭设备的发动机

并行打印机利用定时器检测错误的打印机情况

Page 26: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 26

Linux中存在两类定时器: 动态定时器

内核使用 间隔定时器

由进程在用户态创建

注意:由于软定时器在下半部分处理,内核不能保证定时器正好在时钟到期的时候被执行,会存在延迟,不适用于实时应用

Page 27: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 27

动态定时器动态定时器被动态的创建和撤销,当前活动的动态定时器个数没有限制

数据结构:

系统使用 512个双向链表维护动态定时器

定时器到期时要执行的函数

函数使用的参数

到期时间

Page 28: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 28

创建并激活一个动态定时器创建一个新的 timer_list对象调用 init_timer初始化,并设置定时器要处理的函数和参数

设置定时时间使用 add_timer加入到合适的链表中

通常定时器只能执行一次,如果要周期性的执行,必须再次将其加入链表

Page 29: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 29

动态定时器的处理为提高处理动态定时器的效率,必须给定时器排序,并使用合适的数据结构

Linux根据 expires的值,维护这样的数据结构

Page 30: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 30

=64, 64个双向链表,包含了未来某个时间段内的动态定时器index指向当前应当用来更新上一级定时器的链表

( =256), 256个双向链表,每个表示对应时钟到期时的动态定时器链表Index表示当前节拍对应的那个链表

未来 214-1个节拍内的定时器每 256个节拍内的定时器为 1个链表共 64个

未来 220-1个节拍内的定时器每 214个节拍内的定时器为 1个链表共 64个

未来 226-1个节拍内的定时器每 220个节拍内的定时器为 1个链表共 64个

未来 232-1个节拍内的定时器每 226个节拍内的定时器为 1个链表共 64个

一点点不同:最后一个链表中的定时器的时间可以任意大

Page 31: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 31

run_timer_list

下半部分 timer_bh()调用 run_timer_list()检查到期的动态定时器,包括: 执行动态定时器 更新链表

观察 run_timer_list()

Page 32: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 32

动态定时器的应用使用 schedule_timeout()可以使进程被延迟(睡眠一段时间)

观察 schedule_timeout()并看一个内核应用实例

Page 33: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 33

与定时测量相关的系统调用 time()

返回从 1970年 1月 1日凌晨 0点开始的秒数 ftime()

返回从 1970年 1月 1日凌晨 0点开始的秒数以及最后一秒的毫秒数

数据结构为 timeb gettimeofday()

返回从 1970年 1月 1日凌晨 0点开始的秒数 对应于 sys_gettimeofday()

Page 34: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 34

settimer() 间隔定时器

频率:周期性的触发定时器(若为 0,只触发一次) alarm()

引起 SIGALARM信号

Page 35: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 35

与时钟相关的命令 date:显示或者更改系统时钟

使用 time获得时钟

使用 ctime改变时钟格式

Page 36: Linux 中的 时钟和定时测量 xlanchen@2007.10.9. Linux Operating Systems Analysis2 举例.

[email protected] Linux Operating Systems Analysis 36

Project 5

在用户态编写一个程序,该程序设定一个定时器,在时间到期的时候做出某种可观察的响应

方法不限

分析你的程序的实际执行借助了内核的哪些机制