В чем разница между gcc __sync_bool_compare_and_swap и cmpxchg? - PullRequest
2 голосов
/ 21 марта 2012

для использования 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 исходный код gcc4.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?

__sync_bool_compare_and_swap реализован cmpxchg?

и с помощью вспомогательной функции ядра __kernel_cmpxchg_t, это реализовано cmpxchg?

спасибо!

1 Ответ

3 голосов
/ 21 марта 2012

Я думаю, что __kernel_cmpxchg - это запасной вариант, который Linux делает доступным на некоторых архитектурах, которые не имеют встроенной аппаратной поддержки CAS. Например. ARMv5 или что-то в этом роде.

Обычно GCC inline расширяет встроенные функции _ sync *. Если вы действительно не интересуетесь внутренними компонентами GCC, более простой способ выяснить, что он делает, - это сделать простой пример C и посмотреть на ASM, сгенерированный компилятором.

Рассмотрим


#include <stdbool.h>

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

Компилируя это на компьютере x86_64 Linux с GCC 4.4, генерируется следующий asm:


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