概述
在编程中,当多个处理器或线程访问共享数据,并且至少有一个正在写入时,操作必须是原子的,这意味着数据访问必须被视为相对于其他处理器的单个操作,以避免数据竞争条件。
原子操作的实现依赖处理器硬件提供支持,在不同的处理器体系结构上,原子操作会有不同的实现,例如在x86体系结构下,通常使用锁缓存/总线的方式实现原子操作。目前在ARMv8体系结构下支持两种方式来实现原子操作:
- 一种是经典的独占内存访问机制,也叫做LL/SC(Load-Link/Store-Conditional),早期ARM体系结构下的原子操作都是基于这种方式实现;
- 另一种是ARMv8.1体系结构上新增的LSE(Large System Extension)扩展,LSE提供了多种原子内存访问操作指令。
LL/SC机制
LL/SC机制使用多个指令,并且每个处理器都需要实现一个专有监视器,LL/SC机制利用独占内存访问指令和独占监视器共同实现原子操作。首先看下ARMv8体系结构提供的独占内存访问指令。
独占内存访问指令
ARMv8体系结构实现的独占内存访问指令为LDXR/STXR:
- LDXR:内存独占加载指令,它从内存中以独占方式加载内存地址的值到寄存器中;
- STXR:内存独占存储指令,它以独占的方式把数据存储到内存中。
LDXR/STXR的指令格式如下:
ldxr <xt>, [xn | sp]
stxr <ws>, <xt>, [xn | sp]
多字节独占内存访问指令
LDXP和STXP指令是多字节独占内存访问指令,一条指令可以独占地加载和存储16字节。
ldxp <xt1>, <xt2&