jiffies溢出與時間先后比較-time_after,time_before【轉】


轉自:http://www.cnblogs.com/hfyinsdu/p/4600052.html

參考地址:

http://blog.csdn.net/jk110333/article/details/8177285

http://blog.chinaunix.net/uid-23629988-id-3477143.html

補碼的說明:

http://baike.baidu.com/link?url=qz8yHnVCqqKWguIDLOfcRZDBfLy4h1ekzspS7Rkznu8RdvMYm0QnK_vhBTHP_SSQRzV--lhiGS7lF32fB4xC5q

 

說明:

計算機位數限制,能表示的數值范圍也是有限的;比如129在8位的計算機中,表示為1000 0001,按有符號數讀取的話就是-127,無符號讀取就是129.

所以在判斷結果是否小於0的時候,應該看存儲的二進制的最高位是否為1.

比如127-(-3)=130,雖然看起來是個正數,但是在8位計算機中,以有符號數讀取的話就是負數,因為130存儲為1000 0010.

 

Linux內核為了解決jiffies的回繞問題,提供了現成的宏,用於判斷時間的先后。今天就以time_after為例,看看它為什么可以應對jiffies的回繞問題。

/*
 *  These inlines deal with timer wrapping correctly. You are
 *  strongly encouraged to use them
 *  1. Because people otherwise forget
 *  2. Because if the timer wrap changes in future you won't have to
 *     alter your driver code.
 *
 * time_after(a,b) returns true if the time a is after time b.
 *
 * Do this with "<0" and ">=0" to only test the sign of the result. A
 * good compiler would generate better code (and a really good compiler
 * wouldn't care). Gcc is currently neither.
 */
#define time_after(a,b)     \
    (typecheck(unsigned long, a) && \
     typecheck(unsigned long, b) && \
     ((long)(b) - (long)(a) < 0))

 

這個宏定義很簡單,可以忽略typecheck,其就是用於檢查參數的類型是否正確。如這里就是用於判斷a和b是否為unsigned long類型。

 

最關鍵的就是((long)(b) - (long)(a) < 0)。

 

在理想的情況下,時間是可以不停增長的,后來的時間值一定比前面的值大。所以b-a一定小於0。然后計算機的世界不是一個理想的世界,

所有的值都有其位數限制的。在32位平台上,long的位數為32位。按照二進制補碼的表示方式,從0到0x7fffffff的區間,值是逐漸遞增的。

從0x80000000到0xFFFFFFFF這個區間,值是逐漸縮小的。

這就有4中情況:

1. a和b都在0到0x7FFFFFFF之間:

a若在b之后發生,則a的值大於b。那么(long)b-(long)a<0。

2. a和b都在0x80000000到0xFFFFFFFF之間:

a若在b之后發生,b為較大的負數,a為較小的負數,那么(long)b-(long)a<0。

3. b在0到0x7FFFFFFF之間,而a在0x80000000到0xFFFFFFFF之間:

a為負數。b-a,相當於b+(-a)。只要a與b之間的絕對差值小於或等於0x80000000,則b+(-a)仍然為負數。

4. b在0x80000000到0xFFFFFFFF之間,而a在0到0x7FFFFFFF之間:

b為負數,b-a等於b+(-a)。同樣在a與b之間的絕對差值小於或等於0x80000000,則b+(-a)仍然為負數。

 

總結這四種情況,在a與b的絕對值相差不到0x80000000時,這個宏是正確的。而在利用jiffies作為時間度量和比較單位時,時間差並不會太大。

所以這個time_after可以有效的避免jiffies回繞問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM