本文介绍了Linux如何处理Jiffies中的溢出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下代码:

if (timeout > jiffies)
{
    /* we did not time out, good ... */
}
else
{
    /* we timed out, error ...*
}

当Jiffies值不溢出时,此代码工作得很好。但是,当Jiffie溢出并绕回到零时,此代码无法正常工作。

Linux显然提供了用于处理此溢出问题的宏

#define time_before(unknown, known) ((long)(unkown) - (long)(known) < 0)

上面的代码在替换为此宏时应该是安全的:

// SAFE AGAINST OVERFLOW
if (time_before(jiffies, timeout)
{
    /* we did not time out, good ... */
}
else
{
    /* we timed out, error ...*
}

但是,TIME_BEFORE(和其他时间宏?)背后的基本原理是什么?

TIME_BEFORE(Jiffies,Time Out)将扩展为

((long)(jiffies) - (long)(timeout) < 0)

此代码如何防止溢出问题?

推荐答案

让我们真正试一试:

#define time_before(unknown, known) ((long)(unkown) - (long)(known) < 0)

我会把事情简化得很多,因为along只有两个字节,所以在十六进制中它的值可以在[0, 0xFFFF]的范围内。

现在,它是有符号的,因此范围[0,0xFFFF]可以分为两个单独的范围[0,0x7FFF],[0x8000,0xFFFF]。这些值对应于值[0,32767]、[-32768,-1]。图表如下:

[0x0      -              -                  -               0xFFFF]
[0x0                       0x7FFF][0x8000                   0xFFFF]
[0                         32,767][-32,768                      -1]

假设timeout是32,000。我们想检查我们是否在超时时间内,但实际上我们溢出了,所以jiffies是-31,000。因此,如果我们天真地尝试计算jiffies < timeout,我们将得到True。但是,输入以下值:

   time_before(jiffies, offset)
== ((long)(jiffies) - (long)(offset) < 0)
== (-31000 - 32000 < 0)             // WTF is this. Clearly NOT -63000
== (-31000 - 1768 - 1 - 30231 < 0)  // simply expanded 32000
== (-32768 - 1 - 30232 < 0)         // this -1 causes an underflow
== (32767 - 30232 < 0)
== (2535 < 0)
== False

jiffies是4个字节,而不是2个,但同样的原理也适用。这有帮助吗?

这篇关于Linux如何处理Jiffies中的溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-17 01:04