1. 程式人生 > >Linux核心-核心層互斥鎖實現

Linux核心-核心層互斥鎖實現

核心層程式碼實現

#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/delay.h>

#define DEVNAME	"mutex"

/*
 	產生競爭的全域性變數,用於表示讀寫的滿足條件,讀一次
	更新成false表示空,寫一次更新成true,表示滿,只有可
	讀寫時方可讀寫。
 */
static int is_full = false;

static struct mutex mutex;

ssize_t 
demo_read (struct file *filp, char __user *buf, size_t cnt, loff_t *fpos)
{
	int ret;

	if (cnt == 0) {
		return cnt;
	}	

	/*獲得互斥鎖*/
	mutex_lock(&mutex);

	if (is_full == true) {
		printk("[kernel]: reading...\n");
		mdelay(50);
		is_full = false;
		ret = cnt;
		printk("[kernel]: read done.\n");
	} else {
		ret = -EIO;
	}

	/*釋放互斥鎖*/
	mutex_unlock(&mutex);

	return ret;
}

ssize_t 
demo_write (struct file *filp, const char __user *buf, size_t cnt, loff_t *fpos)
{
	int ret;

	if (cnt == 0) {
		return cnt;
	}

	/*獲得互斥鎖*/
	mutex_lock(&mutex);
	if (is_full == false) {

		printk("[kernel]: writing...\n");
		mdelay(50);
		is_full = true;
		printk("[kernel.]: write done.\n");

		ret = cnt;
	} else {
		ret = -EIO;
	}
	/*釋放互斥鎖*/
	mutex_unlock(&mutex);

	return ret;
}
/*
第一個指標指向自己
實現read write 的驅動函式,為上層的read write 服務
*/
static struct file_operations fops = {
	.owner		=  	THIS_MODULE,
//	.open		=	demo_open,
	.read		=	demo_read,
	.write		=	demo_write,
//	.release	= 	demo_release,	
};
/* 自動生成一個主裝置號為10  次裝置號為系統自動分配
裝置名字為DEVANAME的裝置檔案
並且關聯操作函式集*/
static struct miscdevice misc = {
	.minor	= 	MISC_DYNAMIC_MINOR,
	.name	=	DEVNAME,
	.fops	=	&fops,
};

static int demo_init(void)   //驅動函式模組的入口
{
	int ret;

	/*初始化互斥鎖*/
	mutex_init(&mutex);

	ret = misc_register(&misc);  註冊一個混雜裝置驅動
	if (ret < 0) {
		return ret;
	}

	return 0;
}

module_init(demo_init);

static void demo_exit(void)  //驅動的出口
{
	misc_deregister(&misc);  //銷燬註冊過的混雜裝置驅動

	printk("goodbye...\n");
}

module_exit(demo_exit);

MODULE_LICENSE("GPL");  //發表為GPL的宣告  必須寫

MODULE_VERSION("2018-09-30");
MODULE_AUTHOR("Hebowen");
MODULE_DESCRIPTION("a simple demo for module");

使用者上層app編寫 每次只有1個程序寫成功或者讀成功,實現了互斥

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>

#define N 98 

#define SZ 512

/*
 	./a.out /dev/semaphore  r/w
 */
int main(int argc, char **argv)
{
	int fd;
	int ret;
	int i;
	pid_t pid[N];
	char buf[SZ];

	if (argc != 3) {
		fprintf(stderr, "Usage: %s devicefile r/w\n", argv[0]);
		exit(1);
	}

	fd = open(argv[1], O_RDWR | O_NDELAY);
	assert(fd > 0);

	for (i = 0; i < N; i++) { 
		if ((pid[i] = fork()) < 0) {
			perror("fork");
			exit(1);
		}

		if (pid[i] == 0) {
			if (!strncmp(argv[2], "r", 1)) {
				ret = read(fd, buf, SZ);
				assert(ret == SZ);
				printf("ret = %d\n", ret);
				printf("[app%d]: read %dBytes ok!\n", 
						getpid(), ret);
				close(fd);
				return;	
			} else if (!strncmp(argv[2], "w", 1)) {
				ret = write(fd, buf, SZ);
				assert(ret == SZ);
				printf("[app%d]: write %dBytes ok!\n", 
						getpid(), ret);
				close(fd);
				return;	
			}			
		}
	}

	for (i = 0; i < N; i++) {
		waitpid(pid[i], NULL, 0);
	}

	close(fd);

	return 0;
}