wake_up_interruptible blocks

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

 



Hello,
I've tried to insmod the module which I attached to this file.
On insmod'ing, the module gets stuck on the 

wake_up_interruptible(&timer_queue);

line. If I'm uncommenting this line, everything goes smooth...the timer
runs.
Does somebody know, why the wake_up_interruptible call blocks? What
do I have to do to prevent this? Because I've to wake up processes on every
interrupt.

Best regards,
Juergen

-- 
Neu bei GMX: Preissenkung für MMS-Versand und FreeMMS!

Ideal für alle, die gerne MMS verschicken:
25 FreeMMS/Monat mit GMX TopMail.
http://www.gmx.net/de/cgi/produktemail

+++ GMX - die erste Adresse für Mail, Message, More! +++
/*
 * amu_module.c is based on procfs_example.c by Erik Mouw.
 * For more information, please see The Linux Kernel Procfs Guide,
 * http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html
 *
 * J.J. Boor, AimSys bv
 *   http://www.aimsys.nl
 *   jjboor@aimsys.nl
 */

/*
${CROSS_COMPILE}gcc -O2 -D__KERNEL__ -DMODULE amu_timer.c -o amu_timer.o

*/


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

#define TICK_MAJOR      241

#define MODULE_VERSION "0.1"
#define MODULE_NAME "timer"

static struct proc_dir_entry *timer_file;

static struct timer_list timer;
static unsigned long tick_count = 0;
static int timer_delay = 1;

DECLARE_WAIT_QUEUE_HEAD(timer_queue);

int timer_open(struct inode* inode, struct file* filp);
ssize_t timer_read (struct file *filp, char *buf, size_t count, loff_t *f_pos);
int timer_release(struct inode* inode, struct file* filp);

static struct file_operations timer_fops = {
    open: timer_open,
    read: timer_read,
    release: timer_release
};

static int proc_read_timer(char *page, char **start, off_t off,
                                int count, int *eof, void *data)
{
    int len;
    len = sprintf(page, "nr of timer ticks: %lu\n", tick_count);
    return len;
}


static int proc_write_timer(struct file *file, const char *buffer,
                                 unsigned long count, void *data)
{
    return 0;
}

void timerEvent(unsigned long arg)
{
    tick_count++;
    wake_up_interruptible(&timer_queue);
    timer.expires= jiffies + timer_delay;
    add_timer(&timer);
}

int __init init_timer_module(void)
{
    /* Create the proc entry and make it readable and writeable by all - 0666 */
    timer_file = create_proc_entry("timer", 0666, NULL);
    if (timer_file == NULL) {
        return -ENOMEM;
    }
    
    /* Set timer_file fields */
    timer_file->read_proc = &proc_read_timer;
    timer_file->write_proc = &proc_write_timer;
    timer_file->owner = THIS_MODULE;
    
    SET_MODULE_OWNER(&timer_fops);
    
    /* register /dev/tick */
    register_chrdev(TICK_MAJOR, "tick", &timer_fops);
    
    init_timer(&timer);
    timer.expires= jiffies + timer_delay;
    timer.function=timerEvent;
    timer.data=42;
    add_timer(&timer);
    
    /* everything initialized */
    printk(KERN_INFO "%s %s initialized\n", MODULE_NAME, MODULE_VERSION);
    return 0;
}

static void __exit cleanup_timer_module(void)
{
    del_timer(&timer);
    remove_proc_entry("timer", NULL);
    unregister_chrdev(TICK_MAJOR, "tick");
    
    printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERSION);
}

int timer_open(struct inode* inode, struct file* filp)
{
    return 0;
}

int timer_release(struct inode* inode, struct file* filp)
{
    return 0;
}

ssize_t timer_read (struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
    /* dummy read to wait on kernel timer */
    while (1) {
       interruptible_sleep_on(&timer_queue);
       if (signal_pending (current))  /* a signal arrived */
           return -ERESTARTSYS; /* tell the fs layer to handle it */
       else break;
    } 
    return 0;
}

#ifdef MODULE
/* here are the compiler macros for module operation */
module_init(init_timer_module);
module_exit(cleanup_timer_module);
#endif

MODULE_AUTHOR("J.J. Boor, AimSys bv");
MODULE_DESCRIPTION("timer module");
MODULE_LICENSE("GPL");

EXPORT_NO_SYMBOLS;


[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