莫小帅|Linux kernel同步机制(上篇)
在现代操作系统里 , 同一时间可能有多个内核执行流在执行 , 因此内核其实像多进程多线程编程一样也需要一些同步机制来同步各执行单元对共享数据的访问 , 尤其是在多处理器系统上 , 更需要一些同步机制来同步不同处理器上的执行单元对共享的数据的访问 。 在主流的Linux内核中包含了如下这些同步机制包括:
- 原子操作
- 信号量(semaphore)
- 读写信号量(rw_semaphore)
- Spinlock
- Mutex
- BKL(Big Kernel Lock , 只包含在2.4内核中 , 不讲)
- Rwlock
- brlock(只包含在2.4内核中 , 不讲)
- RCU(只包含在2.6内核及以后的版本中)
- seqlock(只包含在2.6内核及以后的版本中)
一、原子操作原子操作的概念来源于物理概念中的原子定义 , 指执行结束前不可分割(即不可打断)的操作 , 是最小的执行单位 。
原子操作与硬件架构强相关 , 其API具体的定义均位于对应arch目录下的include/asm/atomic.h文件中 , 通过汇编语言实现 , 内核源码根目录下的include/asm-generic/atomic.h则抽象封装了API , 该API最后分派的实现来自于arch目录下对应的代码 。
Structure Definition
typedefstruct{intcounter;}atomic_t;
原子操作主要用于实现资源计数 ,许多引用计数(refcnt)就是通过原子操作实现 , 例如TCP/IP协议栈的IP碎片中 , struct ipq中的refcnt字段 , 类型即为atomic_t 。
atomic_add
原子操作的实现比较简单 , 以下为例 。
原子操作的原子性依赖于ldrex与strex实现 , ldrex读取数据时会进行独占标记 , 防止其他内核路径访问 , 直至调用strex完成写入后清除标记 。 自然strex也不能写入被别的内核路径独占的内存 , 若是写入失败则循环至成功写入 。
API
原子操作的API包括如下, 以arm平台为例:
Structure Definition
Lock & Unlock
核心lock函数 , 使slock +2^16, 当next==owner时 , 释放锁 , 否则进入循环等待 。 Prefetchw用于cache预加载数据 。
由于slock与tickets共享同一块内存(union) , slock 占32位4字节 , tickets内部变量next与owner各16位2字节 。 以大端序为例 , slock 高2字节与next共享 , 低2字节与owner共享 , 因此arch_spin_lock实际上是将tickets.next+1 。 假设初始时next与owner皆为0 , 此时next与owner不等 , 通过wfe指令进入一小段时间等待状态 , 而后读取新的owner值检查与next是否相等 , 不等则继续等待 , 相等则结束等待 。
推荐阅读
- 莫小帅|极乐音乐app下载(软件篇)
- 莫小帅|不仅配置颜值很高,性价比也不错,目前最值得购买的三款华为手机
- 精英联盟总队|最详细的Linux简史——Linux大神带你领略它的前世今生
- 莫小帅|目前最值得购买的三款华为手机,不仅配置颜值很高,性价比也不错
- 莫小帅|14块8包邮廉价游戏耳麦晒单:RGB、蛋白耳罩、双钢梁全配齐
- 轻拔琴弦|给你一个反悔的机会
- 莫小帅|手机这么玩,以后谁还戴套
- 莫小帅|8月“最流畅”安卓手机榜,小米问鼎第一,三星竟然才第七?
- 莫小帅|英特尔 11 代酷睿发布:等,还是 AMD,Yes?
- 莫小帅|9月第一周
