是time_after()Linuxmacros100%傻瓜certificate关于围绕jiffies?

基于我在linux / include / linux / jiffies.h中find的代码:

41 #define time_after(a,b) \ 42 (typecheck(unsigned long, a) && \ 43 typecheck(unsigned long, b) && \ 44 ((long)(b) - (long)(a) < 0)) 

在我看来,没有任何一种环境监测涉及到。 所以,如果jiffies(a)要环绕并且相当接近超时(b),那么当它实际为“真”时,结果将是“假”。

在这个例子中,我们使用一些相当小的数字。 说, time_after(110,150) ,其中110是jiffies,150是超时。 结果显然是错误的 – 无论是否缠绕:150-110总是> 0。

所以,我只想确认我没有错过任何事情,事实确实如此。

只是要清楚,在你的例子中,因为110不是在150之后, time_after(110,150)应该(并且确实)返回false。 从评论:

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

另外,请注意,代码确实处理到0绕包。为了使下面更容易理解,我将使用无符号和有符号的单字节值,即8位2的补码。 但是这个观点是一般的。

假设b是253,jiffies已经包含了5个tick。所以我们期望time_after(2,253)返回true。 它确实(使用int8_t来表示一个有符号的8位值):

 (int8_t) 253 - (int8_t) 2 == -3 - 2 == -5 < 0 

你也可以尝试其他的值。 这一个更棘手, time_after(128, 127) ,这也应该是真实的:

 (int8_t) 127 - (int8_t) 128 == 127 - (-128) == 255 == -1 (for 8-bit 2's complement) < 0 

实际上,表达式(int8_t) 127 - (int8_t) 128将是一个int值,而真正的值将是255.但是使用long类型的表达式类型将会很长,对于time_after( 2147483648, 2147483647)

 (long) 2147483647 - (long) 2147483648 == 2147483647 - (-2147483648) == 4294967295 == -1 < 0 

最终,在“包装”之后,“之后”jiffies值a将开始赶上之前的值b ,而time_after(a,b)将报告错误。 对于N位2的补码,这发生在a比b晚2 ^(N-1)滴答时。 对于N = 8,当a在b之后有128个滴答时发生。 对于N = 32,即2147483648个刻度,或(约1 ms刻度)约25天。

对于数学上的倾斜,我相信一般time_after(a,b)如果(ab)的最小残数(模2 ^ N)> 0且<2 ^(N-1) time_after(a,b)将返回真。

从附近的同一个文件中:

 /* * Have the 32 bit jiffies value wrap 5 minutes after boot * so jiffies wrap bugs show up earlier. */ #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) 

人们会希望这意味着它已经很好的测试了。