1. /*
  2. * These are the generic versions of the spinlocks and read-write
  3. * locks..
  4. *///自旋锁加锁,irqsave表示把标志寄存器存储起来
  5. #define spin_lock_irqsave(lock, flags) do { local_irq_save(flags);//关闭本地中断,保存标志位 spin_lock(lock); } while (0)
  6. #define spin_lock_irq(lock) do { local_irq_disable(); spin_lock(lock); } while (0)
  7. #define spin_lock_bh(lock) do { local_bh_disable(); spin_lock(lock); } while (0)
  8. //读锁与下面写锁,构成读写锁
  9. #define read_lock_irqsave(lock, flags) do { local_irq_save(flags); read_lock(lock); } while (0)
  10. #define read_lock_irq(lock) do { local_irq_disable(); read_lock(lock); } while (0)
  11. #define read_lock_bh(lock) do { local_bh_disable(); read_lock(lock); } while (0)
  12. //写锁,与上面构成读写锁
  13. #define write_lock_irqsave(lock, flags) do { local_irq_save(flags); write_lock(lock); } while (0)
  14. #define write_lock_irq(lock) do { local_irq_disable(); write_lock(lock); } while (0)
  15. #define write_lock_bh(lock) do { local_bh_disable(); write_lock(lock); } while (0)
  16. //自旋锁解锁
  17. #define spin_unlock_irqrestore(lock, flags) do { spin_unlock(lock); local_irq_restore(flags); } while (0)
  18. #define spin_unlock_irq(lock) do { spin_unlock(lock); local_irq_enable(); } while (0)
  19. #define spin_unlock_bh(lock) do { spin_unlock(lock); local_bh_enable(); } while (0)
  20. //读锁解锁
  21. #define read_unlock_irqrestore(lock, flags) do { read_unlock(lock); local_irq_restore(flags); } while (0)
  22. #define read_unlock_irq(lock) do { read_unlock(lock); local_irq_enable(); } while (0)
  23. #define read_unlock_bh(lock) do { read_unlock(lock); local_bh_enable(); } while (0)
  24. //写锁解锁
  25. #define write_unlock_irqrestore(lock, flags) do { write_unlock(lock); local_irq_restore(flags); } while (0)
  26. #define write_unlock_irq(lock) do { write_unlock(lock); local_irq_enable(); } while (0)
  27. #define write_unlock_bh(lock) do { write_unlock(lock); local_bh_enable(); } while (0)


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

    DFS主要在于参数的改变; 样例输入: n=4                //给定n个数字 a={1,2,4,7}    //输入n个数据 k=15              //目标数字 样例输 ...

  2. kali下将Python2.x切换至Python3.x

    注:我是将Python2切换到Python3.6版本的,下面文件夹名,请注意变更. 1.首先在/usr/local/下创建一个Python-3.6 注意文件夹名(根建议据自己安装版本命名)mkdir ...

  3. requests.exceptions.SSLError……Max retries exceeded with url错误求助!!!

    import requests head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Appl ...

  4. Darwin's Letter【达尔文的信】

    Darwin's Letter A letter written by Charles Darwin in 1875 has been returned to the Smithsonian Inst ...

  5. Broken robot CodeForces - 24D (概率DP)

    You received as a gift a very clever robot walking on a rectangular board. Unfortunately, you unders ...

  6. HihoCoder - 1636 Pangu and Stones(区间DP)

    有n堆石子,每次你可以把相邻的最少L堆,最多R堆合并成一堆. 问把所有石子合并成一堆石子的最少花费是多少. 如果不能合并,输出0. 石子合并的变种问题. 用dp[l][r][k]表示将 l 到 r 之 ...

  7. P3402 最长公共子序列(nlogn)

    P3402 最长公共子序列 题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子 ...

  8. 【面试】一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生

    曾经的VIP服务 在网络的初期,网民很少,服务器完全无压力,那时的技术也没有现在先进,通常用一个线程来全程跟踪处理一个请求.因为这样最简单. 其实代码实现大家都知道,就是服务器上有个ServerSoc ...

  9. day10 消息队列,多进程和多线程以及协程,异步IO,事件驱动等

    回顾一下线程和进程 线程与进程的区别 守护线程: 队列: 两种方式: 先进先出  # 后入先出   #卖水果,后来的来的是新的 生产者消费者模型: 生产包子, 吃包子 事件 event: 红绿灯模型 ...

  10. luogu1829 [国家集训队]Crash的数字表格

    被 bs 了姿势水平--好好学习数学QAQQAQQAQ ref #include <iostream> #include <cstring> #include <cstd ...