Messages in this thread | | | Date | Fri, 13 Aug 1999 16:35:16 +0200 | From | Andreas Bombe <> | Subject | Re: Problems writting a CHAR Driver with interruptible_sleep (wait_queu e) |
| |
On Thu, Aug 12, 1999 at 02:51:33PM -0300, Raul Dias wrote: > > Here is how it should work: > > When a user tries to read the device (/dev/chaos0), > the chaos_read() function (responsable for file reading in the module) > have to do an "outb(board)" to "ask" the board to acquire data. > > then it goes to sleep with an interruptible_sleep_on(); > > When the DATA is ready, it does an interrupt. > The interrupt handler uses a wake_up_interruptible() to wake the > process on chaos_read() that will actually read the data (inb) and > output it. > > > Everything is fine, except that: > > sometimes, after a few reads, the interrupt occurs before the proccess > complete the "interruptible_sleep_on()" call.
There is an easy, but probably not so obvious fix: do the things in (interruptible_)sleep_on yourself in the right order. There is no prepackaged function doing that for you.
Take a look at these function's implementation to understand the following example better.
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) DECLARE_WAITQUEUE(wait, current); #else struct wait_queue wait; wait.task = current; #endif
add_wait_queue(&wait_queue, &wait); current->state = TASK_INTERRUPTIBLE; /* or TASK_UNINTERRUPTIBLE */
outb(ioport, 0xFF); /* Ask for data */
schedule(); /* Go to sleep (or not) */ remove_wait_queue(&wait_queue, &wait); /* Have a nice oops if you forget to remove */
data = inb(ioport); /* There you go */
This solves the problem by setting the state to sleep and only after that to trigger the interrupt. If the interrupt happens and wake_up_interruptible() is called before the schedule() then current->state will be TASK_RUNNING again and make schedule() return immediately (or not, if it finds a better task to run).
-- Andreas E. Bombe <andreas.bombe@munich.netsurf.de> http://home.pages.de/~andreas.bombe/ RSA 0x886663c9 30 EC 09 73 84 7B 55 83 C4 7A 91 D9 9D C5 4B B0 DSA 0x04880A44 72E5 7031 4414 2EB6 F6B4 4CBD 1181 7032 0488 0A44
- 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/
| |