On Wed, Feb 26, 2003 at 05:09:50AM +0000, Anticipating a Reply wrote: > Hello Jan , > > Thanks for the reply . > > I understood that we need to do both ,i.e. > satisfy condition & also wakeup , to come out > of "wait_event_interruptible()". > > But this can be achieved using > "sleep_on_interruptible" and doing a > "wakeup_interruptible" after checking > the condition . The difference between wake_up and wake_up_interruptible is a bit strange. You should mostly use plain wake_up, which wakes up both TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE processes. wake_up_interruptible is for special purposes where you need to wake the interruptible sleepers only. > Does "wait_event_interruptible" > need to be used in any specific > scenario or in any particular > situation ? wait_on[_interruptible] is a simple macro around sleep_on! It merely does the three things - puting yourself to the queue, seting TASK_[UN]INTERRUPTIBLE state, checking the condition and actualy calling schedule() in correct order so you can't miss a wake up. So for the common case it saves you some thinking (note that there is no lock - you must assure "atomicity" with correct oredering). Note, that it you use the _interruptible variant, you MUST check the return value and if it returns -ERESTARTSYS, you must return to userland either with -EINTR, -ERESTARTSYS or -ERESTARTNOHAND so pendings signals can be handled. If you return -EINTR, the value is simply propagated to userland. If you return -ERESTARTSYS, signal is handled and your syscall is restarted (unless the signal terminated or the handler exited via a longjump). If you return -ERESTARTNOHAND, your syscall is restarted if the signal was ignored (that is if there is no handler and the action is not to terminate the process (poll uses this)). Other note: in kernel thread, there is no userland to handle signals. So there is no point in interruptible sleep. Important note: you can only sleep in process context. That is, not in interrupts, bottom halves and tasklets. > Kindly explain ,where specifically > do we need to use each of these variants > of wait-sleeps ? > > Thanks in advance . > > Regards ! > > --- Jan Hudec <bulb@ucw.cz> wrote: > On Mon, Feb 24, > 2003 at 11:45:55AM +0000, > > Anticipating a Reply wrote: > > > Hello All , > > > > > > I'am facing a problem in the following > > > kernel module for a 2.4.16 kernel . > > > Here I'am not getting > > > the expected behaviour of > > "wait_event_interruptible". > > > > You are geting the expected behaviour. You are not > > waking up the queue! > > > > The wait_event_interruptible goes to sleep while the > > condition is false. > > When it goes to sleep, you need to wake it up. You > > need to: > > flag = 1; > > wake_up(my_queue); > > > > Note: You should use atomic operations for the flag > > ;-). > > > > > Basically I'am trying to sleep on a > > > a condition (.i.e. a flag value is 0 ) in > > > "read "implementation . I have implemented > > > the unlocking mechanism in "write" implementation > > > (.ie. flag=1 ). > > > > > > But the "read" implementation continues > > > to remain blocked , even if the condition > > > is satisfied when a "write" to the device > > > is done . > > > > > > Kindly suggest me if I'am doing something > > > wrong . I have the code of the driver and > > > test routines below . > > > > > > Thank you in Advance . > > > > > > Regards > > > > > > > > /*************************************************** > > > > > > Trying to write a Kernel module > > > which shows the usage of kernel waitqueue > > > > > > The device acessed is having major=222 minor=0 > > > > > > This module is compiled as : > > > > > > cc -c my.c -I/usr/src/linux/include > > > > > > and inserted as module using : > > > > > > insmod my.o my_major=222 > > > > > > > > > ****************************************************/ > > > > > > #ifndef __KERNEL__ > > > # define __KERNEL__ > > > #endif > > > > > > #ifndef MODULE > > > # define MODULE > > > #endif > > > > > > #include <linux/config.h> > > > #include <linux/module.h> > > > > > > #include <linux/kernel.h> /* printk() */ > > > #include <linux/slab.h> /* kmalloc() */ > > > #include <linux/fs.h> /* everything... */ > > > #include <linux/errno.h> /* error codes */ > > > #include <linux/types.h> /* size_t */ > > > #include <linux/wait.h> > > > #include <asm/page.h> > > > > > > /* Device Major Number */ > > > static int my_major = 0; > > > > > > MODULE_PARM(my_major, "i"); > > > MODULE_AUTHOR("learner"); > > > > > > int flag ; > > > > > > /* Wait queue for this device */ > > > wait_queue_head_t my_queue ; > > > > > > /* > > > * Forwards for our methods. > > > */ > > > int my_open (struct inode *inode, struct file > > *filp); > > > ssize_t my_read(struct file *filp, char *buf, > > size_t > > > count, loff_t *f_pos); > > > ssize_t my_write(struct file *filp, const char > > *buf, > > > size_t count, loff_t *f_pos); > > > int my_release(struct inode *inode, struct file > > > *filp); > > > > > > > > > struct file_operations my_ops = { > > > read: my_read, > > > write: my_write, > > > open: my_open, > > > release: my_release, > > > }; > > > > > > > > > /* > > > * Open the device; all we have to do here is to > > up > > > the usage count and > > > * set the right fops. > > > */ > > > int my_open(struct inode *inode, struct file > > *filp) > > > { > > > MOD_INC_USE_COUNT; > > > return 0; > > > } > > > > > > /* > > > * Reading the Device > > > */ > > > ssize_t my_read(struct file *filp, char *buf, > > size_t > > > count,loff_t *f_pos) > > > { > > > printk( KERN_WARNING "read: Going to sleep on > > wait > > > queue" ); > > > wait_event_interruptible( my_queue, flag ); > > > printk( KERN_WARNING "read: Come out of sleep > > in > > > wait queue" ); > > > printk( KERN_WARNING "read: Data Value %d \n", > > > flag ); > > > return 0; > > > } > > > > > > /* > > > * Writing the Device > > > */ > > > ssize_t my_write(struct file *filp, const char > > *buf, > > > size_t count,loff_t *f_pos) > > > { > > > printk( KERN_WARNING "write: Going to wake up > > > sleeping processes"); > > > flag=1 ; > > > return 0; > > > } > > > > > > /* > > > * Closing the Device > > > */ > > > int my_release(struct inode *inode, struct file > > *filp) > > > { > > > MOD_DEC_USE_COUNT; > > > return 0; > > > } > > > > > > /* > > > * Module housekeeping. > > > */ > > > static int my_init(void) > > > { > > > int result; > > > > > > SET_MODULE_OWNER(&my_ops); > > > > > > result = register_chrdev(my_major, "my", > > &my_ops); > > > if (result < 0) > > > { > > > printk(KERN_WARNING "my: unable to get > > major > > > %d\n", my_major); > > > return result; > > > } > > > > > > if (my_major == 0) > > > my_major = result; > > > > > > init_waitqueue_head( &my_queue ); > > > printk(KERN_WARNING "init: Initialised Wait > > queue > > > \n"); > > > > > > /* Initializing condition Flag to zero */ > > > flag = 0 ; > > > > > > return 0; > > > } > > > > > > static void my_cleanup(void) > > > { > > > unregister_chrdev(my_major, "my"); > > > } > > > > > > module_init(my_init); > > > module_exit(my_cleanup); > > > > > > > > > ******************************************************* > > > TEST ROUTINES > > > > > **************************************************** > > > > > > /* rtest : Program to read device > > > ---------- it should block till the device > > writes > > > to device > > > */ > > > > > > #include<fcntl.h> > > > > > > main() > > > { > > > > > > int fd ; > > > > > > int data ; > > > > > > fd = open("mydev",O_RDONLY ); > > > > > > read( fd, &data, sizeof(data) ); > > > > > > > > > } > > > > > > /* wtest : Program to write device > > > ---------- it should unblocks device blocked > > on > > > read > > > */ > > > > > > #include<fcntl.h> > > > > > > main() > > > { > > > > > > int fd ; > > > > > > int data =0 ; > > > > > > fd = open("mydev",O_WRONLY ); > > > > > > write( fd, &data, sizeof(data) ); > > > > > > } > > > ******************************************** > > > > > > > > > > > > ________________________________________________________________________ > > > Missed your favourite TV serial last night? Try > > the new, Yahoo! TV. > > > visit http://in.tv.yahoo.com > > > -- > > > Kernelnewbies: Help each other learn about the > > Linux kernel. > > > Archive: > > http://mail.nl.linux.org/kernelnewbies/ > > > FAQ: http://kernelnewbies.org/faq/ > > > > > > ------------------------------------------------------------------------------- > > Jan 'Bulb' Hudec <bulb@ucw.cz> > > -- > > Kernelnewbies: Help each other learn about the Linux > > kernel. > > Archive: > > http://mail.nl.linux.org/kernelnewbies/ > > FAQ: http://kernelnewbies.org/faq/ > > > > ________________________________________________________________________ > Missed your favourite TV serial last night? Try the new, Yahoo! TV. > visit http://in.tv.yahoo.com > ------------------------------------------------------------------------------- Jan 'Bulb' Hudec <bulb@ucw.cz> -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/