【问题标题】:Timekeeping in Linux kernel 2.6Linux 内核 2.6 中的计时
【发布时间】:2009-02-17 09:24:13
【问题描述】:

我已阅读“Linux 设备驱动程序”(which can be found here) 中的第 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' 抽出时间来回答这个问题,并为我的 cmets 提供一些反馈。我的内核驱动程序现在工作正常,与您向我提供所有这些提示之前的情况相比,它的丑陋程度要低得多。谢谢!

【问题讨论】:

  • 另一个想法:使用 get_jiffies_64() 是否可以让我不必考虑环绕,让我做简单的数学运算?

标签: c linux-kernel


【解决方案1】:

你在这里实现的本质上是 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 和包装的说明。此外,post 试图在摘要中描述包装。

【讨论】:

  • 如果我查看 msleep_interruptible 的源代码,它看起来确实非常相似!如果我理解正确,我仍然需要考虑该函数的返回值,因为可中断睡眠可以早于预期返回,对吧?
  • 关于超过 MAX_JIFFY_OFFSET 标记的超时,你知道这是否可以吗?我看到它在内核源代码中发生了很多,但这是我想知道的更理论的事情。感谢您抽出宝贵时间做出回应! :)
猜你喜欢
  • 1970-01-01
  • 2011-09-03
  • 2014-08-22
  • 2019-03-08
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
相关资源
最近更新 更多