zoukankan      html  css  js  c++  java
  • Linux时间子系统之二:表示时间的单位和结构【转】

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

     

    目录(?)[+]

     

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

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

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

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

    1.  jiffies

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

    [cpp] view plain copy
     
    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进行比较时,应该使用以下辅助宏来实现:
    [cpp] view plain copy
     
    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和毫秒以及纳秒之间的转换:

    [cpp] view plain copy
     
    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由秒和微秒组成,它的定义如下:
    [cpp] view plain copy
     
    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由秒和纳秒组成,它的定义如下:
    [cpp] view plain copy
     
    1. struct timespec {  
    2.     __kernel_time_t tv_sec;         /* seconds */  
    3.     long        tv_nsec;        /* nanoseconds */  
    4. };  
    同样地,内核也提供了一些辅助函数用于jiffies、timeval、timespec之间的转换:
    [cpp] view plain copy
     
    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.   
    11. static inline s64 timespec_to_ns(const struct timespec *ts);  
    12. static inline s64 timeval_to_ns(const struct timeval *tv);  
    13. extern struct timespec ns_to_timespec(const s64 nsec);  
    14. extern struct timeval ns_to_timeval(const s64 nsec);  
    15. static __always_inline void timespec_add_ns(struct timespec *a, u64 ns);  
    [cpp] view plain copy
     
    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结构被定义如下:
    [cpp] view plain copy
     
    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作为计时单位。下面是一些辅助函数用于计算和转换:
    [cpp] view plain copy
     
    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);  
  • 相关阅读:
    Java实现Labeling Balls(拓扑排序的应用)
    Java实现Labeling Balls(拓扑排序的应用)
    Java实现Labeling Balls(拓扑排序的应用)
    Java实现Labeling Balls(拓扑排序的应用)
    string与QString转换(string既可以是utf8,也可以是gbk)
    Qt4.8.6详细安装步骤(使用了i686-4.8.2-release-posix-dwarf-rt_v3-rev3,手动设置gcc和gdb)非常清楚 good
    qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method
    小试X64 inline HOOK,hook explorer.exe--->CreateProcessInternalW监视进程创建
    RtlAdjustPrivilege进程提权,权限ID对照表
    jQuery AJAX 网页无刷新上传示例
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7083542.html
Copyright © 2011-2022 走看看