本文转载自:http://blog.csdn.net/droidphone/article/details/7979295

版权声明:本文为博主原创文章,未经博主允许不得转载。

 

目录(?)[+]

 

人们习惯用于表示时间的方法是:年、月、日、时、分、秒、毫秒、星期等等,但是在内核中,为了软件逻辑和代码的方便性,它使用了一些不同的时间表示方法,并为这些表示方法定义了相应的变量和数据结构,本节的内容就是阐述这些表示方法的意义和区别。

/*****************************************************************************************************/

声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢!

/*****************************************************************************************************/

1.  jiffies

内核用jiffies变量记录系统启动以来经过的时钟滴答数,它的声明如下:

  1. extern u64 __jiffy_data jiffies_64;
  2. extern unsigned long volatile __jiffy_data jiffies;

可见,在32位的系统上,jiffies是一个32位的无符号数,系统每过1/HZ秒,jiffies的值就会加1,最终该变量可能会溢出,所以内核同时又定义了一个64位的变量jiffies_64,链接的脚本保证jiffies变量和jiffies_64变量的内存地址是相同的,通常,我们可以直接访问jiffies变量,但是要获得jiffies_64变量,必须通过辅助函数get_jiffies_64来实现。jiffies是内核的低精度定时器的计时单位,所以内核配置的HZ数决定了低精度定时器的精度,如果HZ数被设定为1000,那么,低精度定时器(timer_list)的精度就是1ms=1/1000秒。因为jiffies变量可能存在溢出的问题,所以在用基于jiffies进行比较时,应该使用以下辅助宏来实现:

  1. time_after(a,b)
  2. time_before(a,b)
  3. time_after_eq(a,b)
  4. time_before_eq(a,b)
  5. time_in_range(a,b,c)

同时,内核还提供了一些辅助函数用于jiffies和毫秒以及纳秒之间的转换:

  1. unsigned int jiffies_to_msecs(const unsigned long j);
  2. unsigned int jiffies_to_usecs(const unsigned long j);
  3. unsigned long msecs_to_jiffies(const unsigned int m);
  4. unsigned long usecs_to_jiffies(const unsigned int u);

2.  struct timeval

timeval由秒和微秒组成,它的定义如下:
  1. struct timeval {
  2. __kernel_time_t     tv_sec;     /* seconds */
  3. __kernel_suseconds_t    tv_usec;    /* microseconds */
  4. };

__kernel_time_t 和__kernel_suseconds_t 实际上都是long型的整数。gettimeofday和settimeofday使用timeval作为时间单位。

3.  struct timespec

timespec由秒和纳秒组成,它的定义如下:
  1. struct timespec {
  2. __kernel_time_t tv_sec;         /* seconds */
  3. long        tv_nsec;        /* nanoseconds */
  4. };

同样地,内核也提供了一些辅助函数用于jiffies、timeval、timespec之间的转换:

  1. static inline int timespec_equal(const struct timespec *a, const struct timespec *b);
  2. static inline int timespec_compare(const struct timespec *lhs, const struct timespec *rhs);
  3. static inline int timeval_compare(const struct timeval *lhs, const struct timeval *rhs);
  4. extern unsigned long mktime(const unsigned int year, const unsigned int mon,
  5. const unsigned int day, const unsigned int hour,
  6. const unsigned int min, const unsigned int sec);
  7. extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
  8. static inline struct timespec timespec_add(struct timespec lhs, struct timespec rhs);
  9. static inline struct timespec timespec_sub(struct timespec lhs, struct timespec rhs);
  10. static inline s64 timespec_to_ns(const struct timespec *ts);
  11. static inline s64 timeval_to_ns(const struct timeval *tv);
  12. extern struct timespec ns_to_timespec(const s64 nsec);
  13. extern struct timeval ns_to_timeval(const s64 nsec);
  14. static __always_inline void timespec_add_ns(struct timespec *a, u64 ns);
  1. unsigned long timespec_to_jiffies(const struct timespec *value);
  2. void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value);
  3. unsigned long timeval_to_jiffies(const struct timeval *value);
  4. void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value);

timekeeper中的xtime字段用timespec作为时间单位。

4.  struct ktime

linux的通用时间架构用ktime来表示时间,为了兼容32位和64位以及big-little endian系统,ktime结构被定义如下:
  1. union ktime {
  2. s64 tv64;
  3. #if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
  4. struct {
  5. # ifdef __BIG_ENDIAN
  6. s32 sec, nsec;
  7. # else
  8. s32 nsec, sec;
  9. # endif
  10. } tv;
  11. #endif
  12. };

64位的系统可以直接访问tv64字段,单位是纳秒,32位的系统则被拆分为两个字段:sec和nsec,并且照顾了大小端的不同。高精度定时器通常用ktime作为计时单位。下面是一些辅助函数用于计算和转换:

  1. ktime_t ktime_set(const long secs, const unsigned long nsecs);
  2. ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs);
  3. ktime_t ktime_add(const ktime_t add1, const ktime_t add2);
  4. ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
  5. ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec);
  6. ktime_t timespec_to_ktime(const struct timespec ts);
  7. ktime_t timeval_to_ktime(const struct timeval tv);
  8. struct timespec ktime_to_timespec(const ktime_t kt);
  9. struct timeval ktime_to_timeval(const ktime_t kt);
  10. s64 ktime_to_ns(const ktime_t kt);
  11. int ktime_equal(const ktime_t cmp1, const ktime_t cmp2);
  12. s64 ktime_to_us(const ktime_t kt);
  13. s64 ktime_to_ms(const ktime_t kt);
  14. ktime_t ns_to_ktime(u64 ns);

