read_lock()和write_lock()

 read_lock()和write_lock()的过程描述如下:

锁变量的初值为RW_LOCK_UNLOCKED(0x01000000),锁变量为正时为未锁状态,反之为上锁状态。

read_lock()对锁变量减1,如果结果为负,则说明已被某个write_lock()上锁。然后read_lock()对锁变量加1,释 放read_lock状态,接着等待锁变量的值变为1;一旦锁变量变为1,read_lock()再次对锁变量减1 ,如果非负则成功,否则重复上述过程。

write_lock()对锁变量减0x01000000,如果结果非零,则说明已被write_lock()或read_lock()上锁。然 后write_lock()对锁变量加0x01000000,释放write_lock()状态,接着等待锁变量的值变为0x01000000;一旦锁变 量变为0x01000000,write_lock()再次对锁变量减0x01000000,如果为零则成功,否则重复上述过程。

read_lock(&mr_rwlock);
write_lock(&mr_rwlock);



deadlocks as the write lock spins, waiting for all readers to release the lockincluding yourself. If you ever need to write, obtain the write lock from the very start. If the line between your readers and writers is muddled, it might be an indication that you do not need to use reader-writer locks. In that case, a normal spin lock is optimal.
执行上面2行代码的进程将阻塞到write_lock(&mr_rwlock); 因为mr_rwlock读锁没有释放




可以多个同时读,但是读-写, , 写-写  都是 互斥的
原理和 spin_lock一样


include/linux/spinlock.h   中定义了write_lock,由于不是SMP,所以定义如下 :  就是禁止抢占就够了,不会被别人抢到锁

#define _write_lock(lock) /
do { /
    preempt_disable(); /
    _raw_write_lock(lock); /
    __acquire(lock); /
} while(0)


#define _raw_write_lock(lock)    do { (void)(lock); } while(0)




arm代码 (自由CONFIG_SMP时候才会用到)

static inline void _raw_spin_lock(spinlock_t *lock)
{
        unsigned long tmp;
igned long tmp, tmp2;

        __asm__ __volatile__(
"1:     ldrex   %0, [%2]/n"
"       adds    %0, %0, #1/n"
"       strexpl %1, %0, [%2]/n"
"       rsbpls  %0, %1, #0/n"
"       bmi     1b"
        : "=&r" (tmp), "=&r" (tmp2)
        : "r" (&rw->lock)
        : "cc", "memory");
}


static inline void _raw_write_lock(rwlock_t *rw)
{
        unsigned long tmp;

        __asm__ __volatile__(
"1:     ldrex   %0, [%1]/n"
"       teq     %0, #0/n"
"       strexeq %0, %2, [%1]/n"
"       teq     %0, #0/n"
"       bne     1b"
        : "=&r" (tmp)
        : "r" (&rw->lock), "r" (0x80000000)
        : "cc", "memory");
}


static inline void _raw_read_lock(rwlock_t *rw)
{
        unsigned long tmp, tmp2;

        __asm__ __volatile__(
"1:     ldrex   %0, [%2]/n"
"       adds    %0, %0, #1/n"
"       strexpl %1, %0, [%2]/n"
"       rsbpls  %0, %1, #0/n"
"       bmi     1b"
        : "=&r" (tmp), "=&r" (tmp2)
        : "r" (&rw->lock)
        : "cc", "memory");
}

都是用
原子操作指令
原子操作和以上也类似 :
static inline void atomic_set(atomic_t *v, int i)
{
        unsigned long tmp;

        __asm__ __volatile__("@ atomic_set/n"
"1:     ldrex   %0, [%1]/n"
"       strex   %0, %2, [%1]/n"
"       teq     %0, #0/n"
"       bne     1b"
        : "=&r" (tmp)
        : "r" (&v->counter), "r" (i)
        : "cc");
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值