Chinaunix首页 | 论坛 | 博客
  • 博客访问: 95481
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-07 19:35
文章分类
文章存档

2015年(11)

2014年(18)

我的朋友

分类: LINUX

2014-10-24 11:31:45

xtime该变量存放当前时间和日期,是一个timespec类型的数据结构,包括tv_sectv_nsec两个字段,该变量每个节拍更新一次,大约每秒更新1000次,用户程序从xtime获得当前时间,内核经常会调用它。

monotonic time该变量该机后单调递增,不因用户调整而改变,不计算系统休眠时间,系统休眠时不递增,不可以往后退。内核并没有直接定义一个特定的变量来记录monotonic时间,而是定义了一个变量wall_to_monotonic,记录了墙上时间核monotonic时间之间的偏移量,当需要获得monotonic时间时,把xtimewall_to_monotonic相加即可。计算monotonic时间要去除系统休眠期间花费的时间,内核用total_sleep_time记录休眠的时间,每次休眠醒来后重新累加该时间,并调整wall_to_monotonic的值,使其在系统休眠醒来后,monotonic时间不会发生跳变。因为wall_to_monotonic值被调整。
 
raw_timemonotonic时间虽然不受settimeofday的影响,但会受到ntp调整的影响,但是raw_time不受ntp的影响,它真的就是开完机后就单调地增加。
 
xtimemonotonic timeraw_time可以通过用户空间的clock_gettime函数获得,对应的ID参数分别是CLOCK_REALTIMECLOCK_MONOTONICCLOCK_MONOTONIC_RAW
 
clock sourcextimemonotonic timeraw time都是基于该时钟源进行计时操作,当有新的精度更高的时钟源被注册时,通过timekeeping_notify函数,change_clocksource函数将会被调用,timekeeper.clock字段将会被更新,指向新的clocksource
 
kernel/time/jiffies.c内核会默认注册一个jiffiesclocksource, 如下:

1.    static cycle_t jiffies_read(struct clocksource *cs)

2.    {

3.        return (cycle_t) jiffies;

4.    }

5.     

6.    struct clocksource clocksource_jiffies = {

7.        .name = "jiffies",

8.        .rating = 1, /* lowest valid rating*/

9.        .read = jiffies_read,

10.     .mask = 0xffffffff, /*32bits*/

11.     .mult = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */

12.     .mult_orig = NSEC_PER_JIFFY << JIFFIES_SHIFT,

13.     .shift = JIFFIES_SHIFT,

14. };

15. static int __init init_jiffies_clocksource(void)

16. {

17.     return clocksource_register(&clocksource_jiffies);

18. }

 注册jiffies之后,内核会提供精度为1/HZ的时间精度,但是你的设备体系还会注册它自己的clocksource,这个clocksource是硬件相关的,会更精准,

 

/arch/m68k/coldfire/time.c文件:

time_init()函数,初始化xtime变量,读取RTC时间。

初始化wall_to_monotonic变量,创建时钟中断程序timer interrupt

用户程序直接从xtime变量获得当前时间,所以内核必须周期性的更新该变量,全局时钟中断处理程序timer interrupt调用do_timer(1),每个tick调用update_times()更新xtime变量的值。其中有函数update_wall_time(),使用当前时钟源更新wall time

update_wall_time里会从之前注册的clocksource中读取计数值,然后将其换算为纳秒并赋值给xtime!以此为基础,xtime为用户空间提供了精准时钟。

do_gettimeofday()函数 首先执行usec = mach_gettimeoffset();  //用当前定时器对象的coldfire_gettimeoffset函数,确定自上一次时钟中断以来所走过的微秒数。如果定时器中断丢失,则加上相应的延迟。

usec += xtime.tv_nsec/1000; //usec加上1秒前走过的微秒数。

sec = xtime.tv_sec; //xtime复制到系统调用参数tv指向的缓冲区。

这里的处理要加锁xtime_lock,如果另一条内核路径获得了锁,则从开始读取。

最后的while循环用来检查微秒字段是否溢出,如果溢出则调整相应字段。

Linux指令date就是调用该函数获取时间。

Linux应用程序编程中sleep函数也要使用该函数作为时间基准。

 


阅读(1776) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:详解Linuxrc、rcS、rc.local、Profile

给主人留下些什么吧!~~