我有一个设备驱动程序,硬件在其中不断将数据流传输到内核空间中的循环缓冲区中。当用户调用read()
时,数据从该缓冲区移动到调用者的缓冲区。如果硬件填充DMA描述符(即准备好更多数据)或硬件遇到错误,则会触发中断。无论哪种情况,中断处理程序都将工作安排在下半部分。
下半部分确定中断是由硬件故障还是数据可用引起的。无论哪种情况,它都会设置一些标志,以使read()
系统调用知道发生了什么。设置完上述标志后,下半部分将调用wake_up_interruptible(&my_waitqueue);
在read()
系统调用中,如果内核缓冲区中没有可用数据,我想阻塞一些超时。如果超时到期,我只是让呼叫者知道数据不可用。结果,我打电话给wait_event_interruptible_hrtimeout(my_waitqueue, (error || data_ready), my_timeout);
,基本上,我阻止等待错误条件或数据可用。
我的问题与这些线程的顺序(即下半部分和read()
调用)是否重要有关。特别是,我想知道wait_event_interruptible_hrtimeout()
是否总是等待有人唤醒它吗?如果以前曾打过wake_up_interruptible()
,该怎么办?
说不定,我担心以下情况:
read()
系统调用而言,向循环缓冲区的传输是独立发生的。wake_up_interruptible()
。请注意,由于这是硬件故障,因此不会再触发任何中断,并且在重置设备之前,我们不会再次运行下半部分。read()
。现在,我们进入包含wait_event_interruptible_hrtimeout()
的代码行。是阻止我们唤醒等待的等待,还是等待队列知道上一次对wake_up_interruptible()
的调用?基本上,我想知道是否需要在调用wait_event_interruptible_hrtimeout()
之前先检查传递给(error || data_ready)
(即wait_event_interruptible_hrtimeout()
)的条件。
答案 0 :(得分:0)
由于Tsyvarev,我决定进一步研究内核源代码。
这是我发现的东西:
#define wait_event_interruptible_hrtimeout(wq, condition, timeout) \
({ \
long __ret = 0; \
might_sleep(); \
if (!(condition)) \
__ret = __wait_event_hrtimeout(wq, condition, timeout, \
TASK_INTERRUPTIBLE); \
__ret; \
})
首先检查条件,这意味着如果我获取数据或发生硬件故障,则不会阻塞,因为这是我传递给此函数的条件。