定时器和时间管理
时间管理在内核中占非常重要的地位;
相对时间;
绝对时间;
周期性产生事件---都是由系统定时器驱动的;
什么是系统定时器?
系统定时器是一种可编程的硬件芯片,它能以固定的频率产生中断---定时器中断;
定时器中断对应的中断处理程序负责更新系统时间,也负责执行需要周期性执行的任务;
什么是动态定时器?
动态定时器---一种用来推迟执行程序的工具;
内核能够动态创建或撤销动态定时器;
内核必须在硬件的帮助下才能计算和管理时间;
硬件为内核提供了一个系统定时器计算和管理时间;
系统定时器以编程预定的频率(节拍率---tick rate,单位时间内中断产生的次数,一般为HZ(次/S))自行触发时钟中断(称为(hitting---击中)或(popping---射中,时钟中断);
当系统定时器中断发生时,内核通过一种特殊的中断处理程序对其进行处理;
系统定时器发出的连续两次时钟中断的间隔时间称为节拍(tick,(1/tick rate)秒);
内核靠着系统定时器时钟中断间隔(tick,节拍)来计算墙上时间和系统运行时间;
节拍率---HZ(每秒中断的次数),怎样去设置?
系统定时器频率(节拍率)是通过静态预处理定义的;
在系统启动时按照HZ值对硬件进行设置;
体系结构不同,HZ值不同;
同体系结构机器不同,HZ也可能不同;
内核中的全部时间概念都来源于周期运行的系统时钟;
改变中断频率会对整个系统造成冲击---内核中的众多子系统都必须依赖时钟中断工作;
一句话:合适的才是最好的!
提高节拍率对系统的好处?
- 更高的时钟中断解析度(resolution)可提高时间驱动时间的解析度;
- 提高了时间驱动时间的准确度(accuracy);
- 依赖定时值执行的系统调用,如poll和select能以更高精度运行(poll和select两种系统调用会在等待时钟中断上浪费大量时间);
- 提高进程抢占的准确度;
提高节拍率的缺点?
节拍率越高,时钟中断频率越高,系统负担越重;时钟频率越高意味着处理器必须花费更多的时间来执行时钟中断处理程序---减少处理器处理其他工作的时间;频繁打乱处理器高速缓存并增加耗电;
什么是jiffy(jiffies)?
HZ---1秒内产生的时钟节拍数(m个tick),次数;
Jiffies---系统启动以来节拍数之和(n个tick),总的次数
单位节拍耗费时间---1/HZ秒;
系统运行时间---jiffy*(1/HZ) 秒;
全局变量jiffies用来记录自系统启动以来产生的节拍的总数;
系统启动时,内核将全局变量jiffies初始化为0;
每次时钟中断处理程序会增加变量jiffies的值;
一秒内时钟中断的次数等于HZ,一秒内jiffies增加的值HZ;
提供了jiffiy的定义及节拍计数比较的接口;
用户空间和HZ?
提供了内核节拍数到用户空间的节拍数的转换函数接口;
什么是墙上时间?
墙上时间(实际时间)对用户空间的应用程序最重要;
内核通过控制时钟中断维护实际时间;
内核为用户空间提供了一组系统调用以获取实际日期和实际时间;
什么是系统运行时间?
系统运行时间---自系统启动开始所流逝的时间;
系统运行时间对用户空间和内核都很有用---许多程序都必须清楚流逝的时间;
如何计算相对流行时间?
通过计算(当前和之后)两个时间点的系统运行时间差获取相对流逝时间;
硬时钟和实时钟
体系结构提供了两种设备进行计时;
什么是实时钟?
实时时钟(RTC)是用来持久存放系统时间的设备---系统关闭后,实时时钟仍然可以靠主板上的微型电池提供的电力保持系统的计时;
周期性的将当前系统时间存放进RTC中?
当系统启动时,内核通过读取RTC来初始哈墙上时间,该时间存放在xtime变量中;
系统定时器?
系统定时器是内核定时机制中最为重要的角色;
不同的体系结构实现不尽相同,但系统定时器的根本思想相同---提供一种周期性触发中断机制;
时钟中断处理程序?
时钟中断处理程序可以划分为两个部分:体系结构相关部分和体系结构无关部分;
体系结构相关的例程作为定时器的中断处理程序而注册到内核中,以便在产生时钟中断时,能相应地运行;
定时器
定时器(动态定时器或内核定时器)是管理内核流逝的时间的基础;
定时器的使用
初始化;设置超时时间;指定超时发生的函数;**定时器;
指定的函数将在定时器到期时自动执行;
定时器并不周期性的运行---在超时后自行撤销(被称为动态定时器的一个原因);
动态定时器不断地创建和撤销,运行次数也不受限制;
定时器的数据结构
数据结构及相关接口的声明;
相关接口的实现:
内核在时钟中断发生后执行定时器,定时器作为软中断在下半部上下文中执行;
内核所有定时器以链表形式放在一起;
内核将定时器按它们的超时时间划分五组---减少搜索超时定时器带来的负担;
当定时器超时时间接近时,定时器将随组一起下移;
内核中有哪些延迟执行的方法(特指“时间”相关的)?
- 忙等待(忙循环)---在循环中不断旋转直到希望的时钟节拍数耗尽;
使用情景:想要延迟的时间是节拍的整数倍或精确要求不高时可以使用;
使用jiffies;
- 短延迟---一般指小于1ms的延迟
使用情景:硬件同步---需要短暂等待某个动作的完成(等待时间往往小于1ms);
内核提供了三个可以处理ms、us、ns级别的延迟函数;
udelay()函数依靠执行数次循环达到延迟效果;---内核知道处理器1s内能执行多少次循环;
超过1ms的延迟不要使用udelay()函数---会溢出;
mdelay()函数是通过udelay()函数实现的;
3. schedule_timeout - sleep until timeout
schedule_timeout(signed long timeout)函数会让需要延迟执行的任务睡眠到指定的延迟时间耗尽后再运行;(无法保证睡眠时间正好等于指定的延迟时间---存在绝对误差;)
当指定的时间到期后,内核唤醒被延迟的任务并将任务重新放回运行队列;
schedule_timeout(signed long timeout)---是内核定时器的简单使用;
调用schedule_timeout(signed long timeout)代码必须能够睡眠---处于进程上下文且不能持锁;