Linux kernel 等待可中断的等待事件的周期性事件

Linux kernel 等待可中断的等待事件的周期性事件,linux-kernel,linux-device-driver,embedded-linux,Linux Kernel,Linux Device Driver,Embedded Linux,我正在编写一个内核模块,它使用外部时钟执行计时功能。基本上,模块从时钟计数脉冲,每隔一段时间滚动一次。用户进程可以使用ioctl请求在特定计数时被唤醒;然后,它们执行一些任务并调用相同的ioctl,以等待下次出现相同的计数。通过这种方式,它们可以使用此外部定时定期执行 我已经创建了一个wait\u queue\u head\ts数组,每个可用的调度时隙对应一个(即,如上所述的每个“计数”)。当用户进程调用ioctl时,我只需调用sleep\u on(),ioctl参数指定调度槽,从而指定等待队列

我正在编写一个内核模块,它使用外部时钟执行计时功能。基本上,模块从时钟计数脉冲,每隔一段时间滚动一次。用户进程可以使用ioctl请求在特定计数时被唤醒;然后,它们执行一些任务并调用相同的ioctl,以等待下次出现相同的计数。通过这种方式,它们可以使用此外部定时定期执行

我已经创建了一个
wait\u queue\u head\t
s数组,每个可用的调度时隙对应一个(即,如上所述的每个“计数”)。当用户进程调用ioctl时,我只需调用
sleep\u on()
,ioctl参数指定调度槽,从而指定等待队列。当内核模块接收到时钟脉冲并增加计数时,它会唤醒与该计数对应的等待队列

我知道应该使用
sleep\u on()
,因为在测试进程是否应该睡眠和相应调用
sleep\u on()
之间,状态可能会发生变化。但在这种情况下,我不会在睡觉前做这样的测试,因为醒着的事件是周期性的。如果我“只是错过”了一个唤醒事件,因为另一个事件很快就会到来,这并不重要(事实上,如果调用ioctl的时间非常接近指定的调度时间段,那么就出现了问题,我宁愿等到下一个时间段)

我已经研究过如何使用
wait\u event\u interruptible()
,这被认为是更安全的,但我不知道如何使用
wait\u event\u interruptible
所需的条件参数
wait\u event\u interruptable
将在睡眠前检查此条件,但我希望它在调用ioctl时始终处于睡眠状态。我可以使用一个我在睡觉前清除并在起床前设置的标志,但我担心这在等待队列中有多个进程的情况下可能不起作用-一个进程可能完成,并在下一个进程被唤醒之前清除标志


我担心这件事对吗?或者,是否保证等待队列中的所有进程在任何进程运行之前都会被唤醒(因此可以清除该标志)?有没有更好的方法来实施这样一个系统?使用
sleep\u on()
,实际上可以吗?(如果是,是否有可中断的
sleep\u on()
版本?

可中断的
sleep\u on
版本是
interruptable\u sleep\u on
。请注意,自内核3.15以来,睡眠函数已被删除

至于
wait\u event\u interruptable
,requirement
我希望它在调用ioctl时总是处于休眠状态。
对它来说并不常见。您可以使用标志,但该标志应为每个进程(或每个计划槽)。或者您可以将等待计数修改为至少
当前计数+1


在这种不常见的情况下,您可以使用由宏
wait\u event\u interruptable
组成的块,而不是宏
wait\u event\u interruptable
,并按照需要的方式排列它们。一般来说,任何等待都可以通过这种方式实现。

可中断版本的
睡眠时间
可中断睡眠时间
。请注意,自内核3.15以来,睡眠函数已被删除

至于
wait\u event\u interruptable
,requirement
我希望它在调用ioctl时总是处于休眠状态。
对它来说并不常见。您可以使用标志,但该标志应为每个进程(或每个计划槽)。或者您可以将等待计数修改为至少
当前计数+1


在这种不常见的情况下,您可以使用由宏
wait\u event\u interruptable
组成的块,而不是宏
wait\u event\u interruptable
,并按照需要的方式排列它们。通常,任何等待都可以通过这种方式完成。

谢谢。因为我的内核仍然有
interruptable\u sleep\u on()。我没有想过实现每个进程的标志,然后将其传递到ioctl中-这听起来像是使用
wait\u event\u interruptable()
的最佳方式,如果需要的话。谢谢。因为我的内核仍然有
interruptable\u sleep\u on()。我没有想过实现每个进程的标志,然后将其传递到ioctl中——这听起来像是使用
wait\u event\u interruptible()
的最佳方式,如果我需要的话。