系统中有很多变量用来记录一个单调递增的现实,典型的有两个,一个是TCP的序列号,另一个就是jiffies,但是由于计算机内表示的数字都
是有限无界的,所以任何数字都不能做到完全意义的单调递增,它们只是在绕圈圈,就像钟表一样,值域就是那些有限的数字,周而复始。实际上不管是TCP序列
号还是jiffies,都面临一类问题,就是回绕问题。就像我们看钟表,1点时在11点前呢,还是在11点后呢?其实这个问题并没有想象的那么容易回答。
我们用char型来简单描述一下这个问题的解法。char只有8位,二进制从00000000到11111111,如果用一个char表示
jiffies,那么当其值已经达到11111111的时候,将面临一次跳变,即回归到0,这是因为11111111加1的话,将会得到
100000000,然而char只有8位,造成最高位溢出,所得到的结果就是00000000,这就是0点跳变,本质原因就是在跳变点附近,值域并不是
连续的。11111111的十进制是255,显然和0并不是连续的。
然而,11111111除了可以表示255之外,还可以表示-1,而-1和0却是连续的!我们知道,计算机内对于数据的存储是不区分符号的,符号只是在计
算的时候才根据指令的不同给与不同的解释,因此只需要将无符号的jiffies看作是有符号的数字,就可以解决这个跳变问题,显然0是在-1后面的,这也
就是说,0在255后面。将有符号数字解释为无符号数字,只是一种解释方式的不同,对于数据的表示没有任何影响,它只影响计算。有符号计算指令会将值域坐
标轴往左平移半个值域宽度,从而将0点变成中点,而不是左端点,解决0点跳变问题。然而这个只在后半个值域空间有效,也就是说,对于char而言,系统只
能正确识别128以后的跳变,如果你测试129和1水更靠前,答案是129,然而如果你测试127和1谁更靠前,答案就是1!但是这已经足够了,因为对于
jiffies的比较,基本都是附近值得比较,没有人会去比较现在和几千几万年以后的时间。
详情参见time_after,time_before宏。
关于jiffies回绕以及time_after,time_before
原文地址:http://dog250.blog.51cto.com/2466061/1735765