9

我已经阅读了“Linux 设备驱动程序” (可以在此处找到)中的第 7 章,时间可以用“jiffies”来衡量。stock jiffies 变量的问题在于它非常频繁地回绕(特别是如果您将 CONFIG_HZ 设置为 1000)。

在我的内核模块中,我保存了一个设置为未来某个时间的 jiffies 值,并在稍后将其与当前的“jiffies”值进行比较。我已经了解到有些函数会考虑 32 位 jiffy 换行,因此要比较我正在使用的两个值:

if (time_after(jiffies, some_future_jiffies_value))
{
   // we've already passed the saved value
}

我的问题来了:所以现在我想将“some_future_jiffies_value”设置为“now + 10ms”。这可以通过执行以下操作轻松完成:

some_future_jiffies_value = jiffies + msecs_to_jiffies(10);

它是否正确?如果当前 jiffies 接近 MAX_JIFFY_OFFSET 并且 msecs_to_jiffies(10) 的结果值使 some_future_jiffies_value 超过该偏移量,会发生什么情况?它会自动环绕还是我应该添加一些代码来检查这个?有没有让我不必处理这个问题的功能?

更新:

为了避免环绕的东西,我重写了我的睡眠循环:

   // Sleep for the appropriate time
   while (time_after(some_future_jiffies_value, jiffies))
   {
      set_current_state(TASK_INTERRUPTIBLE);
      schedule_timeout(1);
   }

我认为这更便携对吧?

更新 2:

非常感谢 'ctuffli' 抽出时间回到这个问题,并为我的评论提供一些反馈。我的内核驱动程序现在工作正常,与您向我提供所有这些提示之前的情况相比,它的丑陋程度要低得多。谢谢!

4

1 回答 1

8

你在这里实现的本质上是 msleep_interruptible() (linux/kernel/timer.c)

/**
 * msleep_interruptible - sleep waiting for signals
 * @msecs: Time in milliseconds to sleep for
 */
unsigned long msleep_interruptible(unsigned int msecs)

此函数的优点是规范以毫秒为单位,并隐藏了内部 jiffies 包装的细节。请务必检查返回值,因为此调用返回剩余的 jiffies 数。零表示呼叫休眠了指定的毫秒数,而非零值表示呼叫提前中断了这么多时间。

关于包装,请参阅第6.2.1.2节了解 jiffies 和包装的说明。此外,这篇文章试图在摘要中描述包装。

于 2009-02-17T19:22:47.103 回答