Messages in this thread | | | Subject | Re: Problems writting a CHAR Driver with interruptible_sleep (wait_queu e) | Date | Sat, 14 Aug 1999 15:33:43 +0100 | From | David Woodhouse <> |
| |
rmk@arm.linux.org.uk said: > Benjamin LaHaise writes: > > current->state = TASK_INTERRUPTIBLE; > > add_wait_queue(&my_wait_queue, &wait); > > That should be: > add_wait_queue(&my_wait_queue, &wait); > current->state = TASK_INTERRUPTIBLE; > > otherwise there is a chance that the interrupt could occur between > the TASK_INTERRUPTIBLE and the add_wait_queue. If this does happen, > the task will not be on my_wait_queue, and therefore the state will > not be set to TASK_RUNNING.
Conversely, think about what happens with your version if the IRQ arrives between the add_wait_queue and the TASK_INTERRUPTIBLE: The task will be on a wait queue, and the state will be set to TASK_RUNNING, but will be immediately set to TASK_INTERRUPTIBLE afterwards. The effect is the same.
The trick is to start the hardware after _both_ of these have already happened - that way, there's no chance that the completion interrupt will arrive in between.
However, that's not always possible. Sometimes your event was started asynchronously, and you have to wait for completion (e.g. Flash erase, followed by a separate sync() call). Or possibly you expect the hardware to finish immediately in the majority of times, and you don't always want to schedule at all.
In that case, you can do something like the following:
initiate_hardware();
/* Do other stuff as necessary, including possibly returning to the user */
...
/* Cleanup or completion call ... */
current->state = TASK_INTERRUPTIBLE; // Race here as rmk points out, but // it doesn't matter because we clean it up ourselves. add_wait_queue(&my_wait_queue, &wait);
if ( !hardware_has_completed() ) { schedule(); if (signal_pending(current)) ret = -ERESTARTSYS; }
current->state = TASK_RUNNING; remove_wait_queue(&my_wait_queue, &wait); return ret;
---- ---- ---- David Woodhouse David.Woodhouse@mvhi.com Office: (+44) 1223 810302 Project Leader, Process Information Systems Mobile: (+44) 976 658355 Axiom (Cambridge) Ltd., Swaffham Bulbeck, Cambridge, CB5 0NA, UK. finger dwmw2@ferret.lmh.ox.ac.uk for PGP key.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |