3

我正在开发 C/C++ 跨平台代码,最后一个平台是基于 Itanium 的 HP-UX。相关机器和处理器信息可在问题末尾找到。

我需要为下面给出的机器和编译器规范实现或找到原子比较和交换。

我找到了一些解决方案的可能性,但无法找到如何使用它们。

第一个可能的解决方案是使用 _Asm_cmpxchg(此处的文档)。我找不到为此包含的标头或如何编译它。

第二种可能的解决方案是直接使用 cmpxchg 和 cmpxchg8b 命令编写我自己的内联程序集,但我也无法找到正确执行此操作的方法。我找到了各种资源,其中大部分是直接编写程序集,而不是针对我需要的处理器架构,或者没有显示足够具体的示例。

我在这里找到了有关 cmpxchg 和 cmpxchg8 指令(以及 tzcnt 和 lzcnt 这两个很好,但不是必需的)的更多文档。如果您在谷歌浏览器中查看,cmpxchg 的绝对页面值为 234,cmpxchg8 的绝对页面值为 236。

限制:由于我无法控制的限制,我无法使用第三方库。

uname -smr 的结果: HP-UX B.11.31 ia64

处理器型号: Intel(R) Itanium(R) 处理器 9340

编译器-v: aCC:HP C/aC++ B3910B A.06.28

更新:我能够编译 _Asm_cmpxchg,但它似乎不起作用(值保持不变)。对于参数,我为 _Asm_sz 传递了 _SZ_W,为 _Asm_sem 传递了 _SEM_ACQ,为 _Asm_ldhint 传递了 _LDHINT_NONE,为 r3 传递了一个指向原始 32 位整数值的指针,为 r2 传递了所需的新值。鉴于文档非常乏味,我猜测参数的含义。

4

1 回答 1

1

我最终使用选项 1 自己找到了解决方案。下面是使其工作的示例代码:

bool compare_and_swap(unsigned int* var, unsigned int oldval, unsigned int newval)
{
    // Move the old value into register _AREG_CCV because this is the register
    // that var will be compared against
    _Asm_mov_to_ar(_AREG_CCV, oldval);
    // Do the compare and swap
    return oldval == _Asm_cmpxchg(
        _SZ_W /* 4 byte word */, 
        _SEM_ACQ /* acquire the semaphore */, 
        var, 
        newval, 
        _LDHINT_NONE /* locality hint */);
}
于 2015-08-20T20:39:59.607 回答