1. /*
    1. * These are the generic versions of the spinlocks and read-write
    1. * locks..
    1. *///自旋锁加锁,irqsave表示把标志寄存器存储起来
    1. #define spin_lock_irqsave(lock, flags) do { local_irq_save(flags);//关闭本地中断,保存标志位 spin_lock(lock); } while (0)
    1. #define spin_lock_irq(lock) do { local_irq_disable(); spin_lock(lock); } while (0)
    1. #define spin_lock_bh(lock) do { local_bh_disable(); spin_lock(lock); } while (0)
    1. //读锁与下面写锁,构成读写锁
    1. #define read_lock_irqsave(lock, flags) do { local_irq_save(flags); read_lock(lock); } while (0)
    1. #define read_lock_irq(lock) do { local_irq_disable(); read_lock(lock); } while (0)
    1. #define read_lock_bh(lock) do { local_bh_disable(); read_lock(lock); } while (0)
    1. //写锁,与上面构成读写锁
    1. #define write_lock_irqsave(lock, flags) do { local_irq_save(flags); write_lock(lock); } while (0)
    1. #define write_lock_irq(lock) do { local_irq_disable(); write_lock(lock); } while (0)
    1. #define write_lock_bh(lock) do { local_bh_disable(); write_lock(lock); } while (0)
    1. //自旋锁解锁
    1. #define spin_unlock_irqrestore(lock, flags) do { spin_unlock(lock); local_irq_restore(flags); } while (0)
    1. #define spin_unlock_irq(lock) do { spin_unlock(lock); local_irq_enable(); } while (0)
    1. #define spin_unlock_bh(lock) do { spin_unlock(lock); local_bh_enable(); } while (0)
    1. //读锁解锁
    1. #define read_unlock_irqrestore(lock, flags) do { read_unlock(lock); local_irq_restore(flags); } while (0)
    1. #define read_unlock_irq(lock) do { read_unlock(lock); local_irq_enable(); } while (0)
    1. #define read_unlock_bh(lock) do { read_unlock(lock); local_bh_enable(); } while (0)
    1. //写锁解锁
    1. #define write_unlock_irqrestore(lock, flags) do { write_unlock(lock); local_irq_restore(flags); } while (0)
    1. #define write_unlock_irq(lock) do { write_unlock(lock); local_irq_enable(); } while (0)
    1. #define write_unlock_bh(lock) do { write_unlock(lock); local_bh_enable(); } while (0)


自旋锁加锁解析
    1. static inline void spin_lock(spinlock_t *lock)
    1. {
    1. #if SPINLOCK_DEBUG
    1. __label__ here;
    1. here:
    1. if (lock->magic != SPINLOCK_MAGIC) {//判断是否等于魔数
    1. printk("eip: %p\n", &&here);
    1. BUG();
    1. }
    1. #endif
    1. __asm__ __volatile__(
    1. spin_lock_string
    1. :"=m" (lock->lock) : : "memory");
    1. }
其中spin_lock_string为一个宏
    1. #define spin_lock_string \
    1. "\n1:\t" \
    1. "lock ; decb %0\n\t" \ //将lock->lock减1,指令带lock表示把总线锁住,禁止其他cpu访问
    1. "js 2f\n" \//不是非负数,直接进入临界区
    1. ".section .text.lock,\"ax\"\n" \
    1. "2:\t" \
    1. "cmpb $0,%0\n\t" \//如果-1结果为负数,那就循环检测
    1. "rep;nop\n\t" \
    1. "jle 2b\n\t" \//如果检测依旧是负数,跳转到2
    1. "jmp 1b\n" \//否则检测
    1. ".previous"


互斥锁,读写锁,条件变量,自旋锁(用于线程互斥)
信号量,文件锁用于进程同步


