On Wed, Feb 26, 2003 at 11:47:19AM +0000, Anticipating a Reply wrote: > Hello Jan , > > Thanks again . > > But maybe you missed telling me how > > int wait_event_interruptible(wait_head_queue_t qu, > int condition ); < > is different from > > int interruptible_sleep_on(wait_head_queue_t *queue ); > > I presume both are different in the > way they work . They work the same way. But wait_event[_interruptible] checks a condition while [interruptible_]sleep_on does not. > So I wanted to know what are the specific > situations in which each of them will be used ? If a sleep is conditional on some condition, you need wait_event. If you want to uncodnitionaly put yourself to sleep on a wait queue, you use sleep_on. (and respective interruptible variants). And note, that while(condition) sleep_on(queue); is not the same as wait_event and is usualy WRONG. (because there is a race condition). I strongly suggest you take a look at the real primitives - set_current_state and wait_queue_add. > I'am sorry if I could not understand the > difference from the nice explanation you > have given earlier. > > Thank you in advance . > > Regards ! > > > > > --- Jan Hudec <bulb@ucw.cz> wrote: > 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/ > > > > ________________________________________________________________________ > 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/