本文介绍了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中的溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!