莫小帅|kernel同步机制(上篇),Linux

【莫小帅|kernel同步机制(上篇),Linux】在现代操作系统里 , 同一时间可能有多个内核执行流在执行 , 因此内核其实像多进程多线程编程一样也需要一些同步机制来同步各执行单元对共享数据的访问 , 尤其是在多处理器系统上 , 更需要一些同步机制来同步不同处理器上的执行单元对共享的数据的访问 。 在主流的Linux内核中包含了如下这些同步机制包括:
原子操作信号量(semaphore)读写信号量(rw_semaphore)SpinlockMutexBKL(BigKernelLock , 只包含在2.4内核中 , 不讲)Rwlockbrlock(只包含在2.4内核中 , 不讲)RCU(只包含在2.6内核及以后的版本中)seqlock(只包含在2.6内核及以后的版本中)本文章分为两部分 , 这一章我们主要讨论原子操作 , 自旋锁 , 信号量和互斥锁 。
一、原子操作原子操作的概念来源于物理概念中的原子定义 , 指执行结束前不可分割(即不可打断)的操作 , 是最小的执行单位 。
原子操作与硬件架构强相关 , 其API具体的定义均位于对应arch目录下的include/asm/atomic.h文件中 , 通过汇编语言实现 , 内核源码根目录下的include/asm-generic/atomic.h则抽象封装了API , 该API最后分派的实现来自于arch目录下对应的代码 。
StructureDefinition
typedefstruct{intcounter;}atomic_t;
原子操作主要用于实现资源计数 , 许多引用计数(refcnt)就是通过原子操作实现 , 例如TCP/IP协议栈的IP碎片中 , structipq中的refcnt字段 , 类型即为atomic_t 。
atomic_add
原子操作的实现比较简单 , 以下为例 。
API
原子操作的API包括如下,以arm平台为例:
StructureDefinition
Lock&Unlock
由于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是否相等 , 不等则继续等待 , 相等则结束等待 。