Messages in this thread | | | Date | Thu, 30 Dec 1999 21:41:33 +0200 (IST) | From | Mark Mokryn <> | Subject | Re: sleep_on, wake_up question |
| |
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/
| |