【问题标题】:how to implement an atomic assignment on AIX/powerpc?如何在 AIX/powerpc 上实现原子分配?
【发布时间】:2011-09-29 16:53:22
【问题描述】:

我正在将内核扩展移植到多处理器 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”是什么意思?

【问题讨论】:

  • 那不是“原子”的意思!如果您想要订购保证,请使用内存屏障。 (或者只是使用锁,因为显然每个人都弄错了障碍。)
  • @tc:不幸的是,微处理器社区对“原子”一词的含义并不一致。当我大约在 1991 年定义 Intel x86 内存排序架构时,我使用了 tc 使用的定义——“原子”指的是看到一个操作全部完成或根本没有完成,永远不会半途而废,而“内存排序”则是另一回事。然而,ARM 最近使用“原子”来指代内存排序,“单一位置原子性”指代 tc 和我称之为“原子”的东西,而“多位置原子性”或“写入原子性”指代内存排序系统的属性。

标签: kernel aix powerpc atomic


【解决方案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

【讨论】:

    【解决方案2】:

    我已经回答了问题 1 和 2,但没有回答 3:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 2018-07-14
      • 1970-01-01
      • 2012-11-04
      相关资源
      最近更新 更多