深入浅出LDD-4-设备的驱动的并发控制2


/***************************************************************************************************
在 深入浅出LDD-4-设备的驱动的并发控制1的基础上

    我们给 globalvar 的驱动程序增加 open()和 release()函数,
    并在其中借助自旋锁来保护对全局变量 int  globalvar_count(记录打开设备的进程数)
    的访问来实现设备只能被一个进程打开(必须确保 globalvar_count 最多只能为 1)
****************************************************************************************************/

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>

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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值