Is the time_after() linux macro 100% fool-proof regarding the wrap around of jiffies?
Based on the code I found in linux/include/linux/jiffies.h:
41 #define time_after(a,b) \
42 (typecheck(unsigned long, a) && \
43 typecheck(unsigned long, b) && \
44 ((long)(b) - (long)(a) < 0开发者_开发问答))
It seems to me that there is no kind of wrap around monitoring involved. So, if the jiffies(a) were to wrap around and get back fairly close to the timeout(b), then the result would be "false" when it is actually "true".
Let's use some fairly small numbers for this example. Say, time_after(110,150)
where 110 is jiffies and 150 is the timeout. The result will clearly be false - whether jiffies wrapped around or not: 150-110 is always > 0.
So, I just wanted to confirm that I didn't miss something and that is indeed how it is.
Just to be clear, in your example, because 110 is not after 150, time_after(110,150)
should (and does) return false. From the comment:
time_after(a,b) returns true if the time a is after time b.
Also, note that the code does indeed handle wrapping around to 0. To make the following a bit easier to understand, I'll use unsigned and signed one-byte values, i.e. 8-bit 2's complement. But the argument is general.
Suppose b is 253, and five ticks later jiffies has wrapped around to 2. We would therefore expect time_after(2,253)
to return true. And it does (using int8_t to denote a signed 8-bit value):
(int8_t) 253 - (int8_t) 2 == -3 - 2 == -5 < 0
You can try other values, too. This one is trickier, for time_after(128, 127)
, which should be true as well:
(int8_t) 127 - (int8_t) 128 == 127 - (-128) == 255 == -1 (for 8-bit 2's complement) < 0
In reality the type of the expression (int8_t) 127 - (int8_t) 128
would be an int, and the value really would be 255. But using longs the expression type would be long and the equivalent example would be, for time_after( 2147483648, 2147483647)
:
(long) 2147483647 - (long) 2147483648 == 2147483647 - (-2147483648) == 4294967295 == -1 < 0
Eventually, after wrapping around, the "after" jiffies value a
will begin to catch up with the before value b
, and time_after(a,b)
will report false. For N-bit 2's complement, this happens when a
is 2^(N-1) ticks later than b. For N=8, that happens when a
is 128 ticks after b. For N=32, that's 2147483648 ticks, or (with 1 ms ticks) about 25 days.
For the mathematically inclined, I believe that in general time_after(a,b)
returns true iff the least residue (modulo 2^N) of (a-b) is > 0 and < 2^(N-1).
From nearby in the same file:
/*
* 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))
One would hope this means it's pretty well tested.
精彩评论