系统之家 - 系统光盘下载网站!

当前位置:系统之家 > 系统教程 > Linux变量jiffies用法

Linux全局变量jiffies的用法

时间:2015-01-14 17:23:30 作者:qipeng 来源:系统之家 1. 扫描二维码随时看资讯 2. 请使用手机浏览器访问: https://m.xitongzhijia.net/xtjc/20150114/34867.html 手机查看 评论

  jiffies是Linux系统中的全局变量,与时间有关,那么jiffies变量具体有哪些作用呢?下面小编就给大家介绍下Linux全局变量jiffies的用法,感兴趣的朋友不妨来了解下吧。

 Linux全局变量jiffies的用法

  系统运行时间以秒为单位,等于jiffies/Hz。

  注意,jiffies类型为无符号长整型(unsigned long),其他任何类型存放它都不正确。

  将以秒为单位的时间转化为jiffies:

  seconds * Hz

  将jiffies转化为以秒为单位的时间:

  jiffies / Hz

  相比之下,内核中将秒转换为jiffies用的多些。

  jiffies的内部表示

  jiffies定义于文件中:

  /*

  * The 64-bit value is not atomic - you MUST NOT read it

  * without sampling the sequence number in xtime_lock.

  * get_jiffies_64() will do this for you as appropriate.

  */

  extern u64 __jiffy_data jiffies_64;

  extern unsigned long volatile __jiffy_data jiffies;

  ld(1)脚本用于连接主内核映像(在x86上位于arch/i386/kernel/vmlinux.lds.S中),然后用jiffies_64变量的初值覆盖jiffies变量。因此jiffies取整个jiffies_64变量的低32位。

  访问jiffies的代码只会读取jiffies_64的低32位,通过get_jiffies_64()函数就可以读取整个64位的值。在64位体系结构上,jiffies_64和jiffies指的是同一个变量。

  #if (BITS_PER_LONG 《 64)

  u64 get_jiffies_64(void);

  #else

  static inline u64 get_jiffies_64(void)

  {

  return (u64)jiffies;

  }

  #endif

  在中

  #if (BITS_PER_LONG 《 64)

  u64 get_jiffies_64(void)

  {

  unsigned long seq;

  u64 ret;

  do {

  seq = read_seqbegin(&xtime_lock);

  ret = jiffies_64;

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

  return ret;

  }

  jiffies的回绕wrap around

  当jiffies的值超过它的最大存放范围后就会发生溢出。对于32位无符号长整型,最大取值为(2^32)-1,即429496795。如果节拍计数达到了最大值后还要继续增加,它的值就会回绕到0。

  内核提供了四个宏来帮助比较节拍计数,它们能正确的处理节拍计数回绕的问题:

  /*

  * These inlines deal with timer wrapping correctly. You are

  * strongly encouraged to use them

  * 1. Because people otherwise forget

  * 2. Because if the timer wrap changes in future you won‘t have to

  * alter your driver code.

  *

  * time_after(a,b) returns true if the time a is after time b.

  *

  * Do this with “《0” and “》=0” to only test the sign of the result. A

  * good compiler would generate better code (and a really good compiler

  * wouldn’t care)。 Gcc is currently neither.

  */

  #define time_after(a,b) /

  (typecheck(unsigned long, a) && /

  typecheck(unsigned long, b) && /

  ((long)(b) - (long)(a) 《 0))

  #define time_before(a,b) time_after(b,a)

  #define time_after_eq(a,b) /

  (typecheck(unsigned long, a) && /

  typecheck(unsigned long, b) && /

  ((long)(a) - (long)(b) 》= 0))

  #define time_before_eq(a,b) time_after_eq(b,a)

  /* Same as above, but does so with platform independent 64bit types.

  * These must be used when utilizing jiffies_64 (i.e. return value of

  * get_jiffies_64() */

  #define time_after64(a,b) /

  (typecheck(__u64, a) && /

  typecheck(__u64, b) && /

  ((__s64)(b) - (__s64)(a) 《 0))

  #define time_before64(a,b) time_after64(b,a)

  #define time_after_eq64(a,b) /

  (typecheck(__u64, a) && /

  typecheck(__u64, b) && /

  ((__s64)(a) - (__s64)(b) 》= 0))

  #define time_before_eq64(a,b) time_after_eq64(b,a)

  用户空间和HZ

  问题提出:

  在2.6以前的内核中,如果改变内核中的HZ值会给用户空间中某些程序造成异常结果。因为内核是以节拍数/秒的形式给用户空间导出这个值的,应用程序便依赖这个特定的HZ值。如果在内核中改变了HZ的定义值,就打破了用户空间的常量关系---用户空间并不知道新的HZ值。

  解决方法:

  内核更改所有导出的jiffies值。内核定义了USER_HZ来代表用户空间看到的HZ值。在x86体系结构上,由于HZ值原来一直是100,所以USER_HZ值就定义为100。内核可以使用宏jiffies_to_clock_t()将一个有HZ表示的节拍计数转换为一个由USER_HZ表示的节拍计数。

  在中

  /*

  * Convert jiffies/jiffies_64 to clock_t and back.

  */

  clock_t jiffies_to_clock_t(long x)

  {

  #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0

  return x / (HZ / USER_HZ);

  #else

  u64 tmp = (u64)x * TICK_NSEC;

  do_div(tmp, (NSEC_PER_SEC / USER_HZ));

  return (long)tmp;

  #endif

  }

  unsigned long clock_t_to_jiffies(unsigned long x)

  {

  #if (HZ % USER_HZ)==0

  if (x 》= ~0UL / (HZ / USER_HZ))

  return ~0UL;

  return x * (HZ / USER_HZ);

  #else

  u64 jif;

  /* Don‘t worry about loss of precision here 。。 */

  if (x 》= ~0UL / HZ * USER_HZ)

  return ~0UL;

  /* 。。 but do try to contain it here */

  jif = x * (u64) HZ;

  do_div(jif, USER_HZ);

  return jif;

  #endif

  }

  u64 jiffies_64_to_clock_t(u64 x)

  {

  #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0

  do_div(x, HZ / USER_HZ);

  #else

  /*

  * There are better ways that don’t overflow early,

  * but even this doesn‘t overflow in hundreds of years

  * in 64 bits, so.。

  */

  x *= TICK_NSEC;

  do_div(x, (NSEC_PER_SEC / USER_HZ));

  #endif

  return x;

  }

  在中

  /*

  * do_div() is NOT a C function. It wants to return

  * two values (the quotient and the remainder), but

  * since that doesn’t work very well in C, what it

  * does is:

  *

  * - modifies the 64-bit dividend _in_place_

  * - returns the 32-bit remainder

  *

  * This ends up being the most efficient “calling

  * convention” on x86.

  */

  #define do_div(n,base) ({ /

  unsigned long __upper, __low, __high, __mod, __base; /

  __base = (base); /

  asm(“”:“=a” (__low), “=d” (__high):“A” (n)); /

  __upper = __high; /

  if (__high) { /

  __upper = __high % (__base); /

  __high = __high / (__base); /

  } /

  asm(“divl %2”:“=a” (__low), “=d” (__mod):“rm” (__base), “0” (__low), “1” (__upper)); /

  asm(“”:“=A” (n):“a” (__low),“d” (__high)); /

  __mod; /

  })

  用户空间期望HZ=USER_HZ,但是如果它们不相等,则由宏完成转换。

  上面就是Linux中jiffies变量的用法介绍了,如果你要计算系统运算了多少时间,那么你就可以使用jiffies变量来计算了,jiffies变量还有很多用途,使用多了你就会了解。

标签 变量

发表评论

0

没有更多评论了

评论就这些咯,让大家也知道你的独特见解

立即评论

以上留言仅代表用户个人观点,不代表系统之家立场

其他版本软件

热门教程

人气教程排行

Linux系统推荐

扫码关注
扫码关注

扫码关注 官方交流群 软件收录