我在多处理器PowerPC上将内核扩展区移植到32/64位AIX,用C语言编写。我不需要更多的原子读操作和原子写操作(我没有使用fetch-and-添加,比较和交换等) 只是为了澄清:对我而言,“原子性”不仅意味着“没有交错”,而且意味着“跨多个核心的可见性”。 操作对指针进行操作,因此对'int'变量的操作对我来说是无用的。
如果我声明变量“volatile”,C标准表示该变量可以被未知因素修改,因此不受优化。
根据我的阅读,似乎常规读写应该是非交错的,linux kernel souces似乎同意。它说:
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
stw
是“存储字”,这应该是原子的,但我不知道“%U0%X0”是什么意思。我不明白这个汇编指令如何强加可见性。
当我编译我的内核扩展时,'std'用于我想要的赋值,但它对于64位机器也应该是原子的,从我读到的。我对PowerPC及其指令集的具体细节知之甚少。但是我没有在编译文件的汇编列表中找到任何内存屏障指令(“sync”或“eieio”)。
内核提供了fetch_and_addlp()服务,可用于实现原子读取(例如v = fetch_and_addlp(&x, 0)
)。
所以我的问题是:
是否足以声明变量'volatile'以在可见性和无交错的意义上实现读写原子性?
如果对1的回答是“否”,那么这种原子性是如何实现的?
Linux PowerPC原子实现中“%U0%X0”的含义是什么?
答案 0 :(得分:1)
GCC内联汇编语法中存在特性。
在该行中,
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
m
是输出操作数,r
是输入操作数。 %1和%0指的是参数顺序(0-> m,1-> r)
stw
汇编指令有2个参数,%U0%X0是参数的约束。这些限制是迫使GCC分析参数并确保你不做一些愚蠢的事情。事实证明,'U'是特定于powerpc的(我习惯于X64约束集:)。完整的约束列表可在以下网址找到:
http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints
答案 1 :(得分:0)
我设法回答问题1和2,但不是3: