liunx内核中的互斥自旋锁和读写自旋锁的实现详解

今天把这两个锁的内核实现源码重新捋了一遍,基于liunx2,6.0,直接粘注释版:
核心文件,x86下实现的spinlock

#ifndef __ASM_SPINLOCK_H
#define __ASM_SPINLOCK_H

#include <asm/atomic.h>
#include <asm/rwlock.h>
#include <asm/page.h>
#include <linux/config.h>

extern int printk(const char * fmt, ...)
	__attribute__ ((format (printf, 1, 2)));

/*
 * Your basic SMP spinlocks, allowing only a single CPU anywhere
 */

typedef struct {
   
    //自旋锁为无符号的整型变量 volatile保证变量都从内存中获取,不要缓存在寄存器里
	volatile unsigned int lock;
#ifdef CONFIG_DEBUG_SPINLOCK
	unsigned magic;
#endif
} spinlock_t;
//定义一个spinlock的魔数,用来调试用
#define SPINLOCK_MAGIC	0xdead4ead

#ifdef CONFIG_DEBUG_SPINLOCK
#define SPINLOCK_MAGIC_INIT	, SPINLOCK_MAGIC
#else
#define SPINLOCK_MAGIC_INIT	/*如果没有开启调试状态将什么也没有 */
#endif
//创建一个值为1的自旋锁
#define SPIN_LOCK_UNLOCKED (spinlock_t) {
      1 SPINLOCK_MAGIC_INIT }
//初始化自旋锁 x是一根指针 所以解引用
#define spin_lock_init(x)	do {
      *(x) = SPIN_LOCK_UNLOCKED; } while(0)

/*
 * Simple spin lock operations.  There are two variants, one clears IRQ's
 * on the local processor, one does not.
 * 简单的自旋锁操作。有两种变体,一种清除本地处理器上的IRQ,另一种不清除。
 *
 * We make no fairness assumptions. They have a cost.
 * 我们没有做出公平的假设(非公平)。它们是有代价的
 */
//判断自旋锁是否被锁定 先通过取地址拿到spinlock里的lock 再转为字符,再解引用判断是否小于0
#define spin_is_locked(x)	(*(volatile signed char *)(&(x)->lock) <= 0)
//等待自旋锁释放,barrier()保证禁止编译器任意排序
#define spin_unlock_wait(x)	do {
      barrier(); } while(spin_is_locked(x))
//获取自旋锁内联汇编代码,这里只是code部分,剩下在用的时候肯定是有输出数和输入数的
#define spin_lock_string \
	"1:" \ //1位置
	"lock ; decb %0" \ //对lock变量的值进行自减,如果lock变量是0或者小于0,再减岂不是直接就小于0了吗,所以底下js判断是否符号位为1,也就是小于0
	"js 2f" \  //f是forward,往后跳,因为2:确实在后面,如果小于0,跳转到前面的2处 js判断的是符号位是否为1,为1当然就小于0啦
	LOCK_SECTION_START("") \ //涉及到ELF的知识
	"2:" \
	"rep;nop" \ //repeat空操作
	"cmpb $0,%0" \ //比较lock的值是否为0,%0可以从后面的代码看出,是输出参数,是lock变量 cmpb的b代表比一个字节,l代表4字节
	"jle 2b" \ //b是backward,往前跳,jle代表小于或等于0,继续2处
	"jmp 1b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

graceful coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值