内核中4种并发源
- 中断和异常
- 软中断和tasklet
- 内核抢占
- 多核处理器并发执行
保护资源或数据,而非保护代码
原子操作和内存屏障
[include/linux/types.h]
typedef struct{
int counter;
} atomic_t;
- 在ARM处理器中,如何实现独占访问内存
LL/SC操作:Load-Link(LL)操作返回一个内存地址上当前存储的值,后面的Store-Conditional(SC)操作,会向这个内存地址写入一个新值,但是只有在这个内存地址上存储的值,从上个LL操作开始直到现在都没有发生改变的情况下,写入操作才能成功,否则都会失败。
对于ARM平台来说,在硬件层面上提供了对LL/SC的支持,LL操作用的是LDREX指令,SC操作用的是STREX指令。
-
LDREX Rx, [Ry] 读取寄存器Ry指向的4字节内存值,将其保存到Rx寄存器中,同时标记对Ry指向内存区域的独占访问。
如果执行LDREX指令的时候发现已经被标记为独占访问了,并不会对指令的执行产生影响。 -
STREX Rx, Ry, [Rz] STREX在更新内存数值时,会检查该段内存是否已经被标记为独占访问,并以此来决定是否更新内存中的值。如果执行这条指令的时候发现已经被标记为独占访问了,则将寄存器Ry中的值更新到寄存器Rz指向的内存,并将寄存器Rx设置成0。指令执行成功后,会将独占访问标记位清除。而如果执行这条指令的时候发现没有设置独占标记,则不会更新内存,且将寄存器Rx的值设置成1。一旦某条STREX指令执行成功后,以后再对同一段内存尝试使用STREX指令更新的时候,会发现独占标记已经被清空了,就不能再更新了,从而实现独占访问的机制
ARM有2种独占监视器(Exclusive Monito):每一个处理器内部都有一个本地监视器(Local Monitor),且在整个系统范围内还有一个全局监视器(Global Monitor)
- atomic_cmpxchg()和atomic_xchg()分别表示什么含义
[include/asm-generic/atomic.h]
#define atomic_cmpxchg(v, old, new) 比较old和原子变量v的值,如果相等则把new赋值给v,返回原子变量v的旧值
#define atomic_xchg(v, new) 把new赋值给原子变量v,返回原子变量v的旧值