Linux Kernel时间子系统之来龙去脉浅析

 

1.1                   AP来看Linux系统提供的时间机制

1.1.1              Time的表达方式

Linux中从AP来看,时间有两种表达方式:

1.       wall-clock time: 自从1970年1月1日0时0分0秒以来到现在的时间差,理论上精确到nano-second。我们称这个时间点为Linux基准时间(或者linux epoch)。此种表达方式有利于software实现。User Application可以使用time()/stime()gettimeofday()/settimeofday()来获得;前者精确到second,后者理论上到nano-second。(ARM系统中一般到10ms)。

2.       现在的绝对时间,即:年,月,日,时,分,秒。这是User最终想看到的时间;RTC时间也如此。User Application可以使用gmtime()/mktime()ctime()/asctime()loactime()来进行两个表达方式的转换。(注意:这些都不是thread safe的,thread safe的版本:xxx_r,具体信息大家可以man一下就知道了。Why)。

1.1.2              AP Interval Timer

通常AP还需要创建一些定时器即timer,如:getitimer()/ setitimer():这些我们通常叫做Interval Timer,简称itimer,是指定时器采用“间隔”值(interval)作为计时方式,当定时器启动后,间隔值interval将不断减小。当 interval值减到0时,我们就说该间隔定时器到期,到期之后,内核一般会发送相应的signal给相应的进程。如果不删除itimeritimer会周期性的到期并发送信号。

具体itimer可以使用不同的time base,具体如下:

      ITIMER_REAL:以ITIMER_REALtime baseitimer在启动后,不管进程是否运行,不管是运行在内核态还是用户态,每个时钟滴答都将其间隔计数器减1。当减到0值时,内核向进程发送SIGALRM信号。

      ITIMER_VIRT:以ITIMER_VIRTtime baseitimer在启动后,只有该timerowner进程是运行在用户态的时候,每个时钟滴答才将其间隔计数器减1。当减到0值时,内核向进程发送SIGVTALRM信号。

      ITIMER_PROF:以ITIMER_PROFtime baseitimer在启动后,只有在该timerowner进程处于运行状态(不管是在用户态还是通过系统调用进入内核态)的时候,每个时钟滴答才将其间隔计数器减1。当减到0值时,内核向进程发送SIGPROF信号。

1.2                   top-down的方法从gettimeofday出发搞清楚Linux time的来龙去脉

1.2.1              gettimeofday的全过程

gettimeofdayC lib function=>> sys_gettimeofday=>>do_gettimeofday=>>__get_realtime_clock_ts

static inline void __get_realtime_clock_ts(struct timespec *ts)

{

   unsigned long seq;

   s64 nsecs;

   do {

          seq = read_seqbegin(&xtime_lock);

          *ts = xtime;

          nsecs = __get_nsec_offset();

   } while (read_seqretry(&xtime_lock, seq));

   timespec_add_ns(ts, nsecs);

}

 

xtime的定义如下:kernel/time/timekeeping.c

struct timespec xtime __attribute__ ((aligned (16)));

该structure的定义如下:

struct timespec {

   time_t     tv_sec;  /* seconds */  //自从197011000

   long tv_nsec;  /* nanoseconds */

};

1.2.2              xtime何时被初始化

cold boot的时候用rtc time更新xtime

start_kernel () =>> rest_init() =>> kernel_init() =>> do_basic_setup() =>> do_initcalls()中会调用rtc_hctosys

1.       rtc_read_time获得当前的rtc time

2.       rtc_tm_to_time将当前的rtc time转换为自从197011000秒数

3.       do_settimeofday=>>set_normalized_timespec(&xtime, sec, nsec); 设置xitme

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值