Re: Problem with "wait_event_interruptible"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 .

 Does "wait_event_interruptible" 
need to be used in any specific 
scenario or in any particular 
situation ?

  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
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux