我已经阅读了“Linux设备驱动程序” (which can be found here)中的第7章,该时间可以用“jiffies”来度量。 stock jiffies变量的问题在于它经常回绕(特别是如果您将CONFIG_HZ设置为1000)。

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

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);

这样对吗?如果当前抖动接近MAX_JIFFY_OFFSET并且msecs_to_jiffies(10)的结果值使some_future_jiffies_value超过该偏移量,会发生什么?它会自动回绕还是我应该添加一些代码来检查呢?是否有使我免于处理此问题的功能?

更新:

为了避免出现缠绕现象,我重写了 sleep 循环:
   // Sleep for the appropriate time
   while (time_after(some_future_jiffies_value, jiffies))
   {
      set_current_state(TASK_INTERRUPTIBLE);
      schedule_timeout(1);
   }

我认为这更便于携带吗?

更新2:

非常感谢“ctuffli”抽出宝贵时间来回答这个问题,并就我的评论提供了一些反馈。我的内核驱动程序现在可以正常工作,与您向我提供所有这些技巧之前的情况相比,它的丑陋程度要小得多。谢谢!

最佳答案

实际上,您在这里实现的是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的详细信息。请确保检查返回值,因为此调用将返回剩余的跳动数。零表示调用睡了指定的毫秒数,而非零值表示调用早已中断了这么多干扰。

关于包装,请参见6.2.1.2节以获取对包装和包装的描述。另外,此post尝试以抽象形式描述包装。

关于c - Linux内核2.6中的计时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/556074/

10-11 15:42