您的位置:首页 > 运维架构 > Linux

linux 下 kernel + kthread + 内核list + vmalloc + vfree + interruptible_sleep_on_timeout 学习实例

2011-08-26 15:52 1101 查看
code:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/vmalloc.h>

typedef struct tag_int_queue {
unsigned int dir;
struct list_head list;
} int_queue;

typedef struct tag_int_thread {
struct task_struct *th;
spinlock_t lock;
struct list_head queue_head;
} queue_thread;

static struct task_struct * _task_read;
static struct task_struct * _task_write;
static struct task_struct * _task3;
static queue_thread queueThread;

static int write_thread_func(void *data)
{
int_queue *pIntQueue;
int n = 0;
wait_queue_head_t timeout_wq;
init_waitqueue_head(&timeout_wq);
while(!kthread_should_stop())
{
pIntQueue = vmalloc(sizeof(int_queue));
pIntQueue->dir = n;
printk("########## write..%d\n", n++);
//spin_lock(&queueThread.lock);
list_add_tail(&pIntQueue->list, &queueThread.queue_head);
//spin_unlock(&queueThread.lock);
interruptible_sleep_on_timeout(&timeout_wq, HZ);
if(n == 50)
{
interruptible_sleep_on_timeout(&timeout_wq, HZ);
interruptible_sleep_on_timeout(&timeout_wq, HZ);
interruptible_sleep_on_timeout(&timeout_wq, HZ);
interruptible_sleep_on_timeout(&timeout_wq, HZ);
interruptible_sleep_on_timeout(&timeout_wq, HZ);
continue;
}
}

return 0;
}

static int read_thread_func(void *data)
{
int_queue *entry = NULL;
int j;
int timeout;
wait_queue_head_t timeout_wq;
j = 0;
printk("########## read thread_func started\n");
init_waitqueue_head(&timeout_wq);
while(!kthread_should_stop())
{
if(!list_empty(&queueThread.queue_head))
{
entry = list_first_entry(&queueThread.queue_head, int_queue, list);

printk("read..%d ##########\n", entry->dir);
//spin_lock(&queueThread.lock);
list_del(&entry->list);
vfree(entry);
//spin_unlock(&queueThread.lock);
}
printk("########## read sleeping..%d\n", j++);
interruptible_sleep_on_timeout(&timeout_wq, HZ);
}
return 0;
}

static void start_kthread()
{
_task_write = kthread_run(write_thread_func, 0, "thread_func_write");
_task_read = kthread_run(read_thread_func, 0, "thread_func_read");

if (!IS_ERR(_task_write) && !IS_ERR(_task_read))
{
printk("##########kthread_create done\n");
}
else
{
printk("##########kthread_create error\n");
}
}
static void end_kthread()
{
int ret = 0;
if (!IS_ERR(_task_read))
{
ret = kthread_stop(_task_read);
printk("##########end thread. ret = %d\n" , ret);
}

if (!IS_ERR(_task_write))
{
ret = kthread_stop(_task_write);
printk("##########end thread. ret = %d\n" , ret);
}
}

static int __init este_init(void)
{
printk(KERN_EMERG"\t########## initialized ##########\n");
INIT_LIST_HEAD(&queueThread.queue_head);
printk(KERN_EMERG"\t########## add queue ##########\n");

printk(KERN_EMERG"\t########## start thread ##########\n");
start_kthread();

return 0;
}

static void __exit este_exit(void)
{
end_kthread();
printk(KERN_EMERG"\t########## unloaded ##########\n");
}

module_init(este_init);
module_exit(este_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("stephen.yin.h@gmail.com");


Makefile:

obj-m := kthread_list.o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.ko *.symvers *.markers *.mod.c run
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: