#include<linux/init.h>
#include<linux/module.h>
#include<linux/wait.h>
#include<linux/sem.h>
#include<linux/sched.h>
#define BUFF_SIZE 10 /*²Ö¿âÖÐÓÐÊ®¸öλÖÿÉÒÔ´æ·Å²úÆ·*/
/*
* _PRODUCE: ±êʶÉú²úÕßµÄ״̬£º
* RUNNING: Éú²úÖÐ
* STOPPED: Í£Ö¹Éú²ú
*/
typedef enum _PRODUCE{RUNNING,STOPPED}PRODUCE;
/*
* _storage: ²úÆ·´æ·ÅµØ
* buff : ²Ö¿â
* lock: ²Ö¿âÃÅËø£¬Ò»¸öʱ¼äÖ»ÄÜÔÊÐíÉú²úÕß´æ·Å²úÆ·»òÕßÖ»ÔÊÐíÏû·ÑÕßÏû·Ñ²úÆ·
* amount: ²úÆ·ÏÖÓеĸöÊý
* state: Éú²úÕßµÄÉú²ú״̬
* (*wait): Ëø¶¨²Ö¿âÃÅ
* (*signal): ¿ªÆô²Ö¿âÃÅ
*/
struct _storage {
char buff[BUFF_SIZE][20];
struct semaphore lock;
int amount;
PRODUCE state;
void (*wait)(struct semaphore *lock);
void (*signal)(struct semaphore *lock);
};
/*
* procon_lock: ²úÆ·ÊýÁ¿¼ì²éËø
* (*wait): µÈ´ýÓвúÆ·¿ÉÒÔÏû·Ñ»òÕßÊǵȴý²Ö¿âÓÐλÖÿÉÒԷŲúÆ·
* (*signla): Ïû·Ñ²úÆ·»òÕß´æ·Å²úÆ··µ»Ø
*/
struct procon_lock {
struct _storage *storage;
void (*wait)(struct _storage *storage);
void (*signal)(struct _storage *storage);
};
/*
* _lock: ´ò°ü¸÷ÖÖ×ÊÔ´
* *storage: ²Ö¿â×ÊÔ´
* *empty: µÈ´ý²Ö¿âÓÐλÖÿÉÒÔ´æ·Å²úÆ·
* *full: µÈ´ý²Ö¿âÀïÓвúÆ·¿ÉÒÔÏû·Ñ
*/
struct _lock {
struct _storage *storage;
struct procon_lock *empty;
struct procon_lock *full;
};
void empty_wait(struct _storage *storage);
void empty_signal(struct _storage *storage);
void full_wait(struct _storage *storage);
void full_signal(struct _storage *storage);
int producer(void *p);
int consumer(void *p);
/*
* storage: ²Ö¿â
*/
struct _storage storage = {
.amount=0, /*³õʼ²Ö¿âÖÐûÓвúÆ·*/
.state=RUNNING,
.wait=down,
.signal=up,
};
/*
* empty: µÈ´ý²Ö¿âÓÐλÖ÷½²úÆ·Ëø
*/
struct procon_lock empty = {
.storage=&storage,
.wait=empty_wait,
.signal=empty_signal,
};
/*
* full: µÈ´ý²Ö¿âÓвúÆ·¿ÉÒÔÏû·ÑËø
*/
struct procon_lock full = {
.storage=&storage,
.wait=full_wait,
.signal=full_signal,
};
/*
* lock: ´ò°ü×ÊÔ´£¬½«Æä´«µÝ¸øÉú²úÕߺÍÏû·ÑÕß
*/
struct _lock lock = {
.storage = &storage,
.empty = &empty,
.full = &full
};
MODULE_LICENSE("Dual BSD/GPL");
/*
* procon_init: ÄÚºËÄ£¿é³õʼ»¯º¯Êý
*/
static int procon_init(void)
{
printk(KERN_INFO"Resolving the proceducer-consumer problem\n");
memset(storage.buff,'\0',BUFF_SIZE*20);/*Çå¿Õ²Ö¿â*/
init_MUTEX(&storage.lock); /*´ò¿ª²Ö¿âÃÅ*/
//kernel_thread(producer,&lock,CLONE_KERNEL);
//kernel_thread(producer,&lock,CLONE_KERNEL);
kernel_thread(producer,&lock,CLONE_KERNEL); /*Æô¶¯Éú²úÏߣ¬Éú²úÕß¿ªÊ¼Éú²ú²úÆ·*/
kernel_thread(consumer,&lock,CLONE_KERNEL);/*Ïû·ÑÕß¿ªÊ¼Ïû·Ñ²úÆ·*/
//kernel_thread(consumer,&lock,CLONE_KERNEL);
return 0;
}
/*
* procon_exit: ÄÚºËÄ£¿éÐ¶ÔØº¯Êý
*/
static void procon_exit(void)
{
printk(KERN_INFO"Resolved the proceducer-consumer problem\n");
}
/*
* producer: Éú²úÕߣ¬¸ºÔðÉú²ú¶þÊ®¸ö²úÆ·
* £À*p: Éú²úÐèÒªµÄ×ÊÔ´
*/
int producer(void *p)
{
struct _lock *lock=(struct _lock *)p; /*½â°ü×ÊÔ´*/
struct _storage *storage=lock->storage;/*»ñÈ¡²Ö¿â×ÊÔ´*/
struct procon_lock *empty=lock->empty;/*»ñÈ¡²Ö¿âλÖÃ̽²â×ÊÔ´*/
struct procon_lock *full=lock->full;/*»ñÈ¡²Ö¿âλÖÃ̽²â×ÊÔ´*/
struct task_struct *task=current;/*È¡µÃµ±Ç°Ïß³ÌÃèÊö·û*/
int i,j;
printk(KERN_INFO"%d:producer start produce products...\n",task->pid);/*ÏÔʾ¿ªÊ¼Éú²ú*/
for(i=0;i<20;i++) { /*×ܹ²Éú²ú¶þÊ®¸ö²úÆ·*/
empty->wait(empty->storage); /*Èç¹û²Ö¿âÒѾ·ÅÂú£¬ÔòµÈ´ýÖ±µ½ÓÐλÖÿÉÒԷŲúÆ·*/
storage->wait(&storage->lock);/*´ò¿ª²Ö¿âÃÅ*/
for(j=0;j<BUFF_SIZE;j++) { /*ѰÕÒÒ»¸ö¿ÉÒԷŲúÆ·µÄλÖÃ*/
if(!strlen(storage->buff[j]))
break;
}
snprintf(storage->buff[j],20,"%d:product-%d",task->pid,i);/*Éú²ú²úÆ·£¬·ÅÈë²Ö¿â*/
printk(KERN_INFO"%d:producer produce %s\n",task->pid,storage->buff[j]);/*Éú²úÕßÌáʾÒѾÉú²ú*/
full->signal(full->storage);/*ÌáʾÏû·ÑÕßÓвúÆ·¿ÉÒÔÏû·Ñ*/
storage->signal(&storage->lock);/*¹Ø±Õ²Ö¿âÃÅ*/
}
storage->state=STOPPED;/*Éú²úÍê±Ï£¬¹Ø±ÕÉú²úÏß*/
printk(KERN_INFO"%d:producer exit...\n",task->pid); /*Í˳öÉú²ú*/
return 0;
}
/*
* consumer: Ïû·ÑÕߣ¬Èç¹ûÓвúÆ·£¬ÔòÏû·Ñ²úÆ·
* @*p: Ïû·ÑÐèÒªµÄ×ÊÔ´
*/
int consumer(void *p)
{
struct _lock *lock=(struct _lock *)p;
struct _storage *storage=lock->storage;
struct procon_lock *empty=lock->empty;
struct procon_lock *full=lock->full;
struct task_struct *task=current;
int i;
printk(KERN_INFO"%d:consumer start consume products...\n",task->pid);/*Ìáʾ¿ªÊ¼Ïû·Ñ*/
for(;;) {
/*Èç¹û²Ö¿âÖÐÒѾûÓвúÆ·²¢ÇÒÉú²úÕßÒѾÍ˳öÉú²úÏߣ¬ÔòÍ£Ö¹Ïû·Ñ*/
if(storage->amount==0&&storage->state==STOPPED){
break;
}
full->wait(full->storage); /*Èç¹û²Ö¿âÃÅûÓвúÆ·£¬ÔòµÈ´ýÖ±µ½ÓвúÆ·*/
storage->wait(&storage->lock);/*´ò¿ª²Ö¿âÃÅ*/
for(i=0;i<BUFF_SIZE;i++) {/*ѰÕÒÒ»¸ö²úÆ·*/
if(strlen(storage->buff[i]))
break;
}
printk(KERN_INFO"%d:consumer consume %s\n",task->pid,storage->buff[i]);/*Ïû·ÑÕßÌáʾ»ñµÃÁ˲úÆ·*/
memset(storage->buff[i],'\0',20);/*Ïû·Ñ²úÆ·*/
empty->signal(empty->storage);/*¸æËßÉú²úÕß²Ö¿âÓÐλÖÿÉÒԷŲúÆ·*/
storage->signal(&storage->lock); /*¹Ø±Õ²Ö¿âÃÅ*/
}
printk(KERN_INFO"%d:consumer exit...\n",task->pid);
return 0;
}
/*
* empty_wait: µÈ´ý²Ö¿âÖÐÓÐλÖÿÉÒԷŲúÆ·
* @storage: ²Ö¿â
*/
void empty_wait(struct _storage *storage)
{
do {
if(storage->amount<BUFF_SIZE) /*Èç¹û²Ö¿âÖÐÓÐλÖÿÉÒԷŲúÆ·£¬ÔòÍ˳öµÈ´ý*/
break;
schedule();/*µÈ´ý²Ö¿âÖÐÓпÕλÖÃ*/
}while(1);
}
/*
* empty_signal: ֪ͨÉú²úÕßÕß²Ö¿âÖÐÓÐλÖÿÉÒԷŲúÆ·
* @*storage: ²Ö¿â
*/
void empty_signal(struct _storage *storage)
{
storage->amount--; /*²úÆ·¼ÆÊý¼õÒ»*/
}
/*
* full_wait: µÈ´ý²Ö¿âÖÐÓвúÆ·¿ÉÒÔÏû·Ñ
* @*storage: ²Ö¿â
*/
void full_wait(struct _storage *storage)
{
do {
if(storage->amount>0) /*Èç¹û²Ö¿âÖÐÓвúÆ·¿ÉÒÔÏû·Ñ£¬Ôò·µ»Ø*/
break;
schedule();/*µÈ´ýÓвúÆ·*/
}while(1);
}
/*
* full_signal: ֪ͨÏû·ÑÕß²Ö¿âÖÐÓвúÆ·¿ÉÒÔÏû·Ñ
* @*storage: ²Ö¿â
*/
void full_signal(struct _storage *storage)
{
storage->amount++; /*²úÆ·¼ÆÊý¼ÓÒ»*/
}
module_init(procon_init);
module_exit(procon_exit);
MODULE_AUTHOR("Niu Tao");
MODULE_DESCRIPTION("The proceducer-consumer problem");
MODULE_ALIAS("a simplest module");
Makefile:
obj-m :=procon.o CURRENT_PATH := $(shell pwd) LINUX_KERNEL := $(shell uname -r) LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)
all: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions Module.symvers .Makefile.swp
³ÌÐòÔËÐнá¹û£º
[13899.280451] Resolving the proceducer-consumer problem [13899.284977] 16104:producer start produce products... [13899.284984] 16104:producer produce 16104:product-0 [13899.284987] 16104:producer produce 16104:product-1 [13899.284990] 16104:producer produce 16104:product-2 [13899.284992] 16104:producer produce 16104:product-3 [13899.284994] 16104:producer produce 16104:product-4 [13899.284997] 16104:producer produce 16104:product-5 [13899.284999] 16104:producer produce 16104:product-6 [13899.285002] 16104:producer produce 16104:product-7 [13899.285004] 16104:producer produce 16104:product-8 [13899.285007] 16104:producer produce 16104:product-9 [13899.339264] 16105:consumer start consume products... [13899.339495] 16105:consumer consume 16104:product-0 [13899.339633] 16104:producer produce 16104:product-10 [13899.339769] 16105:consumer consume 16104:product-10 [13899.339907] 16104:producer produce 16104:product-11 [13899.340042] 16105:consumer consume 16104:product-11 [13899.340208] 16104:producer produce 16104:product-12 [13899.340344] 16105:consumer consume 16104:product-12 [13899.340481] 16104:producer produce 16104:product-13 [13899.340616] 16105:consumer consume 16104:product-13 [13899.340887] 16104:producer produce 16104:product-14 [13899.341036] 16105:consumer consume 16104:product-14 [13899.341175] 16104:producer produce 16104:product-15 [13899.341310] 16105:consumer consume 16104:product-15 [13899.341447] 16104:producer produce 16104:product-16 [13899.341582] 16105:consumer consume 16104:product-16 [13899.341719] 16104:producer produce 16104:product-17 [13899.341854] 16105:consumer consume 16104:product-17 [13899.342029] 16104:producer produce 16104:product-18 [13899.342164] 16105:consumer consume 16104:product-18 [13899.342302] 16104:producer produce 16104:product-19 [13899.342305] 16104:producer exit... [13899.342525] 16105:consumer consume 16104:product-19 [13899.342663] 16105:consumer consume 16104:product-1 [13899.342808] 16105:consumer consume 16104:product-2 [13899.343060] 16105:consumer consume 16104:product-3 [13899.343214] 16105:consumer consume 16104:product-4 [13899.343352] 16105:consumer consume 16104:product-5 [13899.343489] 16105:consumer consume 16104:product-6 [13899.343625] 16105:consumer consume 16104:product-7 [13899.343762] 16105:consumer consume 16104:product-8 [13899.343899] 16105:consumer consume 16104:product-9 [13899.343902] 16105:consumer exit... [14598.468929] Resolved the proceducer-consumer problem
|