linux中的jiffies变量.doc_第1页
linux中的jiffies变量.doc_第2页
linux中的jiffies变量.doc_第3页
linux中的jiffies变量.doc_第4页
linux中的jiffies变量.doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

全局变量jiffies用来记录自系统启动以来产生的节拍的总数。启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值。一秒内时钟中断的次数等于Hz,所以jiffies一秒内增加的值也就是Hz。 系统运行时间以秒为单位,等于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位无符号长整型,最大取值为(232)-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 wont have to * alter your driver code. * * time_after(a,b) returns true if the time a is after time b. * * Do this with =0 to only test the sign of the result. A * good compiler would generate better code (and a really good compiler * wouldnt 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_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_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; /* Dont 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 dont overflow early, * but even this doesnt 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 doesnt 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

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论