linux内核情景分析之锁机制
/*
* These are the generic versions of the spinlocks and read-write
* locks..
*///自旋锁加锁,irqsave表示把标志寄存器存储起来
#define spin_lock_irqsave(lock, flags) do { local_irq_save(flags);//关闭本地中断,保存标志位 spin_lock(lock); } while (0)
#define spin_lock_irq(lock) do { local_irq_disable(); spin_lock(lock); } while (0)
#define spin_lock_bh(lock) do { local_bh_disable(); spin_lock(lock); } while (0)
//读锁与下面写锁,构成读写锁
#define read_lock_irqsave(lock, flags) do { local_irq_save(flags); read_lock(lock); } while (0)
#define read_lock_irq(lock) do { local_irq_disable(); read_lock(lock); } while (0)
#define read_lock_bh(lock) do { local_bh_disable(); read_lock(lock); } while (0)
//写锁,与上面构成读写锁
#define write_lock_irqsave(lock, flags) do { local_irq_save(flags); write_lock(lock); } while (0)
#define write_lock_irq(lock) do { local_irq_disable(); write_lock(lock); } while (0)
#define write_lock_bh(lock) do { local_bh_disable(); write_lock(lock); } while (0)
//自旋锁解锁
#define spin_unlock_irqrestore(lock, flags) do { spin_unlock(lock); local_irq_restore(flags); } while (0)
#define spin_unlock_irq(lock) do { spin_unlock(lock); local_irq_enable(); } while (0)
#define spin_unlock_bh(lock) do { spin_unlock(lock); local_bh_enable(); } while (0)
//读锁解锁
#define read_unlock_irqrestore(lock, flags) do { read_unlock(lock); local_irq_restore(flags); } while (0)
#define read_unlock_irq(lock) do { read_unlock(lock); local_irq_enable(); } while (0)
#define read_unlock_bh(lock) do { read_unlock(lock); local_bh_enable(); } while (0)
//写锁解锁
#define write_unlock_irqrestore(lock, flags) do { write_unlock(lock); local_irq_restore(flags); } while (0)
#define write_unlock_irq(lock) do { write_unlock(lock); local_irq_enable(); } while (0)
#define write_unlock_bh(lock) do { write_unlock(lock); local_bh_enable(); } while (0)
自旋锁加锁解析
static inline void spin_lock(spinlock_t *lock)
{
#if SPINLOCK_DEBUG
__label__ here;
here:
if (lock->magic != SPINLOCK_MAGIC) {//判断是否等于魔数
printk("eip: %p\n", &&here);
BUG();
}
#endif
__asm__ __volatile__(
spin_lock_string
:"=m" (lock->lock) : : "memory");
}
其中spin_lock_string为一个宏
#define spin_lock_string \
"\n1:\t" \
"lock ; decb %0\n\t" \ //将lock->lock减1,指令带lock表示把总线锁住,禁止其他cpu访问
"js 2f\n" \//不是非负数,直接进入临界区
".section .text.lock,\"ax\"\n" \
"2:\t" \
"cmpb $0,%0\n\t" \//如果-1结果为负数,那就循环检测
"rep;nop\n\t" \
"jle 2b\n\t" \//如果检测依旧是负数,跳转到2
"jmp 1b\n" \//否则检测
".previous"
互斥锁,读写锁,条件变量,自旋锁(用于线程互斥)
信号量,文件锁用于进程同步