【问题标题】:Jiffies Counter Over Flow case + LinuxJiffies Counter Over Flow 案例 + Linux
【发布时间】:2015-02-12 03:34:38
【问题描述】:

Jiffies 计数器返回一个大小为四个字节的无符号整数。当计数器达到最大值时,它会再次从 0 重新开始。我将用旧值减去最新值以获得持续时间。那么我应该如何考虑旧值是最大值而新值大于零的情况,这样我会得到错误的持续时间?

【问题讨论】:

    标签: linux math counter integer-overflow


    【解决方案1】:

    您无需执行任何操作,您将获得正确的持续时间(只要您使用四个字节的无符号整数进行所有计算)。这就是以固定宽度二进制算术实现的整数值的魔力。

    这里是一个 8 位无符号整数的例子。你实际上可以看到,即使有溢出,差异仍然有效。

    236 - 221 = 11101100 - 11011101 = 11101100 + 00100011 = 00001111 = 15
    251 - 236 = 11111011 - 11101100 = 11111011 + 00010100 = 00001111 = 15
     10 - 251 = 00001010 - 11111011 = 00001010 + 00000101 = 00001111 = 15
     25 -  10 = 00011001 - 00001010 = 00011001 + 11110110 = 00001111 = 15
       ...
    

    当持续时间与计数器的最大值相比不时,您的唯一问题就出现了,即当它可以大于最大值的一半时。

    【讨论】:

    • 嗨。感谢您的响应。考虑我有两个变量如下:old_time,new_time。在连续的while循环中,我将像“ if((new_time-old_time) == 15 ),即 15 秒。但是当发生溢出时,我会错过那个特定的持续时间。有什么情况可以处理这种情况吗?
    • 没有。你不会错过的。这就是我回答的重点。即使在溢出的情况下,new_time-old_time 的结果也会是 15。
    【解决方案2】:

    只有当你的两个事件 a 和 b,a 实际发生在 b 之前,并且它们之间的距离小于 2^(32-1) 时,这个建议才是正确的。如果你计算(b-a),那么你会得到正确的答案。如果您从较大的无符号数中减去较小的无符号值(认为定义了它们的时间顺序),那么您可以得到您想要的答案的负数。

    因此,您还需要考虑新的循环比较操作(请参阅 Linux time_after、time_before 并使用它们等)。

    有符号和无符号比较都是错误的,因为环绕的计数器与有符号或无符号数字并不完全相同。考虑 8 位的情况:

    a=250, b=20   #8-bit sequence number a was created before b
    a=120, b=130  #8-bit sequence number a was created before b
    

    具有相同位数的有符号值和无符号值之间的主要区别在于比较运算符的实现。由于决定用 1 或 0 对负值进行符号扩展,因此在分配给具有更多位的值时,有符号与无符号非常重要。

    考虑一个新的小于为环绕数字设计的定义:

    LT_CIRCULAR_32(250,5)     == True   //like signed?   
    LT_CIRCULAR_32(0,11)      == True
    LT_CIRCULAR_32(127,138)   == True   //like unsigned?
    

    只要第一个值和第二个值之间的实际距离始终小于 2^(32-1),这种比较就有效。

    想象一个有 256 个位置的圆,逆时针方向 a 和 b。如果 a 可以以小于 2^(8-1) 的增量达到 b,则“a

    #define LT_CIRCULAR_LONG(a,b)  ((((long)(b)-(long)(a)) < 0)==0)
    

    这就是为什么 time_after 看起来是这样的原因。 b 和 a 的强制转换分别确保符号扩展是一致的。使值带符号并检查是否小于零是测试高位的技巧。

    我正在观察一位开发人员正在用 jiffies 处理这个问题(即:-300 jiffies),并且已经看到它使用 TCP 序列号和一些其他类似的计数器。所以,2s恭维并不能解决所有问题。

    【讨论】:

      猜你喜欢
      • 2012-11-19
      • 1970-01-01
      • 2023-03-29
      • 2015-12-10
      • 1970-01-01
      • 2012-08-12
      • 2013-02-14
      • 2020-08-31
      • 1970-01-01
      相关资源
      最近更新 更多