如何在AIX / powerpc上实现原子赋值?

时间:2011-07-06 14:37:27

标签: kernel atomic aix powerpc atomicity

我在多处理器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))。

所以我的问题是:

  1. 是否足以声明变量'volatile'以在可见性和无交错的意义上实现读写原子性?

  2. 如果对1的回答是“否”,那么这种原子性是如何实现的?

  3. Linux PowerPC原子实现中“%U0%X0”的含义是什么?

2 个答案:

答案 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:

  1. 不,这还不够。
  2. 仍然需要内存屏障。我使用了__lwsync()中内置的XLC。这应该都可以防止处理器重新排序并将更改发布到其他处理器。