kernel笔记——定时器与时间管理

内核中时钟主要完成以下作用:

 

  • 记录系统运行时间
  • 完成时间相关的统计功能,如cpu占用率等
  • 定时功能,设定某个进程一段时间后完成某项任务 

为实现以上功能,硬件以及内核提供了不同类型的时钟。

 

RTC

实时时钟(real time clock,RTC),又叫硬件时钟、墙上时钟。RTC记录的是00:00:00 GMT,1 January 1970到当前经历的时间。

 

开机时,内核读取RTC时间,关机时内核更新RTC时间,系统运行的过程中不操作RTC。关机后依靠RTC记录时间,其由主板上的电池供电。

 

内核读取到的RTC时间,保存在xtime变量中,xtime是timespec结构类型的变量,在中定义:

struct timespec {
__kernel_time_t tv_sec; /* seconds */
long tv_nsec;           /* nanoseconds */
};

 

从结构定义中可以看到,xtime精度为纳秒。每次时钟中断触发时,中断处理函数将调用update_wall_time函数更新xtime。

 

c库中的gettimeofday/settimeofday,就是基于xtime,获取或设置基准时间(00:00:00 GMT,1 January 1970)到当前的时间间隔。

 

RTC设备在linux中用/dev/rtc表示,可以通过hwclock查询RTC时间、将RTC时间与系统时间相互同步。

 

定时器

周期性发生的事件由定时器(timer)触发,定时器是PIT(programmable interval timer)或TSC(time stamp counter)或其他类型的硬件芯片,时钟中断由定时器产生。

 

一个定时器对应于一个时钟源,时钟源在内核中由clocksource结构表示,该结构定义了时钟源名称、读取时钟源方法、开启/关闭时钟源方法等内容。

 

一个时钟事件由clock_event_device结构表示,该结构包含了时钟事件名称、时钟时间处理方法(event_handler)等字段。

 

时钟中断发生的时间间隔称为节拍(tick),节拍在内核编译阶段设定:

linux # zcat /proc/config.gz | grep CONFIG_HZ
CONFIG_HZ_250=y
CONFIG_HZ=250

 

以上设定节拍为250HZ,即每4ms发生一次时钟中断,每秒发生250次。jiffies是一个全局变量,它记录了自系统启动以来产生的节拍数。

 

每个cpu有各自的定时器,本地时钟中断发生时,由中断处理函数完成更新进程时间片、计算进程用户用时/系统用时等任务。update_process_times函数在本地时钟中断发生时被调用,该函数调用account_process_tick更新进程的用户态/内核态占用率,调用run_local_timers执行软时间中断,调用scheduler_tick更新当前进程的时间片。

 

单次触发

相比时钟中断提供4ms的计时精度,单次触发(one-shot)时钟提供更高的定时器精度。

 

高精度的时间由hrtimer结构表示,nanosleep函数的底层实现就用到了hrtimer以及相关操作函数。系统调用nanosleep的实现如下:SYSCALL_DEFINE2(nanosleep, …) -> hrtimer_nanosleep() -> do_nanosleep() -> hrtimer_start_expires()。超时的hrtimer事件由hrtimer_wakeup处理,hrtimer_wakeup调用wake_up_process唤醒相应进程。

 

suse11相比suse10提供了这种单次触发的时钟,由于其时间精度更高,poll、select、sleep等调用超时返回的频率更高,而cpu占用率、进程资源占用率等统计数据变得更精确。

 

以下为suse11、suse10下usleep命令对比的例子,在两个系统上执行strace -Ttt usleep 1,跟踪输出中与usleep对应的系统调用如下:

//suse11
11:38:44.836889 nanosleep({0, 1000}, {0, 0}) = 0 <0.000061>
11:38:44.836986 exit_group(0) = ?
//suse10
05:41:21.406039 nanosleep({0, 1000}, NULL) = 0 <0.000738>
05:41:21.406838 exit_group(0) = ?

 

从以上对比例子可看出,同样调用usleep休眠1微秒,suse11下usleep实际执行效果更接近1微秒设定值。

 

clockchips.h文件中定义了定时器事件与单次触发事件相应的宏:

#define CLOCK_EVT_FEAT_PERIODIC 0x000001
#define CLOCK_EVT_FEAT_ONESHOT 0x000002

 

Reference: Chapter 11 - Timers and Time Management, Linux kernel development.3rd.Edition

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值