问题描述
我发现 LDREX
和 STREX
可能是要使用的。但是它们是两个 指令(因此不提供 xchgl
的原子性)。我想要原子交换的值是一个32位值。
Can LDREX
和 STREX
可用于提供32位值的原子交换或他们是否有其他方法来实现它(假设它在armv7l或更高版本上工作)?
I found LDREX
and STREX
might be the ones to use. But they are two instructions (and thus not provide the atomicity of xchgl
). The value I want to exchange atomically is a 32-bit value.Can LDREX
and STREX
be used in a way that provides atomic exchange of a 32-bit value or are they other ways to achieve it (provided it works on armv7l or higher)?
通常,我会使用gcc的或更新的(与C ++ 11相当的)
用于这种原子操作。但在这种情况下,我必须在C中使用内联汇编(以将基于x86的futex实现移植到ARM体系结构中)。谢谢!
Normally, I'd the gcc's atomic builtins or the more recent (C++11 equivalent) builtin functionsfor such atomic operations. But in this case, I have to use inline assembly in C (to port an x86-based futex implementation to ARM architecture). Thanks!
推荐答案
在ARM指令集中,没有原子交换指令。相反,您可以使用 ldrex
和 strex
以及如下代码:
In the ARM instruction set, there is no atomic exchange instruction. Instead you use ldrex
and strex
and code like this:
@ exchange r0 and [r1]
ldrex r2,[r1]
strex r3, r0,[r1]
mov r0,r2
当 [r1]
在 ldrex
和 strex
或者由于其他原因无法保证交换是原子的,1返回在 r3
并且不执行存储。如果序列是原子序列,则返回0。因此,通过在循环中执行此代码片段,直到获得零 r3
,您最终可以实现原子交换操作。实际上,gcc和clang是如何实现相应的内在的;将 -S
传递给编译器以观察它的作用。
When [r1]
is modified between ldrex
and strex
or the exchange cannot be guaranteed to be atomic for some other reason, 1 is returned in r3
and the store isn't performed. If the sequence is atomic, 0 is returned. Thus, by executing this snippet in a loop until you get a zero r3
you can eventually reach an atomic exchange operation. That's actually how gcc and clang implement the corresponding intrinsic; pass -S
to the compiler to observe what it does.
这篇关于什么是ARM指令相当于英特尔的xchgl?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!