zoukankan      html  css  js  c++  java
  • 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回绕问题。

  • 相关阅读:
    Webservice详解
    Spring IOC/DI和AOP原理
    MySQL 使用JOIN优化子查询
    MySQL 更新语句技巧
    MySQL插入语句解析
    MySQL用户无法登陆问题
    MySQL基础学习(二) 常用SQL命令
    Servlet/JSP-08 EL表达式
    插值和空间分析(一)_探索性数据分析(R语言)
    爱重启的windows,伤不起
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/5748462.html
Copyright © 2011-2022 走看看