Linux时间子系统之二:表示时间的单位和结构【转】的更多相关文章

  1. 【原创】Linux中断子系统(二)-通用框架处理

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  2. Linux时间子系统之二:表示时间的单位和结构

    人们习惯用于表示时间的方法是:年.月.日.时.分.秒.毫秒.星期等等,但是在内核中,为了软件逻辑和代码的方便性,它使用了一些不同的时间表示方法,并为这些表示方法定义了相应的变量和数据结构,本节的内容就 ...

  3. Linux时间子系统之二:Alarm Timer

    一.前言 严格来讲Alarm Timer也算POSIX Timer一部分,包含两种类型CLOCK_REALTIME_ALARM和CLOCK_BOOTTIME_ALARM.分别是在CLOCK_REALT ...

  4. Linux时间子系统(十二) periodic tick

    一.tick device概念介绍 1.数据结构 在内核中,使用struct tick_device来抽象系统中的tick设备,如下: struct tick_device {     struct ...

  5. Linux usb子系统(二):USB设备驱动usb-skeleton.c

    usb驱动分为通过usbfs操作设备的用户空间驱动,内核空间的内核驱动.两者不能同时进行,否则容易引发对共享资源访问的问题,死锁!使用了内核驱动,就不能在usbfs里驱动该设备. 下面转载的一篇分析u ...

  6. linux led子系统(二)

    对于led子系统中,有那么多得trigger,下面就来简单了解下. 1.default-on static void defon_trig_activate(struct led_classdev * ...

  7. Linux时间子系统专题汇总

    关于Linux时间子系统有两个系列文章讲的非常好,分别是WowoTech和DroidPhone. 还有两本书分别是介绍: Linux用户空间时间子系统<Linux/UNIX系统编程手册>的 ...

  8. 【原创】Linux中断子系统(三)-softirq和tasklet

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  9. Linux 网络子系统

    今天记录一下Linux网络子系统相关的东西. 因为感觉对这一块还是有一个很大的空白,这件事情太可怕了. 摘抄多份博客进行总结一下Linux网络子系统的相关东西. 一. Linux网络子系统体系结构 L ...

随机推荐

  1. 在VMWare下为CentOS设置静态IP通过NAT访问外网

    一.背景 安装好的CentOS系统默认是通过DHCP自动分配地址来共享主机的IP以达到访问外网的目的,但是因为莫名的原因无法访问外网.只好改为通过静态IP的方式访问外网. 二.操作步骤 2.1 确认开 ...

  2. Cards BZOJ 1004

    Cards [问题描述] 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张 ...

  3. Python入门--1--基本中的基本

    一. 1.这是一个面向对面的编程,一种解释性语言. 2.缩进是python的灵魂,使代码变得非常简洁,正确使用冒号“:”,IDLE的       下一行会自动缩进 3.if语句中 python拒绝接受 ...

  4. VirtualBox 5.0.10 中 Fedora 23 在安装了增强工具后无法自动调节虚拟机分辨率的问题(改)

    VirtualBox 5.0.10 中安装 Fedora 23,即使在安装了增强工具后,仍然会发现虚拟机无法根据 VirtualBox 的运行窗口大小自动进行分辨率调节.究其原因,主要是因为 Fedo ...

  5. ****如何优雅的用Axure装逼?高保真原型心得分享

    本文核心内容点:- 啥是高保真原型?(附简单说明原型)- Axure可以画出什么水准的高保真?(给示例,开启装逼模式)- 高保真原型图技巧:- 啥时候上高保真?适用场景 and 不适用场景 啥是高保真 ...

  6. 带你学Node系列之express-CRUD

    前言 hello,小伙伴们,我是你们的pubdreamcc,本篇博文出至于我的GitHub仓库node学习教程资料,欢迎小伙伴们点赞和star,你们的点赞是我持续更新的动力. GitHub仓库地址:n ...

  7. BZOJ——1649: [Usaco2006 Dec]Cow Roller Coaster

    http://www.lydsy.com/JudgeOnline/problem.php?id=1649 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 7 ...

  8. spark hbase

    1 配置 1.1 开发环境: HBase:hbase-1.0.0-cdh5.4.5.tar.gz Hadoop:hadoop-2.6.0-cdh5.4.5.tar.gz ZooKeeper:zooke ...

  9. delphi学习路线

     酷派(53376063) 11:04:19 1.语法基础PASCAL精要 先看个1-3遍,这是基础中的基础,只要没弄清楚看10遍都不多,当然最好结合着代码实例去看.(以后遇到哪儿不熟练继续反复看)2 ...

  10. 【深入Java虚拟机】之五:多态性实现机制——静态分派与动态分派

    方法解析 Class文件的编译过程中不包含传统编译中的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址.这个特性给Java带来了更强大的动态扩 ...