我正在编写独立于操作系统的无锁队列,队列工作正常(使用默认的windows \ linux原子CAS),但我想让队列工作而不需要在linux和windows中进行任何更改。所以我猜我应该在汇编程序中编写自己的CAS,还是有其他方法可以实现?
到目前为止,我有这段代码:
global _CAS
_CAS:
mov eax, [esp+4]
mov edx, [esp+8]
mov ecx, [esp+12]
;XCHG eax, edx <- this function works fine
CMPXCHG ecx, eax, ebx
ret
我知道我仍然必须在lock
之前添加CMPXCHG
并且它应该与结构一起使用,但是现在我对使其工作更感兴趣。
我使用nasm-2.10.05使用此命令编译nasm.exe -f elf -o cas.o cas.asm
我收到此错误testas\cas.asm:14: error: invalid combination of opcode and operands
答案 0 :(得分:12)
你可以在两个平台上使用内在函数来完成它,不需要汇编:
#ifdef _MSC_VER
# include <intrin.h>
# define CAS(ptr, oldval, newval) \
_InterlockedCompareExchange(ptr, newval, oldval)
#elif __GNUC__
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
# error "requires GCC 4.1 or greater"
# endif
# define CAS(ptr, oldval, newval) \
__sync_val_compare_and_swap(ptr, oldval, newval)
#else
# error "CAS not supported on this platform"
#endif
这两个都支持以下界面:
/* If the current value of *ptr is oldval, then write newval
into *ptr. Returns the initial value of *ptr. */
long CAS(long *ptr, long oldval, long newval);
请参阅MSDN documentation,GCC documentation。这也应该对Clang起作用而不做任何修改,因为Clang宣传__GNUC__
与其预定义宏的兼容性。
答案 1 :(得分:3)