Linux内核-定时测量

1、定时测量概念

定时测量作用:

跟踪时间

联合内核活动(如检查超时)来驱使进程切换

组成:由基于固定频率振荡器计数器的几个硬件电路完成

Linux内核必需完成的两种定时测量

保存当前的时间和日期

维持定时器,告诉内核或用户程序某一时间间隔已经过去。

 

2、时钟和定时器电路

  在80x86体系结构上,内核必须显示地与几种时钟和定时器电路打交道。时钟电路同时用于跟踪当前时间和产生精确的时间度量定时器电路由内核编程,它们以固定的、预先定义的频率发出中断

2.1 实时时钟

1、所有PC都包含一个实时时钟,独立与CPU和其他芯片

2、靠一个小电池或蓄电池供电,当PC被切断电源,RTC还继续工作

3、RTC能在IRQ8上发出周期性的中断,频率在2~8192 Hz之间

4、可以对RTC进行编程以使RTC达到某个特定的值时激活IRQ8线,--作为一个闹钟来工作

5、Linux只用RTC来获取时间和日期;不过通过对/dev/rtc设备文件进行操作,也允许进程对RTC编程

2.2 时间戳计数器(TSC

1、在80x86微处理器中,通过CLK输入引线,接收外部振荡器的时钟信号

2、在每个时钟信号到来时加1

3、利用64位的时间戳计算器(TSC)寄存器来实现,可以通过汇编语言指令rdtsc读这个寄存器

4.Linux通过这个寄存器可以获得更精确的时间测量

Linux在初始化系统的时候必须确定时钟信号的频率。 算出CPU实际频率的任务是在系统初始化期间完成的。calibrate_tsc()函数通过计算一个大约在5ms的时间间隔内产生的时钟信号的个数来算出CPU实际的频率。 通过适当地设置可编程间隔定时器的一个通过来产生这个时间常量

2.3 可编程间隔定时器(PIT)

1、PIC计算器16位,经过适当编程后,可以周期性的给出时钟中断,通知内核一个时间间隔已经过去

2、PIT永远以内核确定的固定频率不停地发出全局性的中断,系统中的任一CPU都可以对其处理

3、PIT通过使用0x40~0x43 I/O断开的一个8254 CMOS芯片

4、PIC有其自己的内部时钟振荡器,可以灵活的编程

5、LINXU 给PC的第一个PIT进行编程,使它以(大约)1000Hz的频率向IRQ0发出时钟中断,即每1ms产生一次时钟中断

2.4 CPU本地定时器

1、一种能够产生单步中断或周期性中断的设备

2、APIC定时器把中断只发给自己的处理器

3、APIC定时器是基于总线时钟信号的,每个1,2,4,8,16,32,64128总线时钟信号到来时对该定时器进行递减可以实现对其编程的目的

2.5 高精度事件定时器(HPET

1、高精度事件定时器是由Intel和Microsoft联合开发的一种新型定时器芯片。

2、HPET提供了许多可以被内核使用的硬定时器

3、定时器芯片主要包含8个32位或64位的独立计算器。每个计算器由他自己的时钟信号所驱动,该时钟信号的频率必须至少为10MHZ,因此计数器最少可以每100ns增长一次。

4、任何计数器最多可以与32个定时器相关联,每个定时器由一个比较器和一个匹配寄存器组成。(比较器是一组用于检测计数器中的值与匹配寄存器中的值是否匹配的电路,如果找到一组匹配值就产生一个硬件中断。)

5、定时器可以被激活产生周期性中断。

6、可以通过映射到内存空间的寄存器对HPET芯片编程。HPET寄存器允许内核对计数器和匹配寄存器的值进行读和写。允许内核对单步中断进行编程,允许内核在支持HPET的定时器上激活或禁止周期性中断

2.6 ACPI 电源管理定时器

1、被称作ACPI PMT 是一种时钟设备,包含在几乎所有基于ACPI的主板上。

2、时钟信号拥有大约为3.58MHz的固定频率,该设备实际上是一个简单的计算器,在每个时钟节拍到来时增加一次。

3、如果操作系统或者BIOS可以通过动态降低CPU的工作频率或者工作电压来节省电池的电能,那么ACPI电源管理定时器就比TSC更优越。

3、Linux计时体系结构

Linux 计时体系结构:是一组与时间流相关的内核数据结构和函数。

Linux 必定执行与定时相关的操作,比如内核周期性地:

1、更新自系统启动以来所经过的时间 (clock_gettime)

2、更新时间和日期time/gettimeofday)。

3、确定当前进程在每个CPU上已运行了多长时间,如果已经超过了分配给它的时间,则抢占它。

4、检查每个软定时器的时间间隔是否已到

 

两种计时体系结构:

1、单处理系统上,所有的计时活动都是由全局定时器(可编程间隔定时器或高精度事件定时器)产生的中断触发

2、多处理系统上,所有普通的活动(像软定时器的处理)都是由全局定时器产生的中断触发,而具体CPU的活动(像监控当前运行进程的执行时间)是由本地APIC定时器产生的中断触发

3.1 计时体系的数据结构和变量

timer_opts 数据结构的各个字段:

 

 3.2 单处理器计时体系结构

3.3 多处理器计时体系结构

4、软定时器和延迟函数

定时器是一种软件功能,即允许在将来的某个时刻,函数在给定的时间间隔用完被调用超时表示与定时器相关的时间间隔已经用完的那个时刻

  1. 软定时器
    • 动态定时器(内核)
    • 间隔定时器(可以用户

延迟函数

4.1 动态定时器

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

timer_list结构中

struct timer_list{

struct list_head entry; //用于将软定时器插入双向循环链表队列中

unsigned long expires;// 给出定时器到期时间,时间用节拍数表示,其值为系统启动以来//所经历过的节拍数

spinlock_t lock;

unsigned longmagic;

void(*function)(unsigned long); //包含定时器到期时执行函数的地址

unsigned long data; //指定传递给定时器函数的参数。正是由于data字段,就可以定义一个//单独的通用函数来处理多个设备驱动程序的超时问题,在data字段可以存放设备ID,或其//它有意义的数据,定时器函数可以用这些数据区分不同的//设备。

tvec_base_t *base;

};

4.2 动态定时器竞争

被异步激活的的动态定时器有参与竞争条件的倾向。例如,考虑一个动态定时器,它的函数作用于可丢弃的资源。

如果在定时器函数被激活时资源不存在,那么不停止定时器就释放资源势必导致数据结构的崩溃。因此,一种凭经验的做法就是在释放资源前停止定时器:

内核提供了del_timer_sync()函数。这个函数从链表中删除定时器,然后检查定时器函数是否还在其它CPU上运行;如果是,del_timer_sync()就等待,直到定时器函数结束。

修改已激活定时器expires字段的正确方法是调用mod_timer(),而不是删除定时器随后又创建它。在后一种方法中,要修改同一定时器expires字段的两个内核控制路径可能糟糕地交错在一起。定时器函数在SMP上的安全实现是通过每个timer_list对象包含的lock自旋锁达到的:每当内核必须访问动态定时器的链表时,就禁止中断并猎取这个自旋锁。

4.3 动态定时器处理

尽管软定时器具有巧妙的数据结构,但是对其处理是一种耗时的活动,所以不应该被时钟中断处理程序执行。在Linux.6中该活动由延迟函数来执行,也就是由TIMER_SOFTIRQ软中断行

run_timer_softirq()函数是与TIMER_SOFTIRQ软中断请求相关的可延迟函数。它实质上执行如下操作:

4.4 延迟函数

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章