Milind Arun Choudhary's Weblog

http://www.csl.mtu.edu/~machoudh/

Linux kernel module: Daemons and Blocking mutex

Posted by milindchoudhary on March 29, 2009

/********************************************************************
*Description :: A kernel module which creates 2 kernel threads.
* Converts both of them to daemons.Demonstrates the use of mutex
* to share a dummy resource between the two.
* The mutex is acquired using a blocking call :down_interruptible()
*Author :: Milind A Choudhary
*Date ::07-Dec-2005
********************************************************************/

#include
#include
#include
#include
#include
#include

/* The resource which will be shared */
struct data {
int num;
}data={11};

pid_t kthread_pid1 ;
pid_t kthread_pid2 ;
DECLARE_MUTEX(mutex);

/*Routine for the first thread */

int kthread_routine_1(void *kthread_num)
{
//int num=(int)(*(int*)kthread_num);
int num=1;
char kthread_name[15];

printk(KERN_INFO “Inside daemon_routine() \n”);
sprintf(kthread_name,”kern_daemon_%d”,num);
daemonize(kthread_name);
allow_signal(SIGKILL);
allow_signal(SIGTERM);

do{
printk(KERN_INFO “kernel_daemon [%d] waiting to acquire mutex\n”,num);
if(!down_interruptible(&mutex)){
printk(KERN_INFO “kernel_daemon [%d] accessing the shared data=%d\n”,num,data.num);
data.num=11;
up(&mutex);
printk(KERN_INFO “kernel_daemon [%d] released the mutex data=%d\n”,num,data.num);
}else{
printk(KERN_INFO “kernel_daemon [%d] interrupted while acquiring the mutex\n”,num);
}

set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(5*HZ);

}while(!signal_pending(current));
return 0;
}

/*Routine for the second thread */

int kthread_routine_2(void *kthread_num)
{
//int num=(int)(*(int*)kthread_num);
int num=2;
char kthread_name[15];

printk(KERN_INFO “Inside daemon_routine() \n”);
sprintf(kthread_name,”kern_daemon_%d”,num);
daemonize(kthread_name);
allow_signal(SIGKILL);
allow_signal(SIGTERM);

do{
printk(KERN_INFO “kernel_daemon [%d] waiting to acquire mutex\n”,num);
if(!down_interruptible(&mutex)){
printk(KERN_INFO “kernel_daemon [%d] accessing the shared data=%d\n”,num,data.num);
data.num=22;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10*HZ);
up(&mutex);
printk(KERN_INFO “kernel_daemon [%d] released the mutex data=%d\n”,num,data.num);
}else{
printk(KERN_INFO “kernel_daemon [%d] interrupted while acquiring the mutex\n”,num);
}

set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10*HZ);

}while(!signal_pending(current));
return 0;
}

int _init_(void)
{
int kthread_num =1;
printk(KERN_INFO”starting the first kernel thread\n”);
kthread_pid1 = kernel_thread(kthread_routine_1,NULL,0);
if(kthread_pid1< 0 ){
printk(KERN_ALERT “Kernel thread [1] creation failed\n”);
return -1;
}
kthread_num=2;
printk(KERN_INFO”starting the second kernel thread\n”);
kthread_pid2 = kernel_thread(kthread_routine_2,NULL,0);
if(kthread_pid2 < 0 ){
printk(KERN_ALERT “Kernel thread [2] creation failed\n”);
return -1;
}

return 0;
}

void _fini_(void)
{
printk(KERN_INFO”kernel daemon [1] terminating\n”);
if(kill_proc(kthread_pid1,SIGTERM,1) == -ESRCH){
printk(KERN_ERR “kernel thread1 pid::%d already dead\n”,kthread_pid1);
init_MUTEX(&mutex);
}
printk(KERN_INFO”kernel daemon [2] terminating\n”);
if(kill_proc(kthread_pid2,SIGTERM,1) == -ESRCH){
printk(KERN_ERR “kernel thread2 pid::%d already dead\n”,kthread_pid2);
init_MUTEX(&mutex);
}
}

module_init(_init_);
module_exit(_fini_);

MODULE_LICENSE(“GPL”);
MODULE_DESCRIPTION(“Demonstrates use of mutex”);
MODULE_AUTHOR(“Milind A Choudhary”);

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: