2011-06-04 37 views
3

基於我在linux/include/linux/jiffies.h找到的代碼:time_after()linux宏對於jiffies的繞回是100%的傻瓜嗎?

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),那麼當結果實際爲「true」時,結果將爲「false」。

讓我們在這個例子中使用一些相當小的數字。說,time_after(110,150)其中110是jiffies和150是超時。其結果顯然是錯誤的 - 不管的jiffies周圍或不裹:150-110總是> 0

所以,我只是想確認我沒有錯過一些東西,這確實是怎麼回事。

回答

1

從在同一文件中附近:

/* 
* 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)) 

人們希望,這意味着它是很好的測試。

+0

哦,我毫不懷疑,這是看一遍測試。但是,這並不一定證明我錯了。這意味着一定有這樣做的理由。我的理論是,一個進程工作/休眠幾乎不可能~50天(這大概是它在首次將jiffies讀取到的情況下完成一個具有1000HZ定時器頻率的32位jiffies變量的整個循環)用作超時值,然後檢查time_after()。所以,這樣一個簡單的宏是令人滿意的。 – Tux 2011-06-04 04:43:36

4

只是要清楚,你的榜樣,因爲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已經纏到2.因此,我們期望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.但是,使用多頭表達式類型會長和等效例子是,對於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毫秒蜱)約25天。如果(a-b)的最小殘基(模2^N)大於0並且< 2 ^(N-1),我相信一般time_after(a,b)返回爲真。