Chinaunix首页 | 论坛 | 博客
  • 博客访问: 232889
  • 博文数量: 37
  • 博客积分: 933
  • 博客等级: 军士长
  • 技术积分: 511
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-16 10:15
文章分类
文章存档

2012年(1)

2011年(36)

分类: LINUX

2011-05-11 10:44:09

jiffies变量是定义在链接脚本arch/i386/kernel/vmlinux.lds.S里面的:
  1. OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
  2. OUTPUT_ARCH(i386)
  3. ENTRY(phys_startup_32)
  4. jiffies = jiffies_64;
是说定义不知道是否妥当,因为这个链接脚本里面的定义概念已经不是我们时常接触的C语言的变量定义的概念了。我们都知道C语言对于变量的定义会为其分配存储空间。然而:
在链接脚本中,这个定义却只是指定了:jiffies符号地址与jiffies_64这个符号的符号地址相同
换句话说:jiffies变量与jiffies_64变量位于同一地址。
我们看一下System-map里这两个符号的地址。
  1. c06fac00 D jiffies
  2. c06fac00 D jiffies_64
的确是一样的。而jiffies_64的定义在kernel/time.c中。如下:
  1. u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
或许你会有些疑问:为什么要把jiffies变量定义在链接脚本里面?
我想是因为:首先C语言中没有很好的别名机制(两个变量共享同一地址,两个变量只不过是不同名称的相同内存地址的内存标签),其次内核代码很少有用到jiffies变量的地方,因为jiffies会产生溢出。而jiffies变量被更多的使用在驱动程序中。
为了解决jiffies(u32)变量的溢出问题,内核利用了下面几个宏对其处理。
  1. 117 #define time_after(a,b) \
  2.  118 (typecheck(unsigned long, a) && \
  3.  119 typecheck(unsigned long, b) && \
  4.  120 ((long)(b) - (long)(a) < 0))
  5.  121 #define time_before(a,b) time_after(b,a)
  6.  122
  7.  123 #define time_after_eq(a,b) \
  8.  124 (typecheck(unsigned long, a) && \
  9.  125 typecheck(unsigned long, b) && \
  10.  126 ((long)(a) - (long)(b) >= 0))
  11.  127 #define time_before_eq(a,b) time_after_eq(b,a)

对于这几个宏是如何解决溢出 可以google一下,网上这类文章很多。

对于time_after等比较jiffies先/后的宏,两个值的取值应当满足以下限定条件:

  1. 首先a超越b的时间不能大于有符号数所能表示的最大值
  2. 对于32位无符号整型,两个值之间相差从逻辑值来讲应小于2147483647。对于HZ=100,那么两个时间值之间相差不应当超过2147483647/100秒 = 0.69年 = 248.5天。对于HZ=60,那么两个时间值之间相差不应当超过2147483647/60秒 = 1.135年。在实际代码应用中,需要比较先/后的两个时间值之间一般都相差很小,范围大致在1秒~1天左右,所以以上time_after等比较时间先/后的宏完全可以放心地用于实际的代码中。
阅读(3588) | 评论(0) | 转发(1) |
0

上一篇:分析Linux idle

下一篇:kernel中的per_cpu变量

给主人留下些什么吧!~~