linux内核情景分析之锁机制的更多相关文章

  1. Linux内核情景分析之消息队列

    早期的Unix通信只有管道与信号,管道的缺点: 所载送的信息是无格式的字节流,不知道分界线在哪,也没通信规范,另外缺乏控制手段,比如保温优先级,管道机制的大小只有1页,管道很容易写满而读取没有及时,发 ...

  2. linux内核情景分析之execve()

    用来描述用户态的cpu寄存器在内核栈中保存情况.可以获取用户空间的信息 struct pt_regs { long ebx; //可执行文件路径的指针(regs.ebx中 long ecx; //命令 ...

  3. linux内核情景分析之内核中的互斥操作

    信号量机制: struct sempahore是其结构,定义如下 struct semaphore { atomic_t count;//资源数目 int sleepers;//等待进程数目 wait ...

  4. Linux内核情景分析的alloc_pages

    NUMA结构的alloc_pages ==================== mm/numa.c 43 43 ==================== 43 #ifdef CONFIG_DISCON ...

  5. Linux内核情景分析之异常访问,用户堆栈的扩展

    情景假设: 在堆内存中申请了一块内存,然后释放掉该内存,然后再去访问这块内存.也就是所说的野指针访问. 当cpu产生页面错误时,会把失败的线性地址放在cr2寄存器.线性地址缺页异常的4种情况 1.如果 ...

  6. linux内核情景分析之exit与Wait

    //第一层系统调用 asmlinkage long sys_exit(int error_code) { do_exit((error_code&0xff)<<8); } 其主体是 ...

  7. linux内核情景分析之匿名管道

    管道的机制由pipe()创建,由pipe()所建立的管道两端都在同一进程.所以必须在fork的配合下,才可以在具有亲缘关系的进程通信 /* * sys_pipe() is the normal C c ...

  8. linux内核情景分析之命名管道

    管道是一种"无名","无形文件,只可以近亲进程使用,不可以再任意两个进程通信使用,所以只能实现"有名","有形"的文件来实现就可以 ...

  9. linux内核情景分析之信号实现

    信号在进程间通信是异步的,每个进程的task_struct结构有一个sig指针,指向一个signal_struct结构 定义如下 struct signal_struct { atomic_t cou ...

随机推荐

  1. oracle中常用的两个伪列

    伪列 伪列就行oracle中的一个列表,但世界上它并未存储在表中,伪列可以被查询但是不能被插入或者更改. rowID 该伪列返回该行地址,可以使用rowID值来定位表中的一行.通常rowID值可以标识 ...

  2. 深入解析AJAX的原理

    AJAX:Asynchronous JavaScript And Xml(异步的JS和XML) 同步:客户端发起请求>服务端的处理和响应>客户端重新载入页面(循环) 异步:客户端实时请求& ...

  3. 开源数据库中间件-MyCat

    开源数据库中间件-MyCat产生的背景 如今随着互联网的发展,数据的量级也是成指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系型数据库已经无法满足快速查询与插入数据的需求.这 ...

  4. Codeforces:68A-Irrational problem(暴力大法好)

    A- Irrational problem p Time Limit: 2000MS Memory Limit: 262144K 64bit IO Format: %I64d& %I64 De ...

  5. HOJ 13819 Height map

    昨天校内比赛做了一个很有意思的题,体面如图: 题目大概意思是,给出一个俯视图矩阵,矩阵内元素表示当前位置有多少个方块,最后要求输出该立体图形中面的数量. 首先给出一组数据: 3 42 1 2 11 2 ...

  6. Androd安全——反编译技术完全解析

    )第二步成功后我们会发现在当前目录下多了一个<APKName>文件夹,这个文件夹中存放的就是反编译的结果了.我们可以打开AndroidManifest.xml.res/layout即可查看 ...

  7. HTML练习题

    1.查询一下对div和span标签的理解 div标签:是用来为HTML文档内大块的内容提供结构和背景的元素.DIV的起始标签和结束标签之间的所有内容都是用来构成这个块的,中文我们把它称作“层”. sp ...

  8. Redis实现之服务器

    命令请求的执行过程 一个命令请求从发送到获得回复的过程中,客户端和服务器需要完成一系列操作.举个栗子,如果我们使用客户端执行以下命令: 127.0.0.1:6379> SET KEY VALUE ...

  9. 【Triangle 】cpp

    题目: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjace ...

  10. UNIX 系统中 wc 程序的主要部分

    以下代码为 UNIX 系统中 wc 程序的骨干部分 #include <stdio.h> #define IN 1 #define OUT 0 int main(int argc, cha ...