Re: Problem with "wait_event_interruptible"

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

 



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/


[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