您的位置 首页 数字

linux国际里的时刻

通常,操作系统可以使用三种方法来表示系统的当前时间与日期:①最简单的一种方法就是直接用一个64位的计数器来对时钟滴答进行计数。②第二种方法就是用一个32位计数器来对秒进行计数,同时还用一个

  一般,操作体系能够运用三种办法来表明体系的其时时刻与日期:

  ①最简略的一种办法便是直接用一个64位的计数器来对时钟滴答进行计数。

  ②第二种办法便是用一个32位计数器来对秒进行计数,一起还用一个32位的辅佐计数器对时钟滴答计数,之子累积到一秒停止。因为232超越136年,因而这种办法直至22世纪都能够让体系作业得很好。

  ③第三种办法也是按时钟滴答进行计数,可是是相关于体系发动以来的滴答次数,而不是相关于相关于某个确认的外部时刻;当读外部后备时钟(如RTC)或用户输入实践时刻时,依据其时的滴答次数核算体系其时时刻。

  UNIX类操作体系一般都选用第三种办法来保护体系的时刻与日期。

  1 基本概念

  首要,有必要清晰一些Linux内核时钟驱动中的基本概念。

  (1)时钟周期(clock cycle)的频率:8253/8254 PIT的实质便是对由晶体振荡器产生的时钟周期进行计数,晶体振荡器在1秒时刻内产生的时钟脉冲个数便是时钟周期的频率。

  Linux用宏CLOCK_TICK_RATE来表明8254 PIT的输入时钟脉冲的频率(在PC机中这个值一般是1193180HZ),该宏界说在include/asm-i386/timex.h头文件中:

  #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */

  (2)时钟滴答(clock tick):咱们知道,当PIT通道0的计数器减到0值时,它就在IRQ0上产生一次时钟中止,也即一次时钟滴答。PIT通道0的计数器的初始值决议了要过多少时钟周期才产生一次时钟中止,因而也就决议了一次时钟滴答的时刻距离长度。

  (3)时钟滴答的频率(HZ):也即1秒时刻内PIT所产生的时钟滴答次数。类似地,这个值也是由PIT通道0的计数器初值决议的(反过来说, 确认了时钟滴答的频率值后也就能够确认8254 PIT通道0的计数器初值)。Linux内核用宏HZ来表明时钟滴答的频率,并且在不同的渠道上HZ有不同的界说值。关于ALPHA和IA62渠道HZ的 值是1024,关于SPARC、MIPS、ARM和i386等渠道HZ的值都是100。该宏在i386渠道上的界说如下(include/asm- i386/param.h):

  #ifndef HZ

  #define HZ 100

  #endif

  依据HZ的值,咱们也能够知道一次时钟滴答的详细时刻距离应该是(1000ms/HZ)=10ms。

  (4)时钟滴答的时刻距离:Linux用全局变量tick来表明时钟滴答的时刻距离长度,该变量界说在kernel/timer.c文件中,如下:

  long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */

  tick变量的单位是奇妙(μs),因为在不同渠道上宏HZ的值会有所不同,因而方程式tick=1000000÷HZ的成果或许会是个小数, 因而将其进行四舍五入成一个整数,所以Linux将tick界说成(1000000+HZ/2)/HZ,其间被除数表达式中的HZ/2的效果便是用来将 tick值向上圆整成一个整型数。

  别的,Linux还用宏TICK_SIZE来作为tick变量的引证别号(alias),其界说如下(arch/i386/kernel/time.c):

  #define TICK_SIZE tick

  (5)宏LATCH:Linux用宏LATCH来界说要写到PIT通道0的计数器中的值,它表明PIT将没隔多少个时钟周期产生一次时钟中止。明显LATCH应该由下列公式核算:

  LATCH=(1秒之内的时钟周期个数)÷(1秒之内的时钟中止次数)=(CLOCK_TICK_RATE)÷(HZ)

  类似地,上述公式的成果或许会是个小数,应该对其进行四舍五入。所以,Linux将LATCH界说为(include/linux/timex.h):

  /* LATCH is used in the interval timer and ftape setup. */

  #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */

  类似地,被除数表达式中的HZ/2也是用来将LATCH向上圆整成一个整数。

  2 表明体系其时时刻的内核数据结构

  作为一种UNIX类操作体系,Linux内核明显选用本节一开始所述的第三种办法来表明体系的其时时刻。Linux内核在表明体系其时时刻时用到了三个重要的数据结构:

  ①全局变量jiffies:这是一个32位的无符号整数,用来表明自内核上一次发动以来的时钟滴答次数。每产生一次时钟滴答,内核的时钟中止处 理函数timer_interrupt()都要将该全局变量jiffies加1。该变量界说在kernel/timer.c源文件中,如下所示:

  unsigned long volatile jiffies;

  C言语限定符volatile表明jiffies是一个易该变的变量,因而编译器将使对该变量的拜访从不经过CPU内部cache来进行。

  ②全局变量xtime:它是一个timeval结构类型的变量,用来表明其时时刻距UNIX时刻基准1970-01-01 00:00:00的相对秒数值。结构timeval是Linux内核表明时刻的一种格局(Linux内核对时刻的表明有多种格局,每种格局都有不同的时刻 精度),其时刻精度是微秒。该结构是内核表明时刻时最常用的一种格局,它界说在头文件include/linux/time.h中,如下所示:

  struct timeval {

  time_t tv_sec; /* seconds */

  suseconds_t tv_usec; /* microseconds */

  };

  其间,成员tv_sec表明其时时刻距UNIX时刻基准的秒数值,而成员tv_usec则表明一秒之内的微秒值,且1000000>tv_usec>=0。

  Linux内核经过timeval结构类型的全局变量xtime来保持其时时刻,该变量界说在kernel/timer.c文件中,如下所示:

  /* The current time */

  volatile struct timeval xtime __attribute__ ((aligned (16)));

  可是,全局变量xtime所保持的其时时刻一般是供用户来检索和设置的,而其他内核模块一般很少运用它(其他内核模块用得最多的是 jiffies),因而对xtime的更新并不是一项急迫的使命,所以这一作业一般被推迟到时钟中止的底半部分(bottom half)中来进行。因为bottom half的执行时刻带有不确认性,因而为了记住内核上一次更新xtime是什么时分,Linux内核界说了一个类似于jiffies的全局变量 wall_jiffies,来保存内核上一次更新xtime时的jiffies值。时钟中止的底半部分每一次更新xtime的时侯都会将 wall_jiffies更新为其时的jiffies值。全局变量wall_jiffies界说在kernel/timer.c文件中:

  /* jiffies at the most recent update of wall time */

  unsigned long wall_jiffies;

  ③全局变量sys_tz:它是一个timezone结构类型的全局变量,表明体系其时的时区信息。结构类型timezone界说在include/linux/time.h头文件中,如下所示:

  struct timezone {

  int tz_minuteswest; /* minutes west of Greenwich */

  int tz_dsttime; /* type of dst correction */

  };

  根据上述结构,Linux在kernel/time.c文件中界说了全局变量sys_tz表明体系其时所在的时区信息,如下所示:

  struct timezone sys_tz;

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/shuzi/115000.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部