Re: sleep_on, wake_up question

Mark Mokryn (mark@psl.technion.ac.il)
Thu, 30 Dec 1999 21:41:33 +0200 (IST)


Okay, I checked Rubini's book, and he has a solution which seems elegant
enough (Alan suggested it in a previous post, but here's the full
expansion).
Here's the code:

struct wait_queue wait = {current, NULL};

add_wait_queue(&my_q, &wait);
current->state = TASK_INTERRUPTIBLE;
play_with_my_hardware_which_will_eventually_generate_an_interrupt();
schedule();
remove_wait_queue(&my_q, &wait);

my_isr()
{
...
wake_up_interruptible(&my_q);
...
}

The story is that if the interrupt beats the schedule(), then the task
will be set to state TASK_RUNNING via the wake_up_interruptible call, and
the process removes itself from the wait queue. This should work well
enough, but I still think that having a bulletproof version of sleep_on is
far more elegant, and may prevent some painful mistakes for driver
writers.
Just one more question (I'm new to linux drivers, was in NT driverland
till recently, glad to get the needle out of my vein :)
In the code above, is there any possibility of the process' state being
changed prior to the schedule() call (i.e. can nonblocking kernel code be
context-switched out?)

thanks,
-Mark

>
> Mark,
> I checked a later kernel and it can get stuck. However, you can
> use sleep_on_timeout() to make sure you do get awakened. A
> check of something the interrupt should have written will let you
> know what happened, i.e,...
>
> spin_lock_irqsave(&device_lock, flags);
> if(irq_flag)
> {
> spin_unlock_irqrestore(&device_lock, flags);
> //// You already got interrupted, fix this first!
>
> spin_lock_irqsave(&device_lock, flags);
> }
> irq_flag = 0;
> tickle_hardware(); /* Interrupts are off */
> spin_unlock_irqrestore(&device_lock, flags);
>
>
> interruptible_sleep_on_timeout(&wait, time * HZ);
> spin_lock_irqsave(&device_lock, flags);
> if(irq_flag)
> /// Was interrupted
> else
> /// Was not
> spin_unlock_irqrestore(&device_lock, flags);
>
>
> isr()
> {
> irq_flag = 1;
> wake_up_interruptible(&wait);
> }
>
> Just check program flow under a spin-lock and it should be safe
> in SMP. Keep the code under the locks short. I have a GPIB driver
> which will have to be modifed once a new kernel is released. It
> does about 100,000 interrupts per second without losing data, but
> it won't even compile with a new kernel because some types have
> changed. So I haven't done anything with it recently.
>
> Cheers,
> Dick Johnson
>
> Penguin : Linux version 2.3.13 on an i686 machine (400.59 BogoMips).
> Warning : The end of the world as we know it requires a new calendar.
> Seconds : 125933 (until Y2K)
>
>
> -
> 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/
>

-
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/