【1】实现线程同步,独占访问,保证多核系统中的内存操作原子性。
ARM架构提供了三条与独占访问相关的指令(读、写、清),以及这些指令的变体,操作字节/半字/字/双字大小的数据。指令依赖于CORE或内存系统的能力来标记特定地址,以便由该核心使用独占访问监视器进行独占访问监视。指令可用于单/多核系统,用于实现运行在同一核心上的线程之间的同步操作。
1.1 指令
ARMv7架构:LDREX, STREX
ARMv8架构:LDXR(load exclusive register), STXR(store exclusive register)及其变种指令
ARMv8.1架构:原子指令(如LDADD(Atomic add), CAS(Compare and Swap))
1.2 与一般指令(LDR, STR)区别
LDXR除了向memory发起load请求外,还会记录该memory所在地址的状态(一般ARM处理器在同一个cache line大小,也就是64 byte的地址范围内共用一个状态),那就是Open和Exclusive。
1.3 处理流程
LDREX和STREX指令,是将单纯的更新内存的原子操作分成了两个独立的步骤。
大致流程:
(1)LDREX读取内存中的值,并标记对该段内存的独占访问:LDREX Rx, [Ry]。
读取寄存器Ry指向地址内的值,将其保存到Rx寄存器中,同时标记对Ry指向地址的独占访问。
如果执行LDREX指令时,地址已被标记为独占访问,也并不影响指令的执行(读操作不受影响)
(2)STREX更新内存中的值,会检查该段内存是否已经被标记为独占访问,并以此来决定是否更新内存中的值:STREX Rx, Ry, [Rz]。
若地址已被标记为独占访问,则将寄存器Ry中的值更新到寄存器Rz指向的内存,同时Rx置为0。指令执行成功后,会将独占访问标记位清除。
若地址未被标记为独占访问,则不会更新内存,同时Rx置为1。
(3)同一段地址,在被某条STREX指令执行成功后,独占访问标记则被清除,那么内存无法再次使用STREX指令进行更新,从而实现独占访问的机制。(不论多少处理器,多少地方申请内存操作,只有最早的STREX指令写入才能成功,随后都会失败,当然也可以再次LDREX读取,然后STREX写入)
1.4 使用要求
配对使用:
(1)LDREXB和STREXB:内存中单字节(Byte,8 bit)独占访问;
(2)LDREXH和STREXH:内存中双字节(Half Word,16 bit)独占访问;
(3)LDREXD和STREXD:内存中四字节(Double Word,64 bit)独占访问。
注:每个核心只能标记一个地址。独占监视器并不阻止其他核心或线程读写所监视的位置,而是简单地监视自LDXR以来该位置是否已被写入。
【2】