问题
Briefly, in a read
method i check if a variable is 0 and if it's i put the current process to sleep:
static ssize_t soc2e_read(struct file *filp, char __user *buf,
size_t count, loff_t * ppos)
{
...
struct soc2e_dev *soc2e = (struct soc2e_dev *)filp->private_data;
if (soc2e->bytes == 0)
{
if (wait_event_interruptible(soc2e->wlist, (soc2e->bytes > 0)))
return -ERESTARTSYS;
}
...
}
I must wake up the process in an interrupt handler:
static irqreturn_t soc2e_irq_handler(int irq, void *dev)
{
...
struct soc2e_dev *soc2e = dev;
...
soc2e->bytes += read_bytes;
wake_up_interruptible(&soc2e->wlist);
return IRQ_HANDLED;
}
I think (and also verified) that here could be a problem of atomicity. What happen if interrupt comes between if (soc2e->bytes == 0)
in read
method and the call to wait_event_interruptible
. Maybe the process won't be waked up until next interrupt. What is the best way to resolve this issue?
回答1:
The wait_event_interruptible
macro is already pretty careful about avoiding the race you describe. In fact, you don't need the initial check of your bytes
member -- you could just write in your read
method:
if (wait_event_interruptible(soc2e->wlist, soc2e->bytes > 0))
return -ERESTARTSYS;
because wait_event_interruptible()
will not actually go to sleep if the condition is true (or becomes true while it's in the middle of going to sleep).
来源:https://stackoverflow.com/questions/9809140/how-correctly-wake-up-process-inside-interrupt-handlers