linux设备驱动中关于竞态与并发的API

中断屏蔽(适合与自旋锁连用,下面会叙述到)

local_irq_disable(void)
local_irq_enable(void)
上述只能禁止和使能本cpu内的中断,不能解决SMP多cpu引发的竞态
local_irq_save(unsigned long flags)
local_irq_restoreunsigned long flags)
上述除了禁止中断外还保存了目前cpu的中断信息。对于ARM而言,其实就是保存和恢复CPSR
local_bh_disable(void)
local_bh_enable(void)
上述是禁止底半部中断

原子操作

  1. 整形原子操作
  1. 设置原子变量的值
    void atomic_set(atomic_t *v, int i); //设置原子变量的值为 i
    atomic v = ATOMIC_INIT(0); //定义并初始化一个原子变量为0
    上述两个语句等价
  2. 获取原子变量的值
    int value = atomic_read(atomic_t *v); //返回原子变量的值到value
  3. 原子变量加 / 减
    void atomic_add(int i, atomic_t *v); //原子变量增加 i
    void atomic_sub(int i, atomic_t *v); //原子变量减少 i
  4. 原子变量自增 / 自减
    void atomic_inc(atomic_t *v); //原子变量增加 1
    void atomic_dec(atomic_t *v); //原子变量减少 1
  5. 操作并测试
    int atomic_inc_and_test(atomic *v);
    int atomic_dec_and_test(atomic *v);
    int atomic_sub_and_test(atomic *v);
    上述是对原子变量执行自增, 自减, 和减操作和测试其值是否为0, 为0则返回true,反之则返回false
  6. 操作并返回
    int atomic_add_return(int i, atomic *v);
    int atomic_sub_return(int i, atomic *v);
    int atomic_inc_return(int i, atomic *v);
    int atomic_dec_return(int i, atomic *v);
    上述操作对原子变量进行加 / 减和自增 / 自减和返回新的值
  1. 位原子操作
  1. 设置位
    void set_bit(nr, void *addr); //设置addr地址的第 nr 位
  2. 清除位
    void clear_bit(nr, void *addr);
  3. 改变位
    void change_bit(nr, void *addr); //对第 nr 位 反置
  4. 测试位
    int test_bi(nr, void *nr); //返回第 nr 位
  5. 测试并操作位
    int test_and_set_bit(nr, void *addr);
    int test_and_clear_bit(nr, void *addr);
    int test_and_change_bit(nr, void *addr);
    上述等同于先执行test_bit(nr, void *addr), 再执行 xxx_bit(nr, void *addr)

自旋锁

  1. 定义
    spinlock_t lock;
  2. 初始化
    spin_lock_init(&lock);
  3. 获得自旋锁
    spin_lock(lock); //阻塞等待
    spin_trylock(lock); //非阻塞,不等待
  4. 释放
    spin_unlock(lock);

自旋锁与中断屏蔽连用

  1. 上锁
    spin_lock_irq(lock);
    spin_lock_irqsave(lock, flags);
    spin_lock_bh(lock);
  2. 解锁
    spin_unlock_irq(lock);
    spin_unlock_irqrestore(lock, flags);
    spin_unlock_bh(lock);

读写锁

  1. 定义和初始化
    rwlock_t my_rwlock;
    rwlock_init(&my_rwlock);
  2. 读锁
    void read_lock(lock);
    void read_unlock(lock);
  3. 写锁
    void write_lock(lock);
    void write_unlock(lock);
    读写锁也有与中断屏蔽的连用

信号量

  1. 定义
    struct semaphore  sem;
  2. 初始化
    void sema_init(struct semaphore *sem, int val);
  3. 获得
    void down(struct semaphore *sem);
    int down_interruptible(&sem);
    int down_trylock(&sem);
  4. 释放
    void up(&sem);

互斥锁

  1. 定义
    struct mutex my_mutex;
  2. 初始化
    mutex_init(&my_mutex);
  3. 获取
    void mutex_lock(&my_mutex);
    int mutex_lock_interruptible(&my_mutex);
    int mutex_trylock(&my_mutex);
  4. 释放
    void mutex_unlock(&lock);

完成量

  1. 定义
    struct completion my_completion;
  2. 初始化
    init_completion(&my_completion);
    reinit_completion(&my_completion);
  3. 等待被唤醒
    void wait_for_completion(&my_completion);
  4. 唤醒
    void completion(&my_completion);
    void completion(&my_completion);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值