Linux – What is the difference between gcc __sync_bool_compare_and_swap and cmpxchg?

What is the difference between gcc __sync_bool_compare_and_swap and cmpxchg?… here is a solution to the problem.

What is the difference between gcc __sync_bool_compare_and_swap and cmpxchg?

To use CAS, GCC provides useful functions such as
:
__sync_bool_compare_and_swap

But we can also use ASM code like 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;

I greped the source code for gcc 4.6.3 and found that __sync_bool_compare_and_swap was implemented with it

typedef int (__kernel_cmpxchg_t) (int oldval, int newval, int *ptr); 
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)

It seems that 0xffff0fc0 is the address of some kernel helper function

But in gcc 4.1.2, there is no code like this __kernel_cmpxchg_t and I can’t find an implementation of __sync_bool_compare_and_swap either.

So what’s the difference between __sync_bool_compare_and_swap and cmpxchg?

Is __sync_bool_compare_and_swap implemented by cmpxchg?

There are also kernel helper functions__kernel_cmpxchg_t, is it implemented by cmpxchg?

Thanks!

Solution

I think __kernel_cmpxchg is a fallback provided by Linux on some architectures that don’t have CAS native hardware support. For example. ARMv5 or something similar.

Typically, GCC extends the _sync* built-in function inline. Unless you’re really interested in GCC internals, an easier way to understand what it does is to make a simple C example and look at the ASM generated by the compiler.

Consider


#include <stdbool.h>

bool my_cmpchg(int *ptr, int oldval, int newval)
{
    return __sync_bool_compare_and_swap(ptr, oldval, newval);
}

Compile on a x86_64 Linux machine with GCC 4.4 to generate the following asm:


my_cmpchg:
. LFB0:
    .cfi_startproc
    movl    %esi, %eax
    lock cmpxchgl   %edx, (%rdi)
    sete    %al
    ret
    .cfi_endproc

Related Problems and Solutions