/********************************************************************
*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");
/*
* file mythread.c
*/
#include
#include
#include
#include
#include
#include
#include
#include
/*
struct student {
int age;
char name[128];
int score;
};
*/
static pid_t thread_id;
struct completion exit_completion;
int my_fuction(void *arg)
{
daemonize("demo-thread");
allow_signal(SIGKILL);
while(!signal_pending(current))
{
printk("jiffies is %lu\n", jiffies);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10 * HZ);
}
complete_and_exit(&exit_completion, 1);
return 0;
}
static int __init init(void)
{
thread_id = kernel_thread(my_fuction, NULL, CLONE_FS | CLONE_FILES);
return 0;
}
static void __exit fini(void)
{
kill_proc(thread_id, SIGKILL, 1);
wait_for_completion(&exit_completion);
printk("Goodbye\n");
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");