正在等待具有wait_event_interruptible的周期性事件



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

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

我知道使用sleep_on()被认为是不好的做法,因为在查看进程是否应该休眠的测试和对sleep_on()的相应调用之间,状态可能会发生变化。但在这种情况下,我不会在睡觉前进行这样的测试,因为清醒的事件是周期性的。如果我"只是错过"了一个醒着的事件,因为另一个事件很快就会到来,这并不重要(事实上,如果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_interruptibleI want it to always sleep when the ioctl is invoked.的需求对它来说并不常见。你可以使用一个标志,但这个标志应该是每个进程(或每个调度槽(。或者您可以将等待计数修改为至少current_count + 1

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

最新更新