Linux全局变量jiffies的用法

2016-02-19 13:43 10 1 收藏

图老师小编精心整理的Linux全局变量jiffies的用法希望大家喜欢,觉得好的亲们记得收藏起来哦!您的支持就是小编更新的动力~

【 tulaoshi.com - Linux教程 】

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位。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

访问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.

*

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

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

*

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

* 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:

*

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

* - modifies the 64-bit dividend _in_place_

* - returns the 32-bit remainder

*

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

* 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变量还有很多用途,使用多了你就会了解。

来源:https://www.tulaoshi.com/n/20160219/1605064.html

延伸阅读
标签: 电脑入门
在Linux系统中,对变量进行赋值后需要发现有些问题,需要对变量值进行删除或替换,本文将针对Linux变量值的替换和删除做个详细介绍,希望对你有所帮助。 1、变量内容的删除 [root@bogon ~]# echo ${PATH} #呼叫出PATH变量的值 /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/mysql/bin:/root/bin [root...
标签: 电脑入门
Linux命令中,chmod命令的用法与chattr命令有些相似,但相对而言chmod命令只是改变文件读写、执行权限,文件权限主要还是通过chattr命令来完成,下面图老师小编就给大家介绍下Linux中chmod命令的用法。 文件或目录的访问权限分为只读,只写和可执行三种。以文件为例,只读权限表示只允许读其内容,而禁止对其做任何的更改操作。可执行权限...
环境变量 缺省情况下,环境变量从进程的父进程继续而来。但是,在程序执行另一个程序时,调用程序可以把环境变量设置为任意值。这对setuid/setgid程序而言很危险,因为其入侵者可以完全控制它们得到的环境变量。由于环境变量一般是继续来的,同样可以传递使用;安全程序可能调用某些其它程序,在没有非凡措施的情况下,这会把有潜...
标签: 服务器
Linux中cron命令的用法详解   linux中有一个命令可以定期来执行系统任务。这就是crond服务。下面介绍下crontab命令的用法。 linux任务调度的工作主要分为以下两类: 编辑/etc/crontab 文件配置cron cron服务每分钟不仅要读一次 /var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用...
标签: 电脑入门
Linux下chkconfig命令主要用于查询系统在每一个执行等级中执行的系统服务,那么chkconfig命令要如何使用呢?下面图老师小编就给大家介绍下Linux中chkconfig命令的具体用法。 chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息。谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接。 使用语法 ...

经验教程

500

收藏

69
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部