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/