3

cas を使用するために、gcc は
__sync_bool_compare_and_swap などの便利な関数を提供します

cmpxchg のような asm コードを使用することもできます

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;

gcc 4.6.3 のソース コードを grep したところ、__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 によって実装されていますか?

ありがとう!

4

1 に答える 1

4

__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);
}

GCC 4.4 を搭載した x86_64 Linux マシンでこれをコンパイルすると、次の asm が生成されます。


my_cmpchg:
.LFB0:
    .cfi_startproc
    movl    %esi, %eax
    lock cmpxchgl   %edx, (%rdi)
    sete    %al
    ret
    .cfi_endproc
于 2012-03-21T07:42:46.350 に答える