【问题标题】:linux kernel: understand how jiffies diff is calculatedlinux内核:了解jiffies diff是如何计算的
【发布时间】:2020-08-31 19:21:57
【问题描述】:

我在内核中遇到了以下代码:

/*
 * Have the 32 bit jiffies value wrap 5 minutes after boot
 * so jiffies wrap bugs show up earlier.
 */             
#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))

static inline u32 cstamp_delta(unsigned long cstamp)
{
        return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
}

cstamp 的值在 jiffies 中。

这是来自net/ipv4/devinet.c 的代码,其中实现了每个接口的 IP 地址(除其他外)。

我看到 INITIAL_JIFFIES 宏取 5 分钟 (300) 的值并将其转换为 jiffies (-300*HZ),并且类型转换确保正确的值包装。

但是为什么它显式设置为负值(-300*HZ)?

我不确定,cstamp_delta() 以什么单位返回?

【问题讨论】:

    标签: linux time linux-kernel


    【解决方案1】:

    为什么显式设置为负值 (-300*HZ)?

    这不是负值。该值被转换为unsigned int,因此它是正数,更准确地说是UINT_MAX - 300*HZ,这意味着最终值将在达到最大无符号32 位整数值之前5 分钟。正如评论所述,这是为了检测部分代码错误地将jiffies 处理为 32 位值。

    我不确定,cstamp_delta() 以什么单位返回?

    好吧,cstamp - INITIAL_JIFFIES 只是计算内核启动时间的总滴答数。将此值除以 HZ 会返回从启动时间算起的 总数。由于该值首先乘以 100,因此最终结果是从引导时间经过的 百分之一秒 的总数。

    由于u32被用作返回类型,这个函数的返回值当然会相对“很快”回绕,在大约1年零4个月的运行时间(2^32/100/60/60 /24/356)。

    【讨论】:

    • 非常感谢您的解释。双重类型转换的目的是什么?第一次到unsigned int,然后到unsigned long(我假设是因为jiffies被定义为长)。
    • 第一个 (unsigned int) 只是将值修整为 32 位并将溢出设置为 UINT_MAX - 300*HZ,第二个 (unsigned long) 是强制转换为正确的 final类型。
    猜你喜欢
    • 1970-01-01
    • 2021-06-01
    • 2012-11-19
    • 1970-01-01
    • 2012-06-08
    • 2013-01-06
    • 2013-05-27
    • 2014-02-05
    • 2013-10-20
    相关资源
    最近更新 更多