读写自旋锁
读写自旋锁是自旋锁的一种提升,通过并发读提升性能。
读写锁自旋锁和自旋锁的数据结构一致:
struct {
raw_rwlock_t raw_lock;//分为两个不同部分,下面解释;
unsigned int break_lock;//当没有被读或者写时设置该位,否则清0;
} spinlock_t;
raw_rwlock_t {volatile unsigned int lock;}
可见,除了type名不同外,其他一致;
区别:
raw_rwlock_t raw_lock;
24位计数器,表示对受保护的数据结构并发读操作的内核控制路径数目,这个计数器的二进制补码存放在这个字段的0-23位;
“未锁”标志字段,当没有内核控制路径读/写时设置该位,否则清0。位于lock的24位;
自旋锁为空时,lock字段值为:0x0100 0000;若写着获取锁,则lock为0x0000 0000。若一个、两个或多个读者获取自旋锁,那么lock为:0xffff ffff,0xffff fffe等。
读锁
int _raw_read_trylock(rwlock_t *lock) {
atomic_t *count = (atomic_t*) lock->lock;
if (atomic_dec_return(count) >= 0) {//从count中减去1,返回新值;
return 1;
}
atomic_inc(count);
return 0;
}
注意:
尽管上述的读锁访问(读-修改-写)是原子的,但整个_raw_read_trylock()整个函数对计数器的操作并不是原子进行。在语句测试返回后,return 1之前,计数器的值可能发生变化。
但是函数能够正常工作。事实上,只有在递减之前计数器的值不为0或负数情况下,函数才返回1。因为计数器等于0x0100 0000表示没有任何进程占用锁,等于0x0fff ffff表示有一个读者,等于0x0000 0000表示有一个写者。
read_lock
static inline void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned long tmp0, tmp1;
/*
* rw->lock : >0 : unlock
*