HP-UX 安腾比较和交换
HP-UX Itanium Compare and Swap
我正在开发 C/C++ cross-platform 代码,最后一个平台是基于安腾的 HP-UX。相关机器处理器信息可以在问题末尾找到。
我需要针对下面给出的机器和编译器规范实施或查找原子比较和交换。
我找到了一些可能的解决方案,但一直找不到如何使用它们。
第一个可能的解决方案是使用 _Asm_cmpxchg (documentation here)。我找不到 header 为此包含什么或如何让它编译。
第二种可能的解决方案是直接使用 cmpxchg 和 cmpxchg8b 命令编写我自己的内联程序集,但我也未能找到正确执行此操作的方法。我找了各种资源,大部分都是直接写汇编,不是我需要的处理器架构,或者没有给出足够具体的例子。
我找到了更多关于 cmpxchg 和 cmpxchg8 指令的文档(以及 tzcnt 和 lzcnt,这两个指令很不错,但不是必需的)here。如果您在 google chrome 中查看,绝对页面值对于 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,指向原始 32 位整数的指针r3 的值,以及 r2 所需的新值。我在猜测参数的含义,因为文档非常乏味。
我最终使用选项 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 */);
}
我正在开发 C/C++ cross-platform 代码,最后一个平台是基于安腾的 HP-UX。相关机器处理器信息可以在问题末尾找到。
我需要针对下面给出的机器和编译器规范实施或查找原子比较和交换。
我找到了一些可能的解决方案,但一直找不到如何使用它们。
第一个可能的解决方案是使用 _Asm_cmpxchg (documentation here)。我找不到 header 为此包含什么或如何让它编译。
第二种可能的解决方案是直接使用 cmpxchg 和 cmpxchg8b 命令编写我自己的内联程序集,但我也未能找到正确执行此操作的方法。我找了各种资源,大部分都是直接写汇编,不是我需要的处理器架构,或者没有给出足够具体的例子。
我找到了更多关于 cmpxchg 和 cmpxchg8 指令的文档(以及 tzcnt 和 lzcnt,这两个指令很不错,但不是必需的)here。如果您在 google chrome 中查看,绝对页面值对于 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,指向原始 32 位整数的指针r3 的值,以及 r2 所需的新值。我在猜测参数的含义,因为文档非常乏味。
我最终使用选项 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 */);
}