等待 wait_event_interruptible 的周期性事件

Waiting for a periodic event with wait_event_interruptible

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

我创建了一个 wait_queue_head_t 数组,每个可用的日程表槽一个(即每个 "count",如上所述)。当用户进程调用 ioctl 时,我只需调用 sleep_on() 并使用 ioctl 参数指定调度槽,从而指定等待队列。当内核模块接收到时钟脉冲并增加计数时,它会唤醒与该计数对应的等待队列。

我知道使用 sleep_on()considered bad practice,因为状态可能会在测试进程是否应该休眠和相应调用 [=12] 之间发生变化=].但在这种情况下,我不会在睡觉前执行此类测试,因为醒来事件是周期性的。如果我 "just miss" 一个唤醒事件并不重要,因为另一个事件很快就会到来(事实上,如果在非常接近指定的调度槽时调用 ioctl,那么就会出现问题,我宁愿等到下一个无论如何插槽)。

我看过使用 wait_event_interruptible(),这被认为更安全,但我不知道为 wait_event_interruptible 要求的条件参数添加什么。 wait_event_interruptible 将在休眠前检查此条件,但我希望它在调用 ioctl 时始终休眠。我可以使用我在睡觉前清除并在醒来前设置的标志,但我担心这在等待队列中有多个进程的情况下可能不起作用 - 一个进程可能会在下一个进程之前完成并清除标志醒了。

我担心这个是对的吗?还是 wait_queue 中的所有进程都保证在任何 运行 之前被唤醒(因此可以清除标志)?有没有更好的方法来实施像这样的系统?只使用 sleep_on() 真的可以吗? (如果有,是否有可中断的 sleep_on() 版本?)

sleep_on 的可中断版本是 interruptible_sleep_on。请注意,从内核 3.15 开始,睡眠功能已被删除。

至于wait_event_interruptible,要求I want it to always sleep when the ioctl is invoked.不常见。你可以使用一个标志,但这个标志应该是每个进程(或每个调度槽)。或者您可以将等待的计数修改为至少 current_count + 1.

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