#include MODULE_LICENSE("GPL");
#define MAJOR_NUM 254
static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);
static int globalvar_open(struct inode *inode, struct file *filp);
static int globalvar_release(struct inode *inode, struct file *filp);
struct file_operations globalvar_fops =
{
read: globalvar_read, write: globalvar_write, open: globalvar_open, release:
globalvar_release,
};
static int global_var = 0;
static int globalvar_count = 0;
static struct semaphore sem;
static spinlock_t spin = SPIN_LOCK_UNLOCKED;
static int __init globalvar_init(void)
{
int ret;
ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
if (ret)
{
printk("globalvar register failure");
}
else
{
printk("globalvar register success");
init_MUTEX(&sem);
}
return ret;
}
static void __exit globalvar_exit(void)
{
int ret;
ret = unregister_chrdev(MAJOR_NUM, "globalvar");
if (ret)
{
printk("globalvar unregister failure");
}
else
{
printk("globalvar unregister success");
}
}
static int globalvar_open(struct inode *inode, struct file *filp)
{
//获得自选锁
spin_lock(&spin);
//临界资源访问
if (globalvar_count)
{
spin_unlock(&spin);
return - EBUSY;
}
globalvar_count++;
//释放自选锁
spin_unlock(&spin);
return 0;
}
static int globalvar_release(struct inode *inode, struct file *filp)
{
globalvar_count--;
return 0;
}
static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t
*off)
{
if (down_interruptible(&sem))
{
return - ERESTARTSYS;
}
if (copy_to_user(buf, &global_var, sizeof(int)))
{
up(&sem);
return - EFAULT;
}
up(&sem);
return sizeof(int);
}
static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len,
loff_t *off)
{
if (down_interruptible(&sem))
{
return - ERESTARTSYS;
}
if (copy_from_user(&global_var, buf, sizeof(int)))
{
up(&sem);
return - EFAULT;
}
up(&sem);
return sizeof(int);
}
module_init(globalvar_init);
module_exit(globalvar_exit);
为了上述驱动程序的效果,我们启动两个进程分别打开/dev/globalvar。在两个终端中调用./globalvartest.o测试程序,当一个进程打开/dev/globalvar后,另外一个进程将打开失败,输出"device open failure",如下图: