使用cas,gcc提供了一些有用的功能,如
__sync_bool_compare_and_swap
但我们也可以使用asm代码,如cmpxchg
bool ret;
__asm__ __volatile__(
"lock cmpxchg16b %1;\n"
"sete %0;\n"
:"=m"(ret),"+m" (*(volatile pointer_t *) (addr))
:"a" (old_value.ptr), "d" (old_value.tag), "b" (new_value.ptr), "c" (new_value.tag));
return ret;
我有grep gcc 4.6.3的源代码,发现__sync_bool_compare_and_swap是用
实现的typedef int (__kernel_cmpxchg_t) (int oldval, int newval, int *ptr);
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
似乎0xffff0fc0是某些内核帮助函数的地址
但是在gcc 4.1.2中,没有像__kernel_cmpxchg_t这样的代码,我找不到__sync_bool_compare_and_swap的实现。
那么__sync_bool_compare_and_swap和cmpxchg之间的区别是什么?
是_mpync_bool_compare_and_swap由cmpxchg实现?
并且使用内核帮助函数__kernel_cmpxchg_t,它是由cmpxchg实现的吗?
谢谢!
答案 0 :(得分:3)
我认为__kernel_cmpxchg是Linux在一些没有CAS本机硬件支持的架构上提供的回退。例如。 ARMv5或类似的东西。
通常,GCC内联扩展了_ sync * builtins。除非你真的对GCC内部感兴趣,否则更容易找到它的作用是创建一个简单的C示例并查看编译器生成的ASM。
考虑
#include <stdbool.h>
bool my_cmpchg(int *ptr, int oldval, int newval)
{
return __sync_bool_compare_and_swap(ptr, oldval, newval);
}
在具有GCC 4.4的x86_64 Linux机器上进行编译,生成以下asm:
my_cmpchg:
.LFB0:
.cfi_startproc
movl %esi, %eax
lock cmpxchgl %edx, (%rdi)
sete %al
ret
.cfi_endproc