Linux内核深度解析之内核互斥技术——读写自旋锁

读写自旋锁

读写自旋锁(通常简称读写锁)是对自旋锁的改进,区分读者和写者,允许多个读者同时进入临界区,读者和写者互斥,写者和写者互斥。

如果读者占有读锁,写者申请写锁的时候自旋等待。如果写者占有写锁,读者申请读锁的时候自旋等待。

读写自旋锁的定义:

include/linux/rwlock_types.h
typedef struct {
	arch_rwlock_t raw_lock;
    ...
} rwlock_t;

各种处理器架构需要自定义数据类型arch_rwlock_t,ARM64架构的定义:

typedef struct qrwlock {
	union {
		atomic_t cnts;
		struct {
#ifdef __LITTLE_ENDIAN
			u8 wlocked;	/* Locked for write? */
			u8 __lstate[3];
#else
			u8 __lstate[3];
			u8 wlocked;	/* Locked for write? */
#endif
		};
	};
	arch_spinlock_t		wait_lock;
} arch_rwlock_t;

定义并且初始化静态读写自旋锁的方法:

DEFINE_RWLOCK(x)

在运行时动态初始化读写自旋锁的方法:

rwlock_init(lock)

申请读锁的函数:

(1)申请读锁,如果写者占有写锁,当前处理器等待

read_lock(lock)

(2)申请读锁,并且禁止当前处理器的软中断

read_lock_bh(lock)

(3)申请读锁,并且禁止当前处理器的硬中断

 read_lock_irq(lock)

(4)申请读锁,保存当前处理器的硬中断状态,并且禁止当前处理器的硬中断

read_lock_irqsave(lock, flags)

 (5)尝试申请读锁,如果没有占有写锁的写者,那么申请成功,返回1;如果写者占有写锁,那么当前处理器不等待,返回0

read_trylock(lock)

释放读锁的函数:

(1)释放读锁

read_unlock(lock)

(2)释放读锁,并且开启当前处理器的软中断

read_unlock_bh(lock)

(3)释放读锁,并且开启当前处理器的硬中断

read_unlock_irq(lock)

(4)释放读锁,并且恢复当前处理器的硬中断状态

read_unlock_irqrestore(lock, flags)

 申请写锁的函数:

(1)申请写锁,如果写者占有写锁或者读者占有读锁,当前处理器自旋等待

write_lock(lock)

(2)申请写锁,并且禁止当前处理器的软中断

write_lock_bh(lock)

(3)申请写锁,并且禁止当前处理器的硬中断

write_lock_irq(lock)

(4)申请写锁,保存当前处理器的硬中断状态,并且禁止当前处理器的硬中断

write_lock_irqsave(lock, flags)

(5)尝试申请写锁,如果没有占有锁的写者和读者,那么申请写锁成功,返回1;如果写者占有写锁或者读者占有读锁,那么当前处理器不等待,立即返回0

write_trylock(lock)

释放写锁的函数:

(1)释放写锁

write_unlock(lock)

(2)释放写锁,并且开启当前处理器的软中断

write_unlock_bh(lock)

(3)释放写锁,并且开启当前处理器的硬中断

write_unlock_irq(lock)

(4)释放写锁,并且恢复当前处理器的硬中断状态

write_unlock_irqrestore(lock, flags)

读写自旋锁使用一个无符号32位整数作为计数值,写锁使用最高位,读锁使用其余31位,算法如下:

(1)申请写锁时,如果计数值是0,那么设置计数的最高位,进入临界区;如果计数值不是0说明写者占有写锁或者读者占有读锁,那么自旋等待;

(2)申请读锁时,如果计数值的最高位为0,那么把计数加1,进入临界区;如果计数的最高位不是0,说明写者占有写锁,那么自旋等待;

(3)释放写锁时,把计数值设置为0;

(4)释放读锁时,把计数值减1。

读写自旋锁的缺点是:如果读者很多,写者很难获取写锁,可能饿死。针对这个缺点,内核实现了排队读写锁,主要改进是:如果写者正在等待写锁,那么读者申请读锁时自旋等待,写者在锁被释放以后先得到写锁。排队读写锁的配置宏是CONFIG_QUEUED_RWLOCKS,源文件是“kernel/locking/qrwlock.c”。

猜你喜欢

转载自blog.csdn.net/linuxweiyh/article/details/106967244