EN JA
ATOMIC_VAR_INIT(3)
ATOMIC_VAR_INIT(3) FreeBSD Library Functions Manual ATOMIC_VAR_INIT(3)

名称

ATOMIC_VAR_INIT, atomic_init, atomic_load, atomic_store, atomic_exchange, atomic_compare_exchange_strong, atomic_compare_exchange_weak, atomic_fetch_add, atomic_fetch_and, atomic_fetch_or, atomic_fetch_sub, atomic_fetch_xor, atomic_is_lock_freeタイプに一般的な不可分の操作

書式

#include < stdatomic.h>

_Atomic(T) v = ATOMIC_VAR_INIT(c);
void
atomic_init( _Atomic(T) *object, T value);

T
atomic_load( _Atomic(T) *object);

T
atomic_load_explicit( _Atomic(T) *object, memory_order order);

void
atomic_store( _Atomic(T) *object, T desired);

void
atomic_store_explicit( _Atomic(T) *object, T desired, memory_order order);

T
atomic_exchange( _Atomic(T) *object, T desired);

T
atomic_exchange_explicit( _Atomic(T) *object, T desired, memory_order order);

_Bool
atomic_compare_exchange_strong( _Atomic(T) *object, T *expected, T desired);

_Bool
atomic_compare_exchange_strong_explicit( _Atomic(T) *object, T *expected, T desired, memory_order success, memory_order failure);

_Bool
atomic_compare_exchange_weak( _Atomic(T) *object, T *expected, T desired);

_Bool
atomic_compare_exchange_weak_explicit( _Atomic(T) *object, T *expected, T desired, memory_order success, memory_order failure);

T
atomic_fetch_add( _Atomic(T) *object, T operand);

T
atomic_fetch_add_explicit( _Atomic(T) *object, T operand, memory_order order);

T
atomic_fetch_and( _Atomic(T) *object, T operand);

T
atomic_fetch_and_explicit( _Atomic(T) *object, T operand, memory_order order);

T
atomic_fetch_or( _Atomic(T) *object, T operand);

T
atomic_fetch_or_explicit( _Atomic(T) *object, T operand, memory_order order);

T
atomic_fetch_sub( _Atomic(T) *object, T operand);

T
atomic_fetch_sub_explicit( _Atomic(T) *object, T operand, memory_order order);

T
atomic_fetch_xor( _Atomic(T) *object, T operand);

T
atomic_fetch_xor_explicit( _Atomic(T) *object, T operand, memory_order order);

_Bool
atomic_is_lock_free( const _Atomic(T) *object);

解説

ヘッダ < stdatomic.h> は、不可分な操作のためにタイプに一般的なマクロを提供します。ロックを獲得せずに、ほとんどの場合、修正されるかもしれないスレッドの間の共用変数を提供するためにマルチスレッド化されたプログラムによって不可分な動作を、使用することができます。

不可分の変数は、 _Atomic() タイプ指定子を使用して宣言されます。これらの変数は、それらの不可分でないものとタイプ互換性がありません。使用されるコンパイラによって、不可分の変数は、不透明かもしれないし、したがって、記述されたマクロの使用のみ影響を受けるかもしれません。

atomic_init() マクロは、 value で不可分の変数 object を初期化します。 ATOMIC_VAR_INIT() を使用して宣言される間に不可分の変数を初期化することができます。

atomic_load() マクロは、不可分の変数 object の値を返します。 atomic_store() マクロは、不可分の変数 object をその desired (希望する) 値に設定します。

atomic_exchange() マクロは、 atomic_load() と atomic_store() の振る舞いを組み合わせます。不可分の変数 object をその希望する value (値) に設定し、不可分の変数の元の内容を返します。

atomic_compare_exchange_strong() マクロは、不可分の変数がその expected (期待) 値と等しい場合のみ、 desired (希望する) 値を不可分の変数オブジェクト object に格納します。成功すれば、マクロは、 true を返します。失敗すれば、 desired (希望する) 値は、不可分の変数の値で上書きされ、 false が返されます。 atomic_compare_exchange_weak() マクロは、 atomic_compare_exchange_strong() と同一ですが、不可分の変数 object がその expected (期待) 値と等しくても失敗することが許されます。

atomic_fetch_add() マクロは、値 operand を不可分の変数 object に追加して、不可分の変数の元の内容を返します。

atomic_fetch_and() マクロは、 and 演算しを不可分の変数 objectoperand に適応し、値を object に格納する一方、不可分の変数の元の内容を返します。

atomic_fetch_or() マクロは、 or 演算子を不可分の変数 objectoperand に適用し、値を object に格納する一方、不可分の変数の元の内容を返します。

atomic_fetch_sub() マクロは、不可分の変数 object から値 operand を減算し、不可分の変数の元の内容を返します。

atomic_fetch_xor() マクロは、不可分の変数 objectoperandxor 演算しを適用し、値を object に格納する一方、不可分の変数の元の内容を返します。

atomic_is_lock_free() マクロは、不可分の演算を使用するとき、不可分の変数 object がロックを使用しているかどうかを返します。

バリア

以前に記述された不可分の演算は、それらが、不可分の演算を横切ってあらゆる近隣のメモリ操作を再順序付けするうためにコンパイラと実行プロセッサの両方を許可しないように実装されます。ある場合に、この振る舞いは、次善の (suboptimal) 実行を引き起こすかもしれません。これを和らげるために、すべての不可分の演算には、設定されるために再順序付けを許可する _explicit() バージョンがあります。

これらの _explicit() マクロの order パラメータには、次の値のうちの 1 つを指定できます。

memory_order_relaxed
メモリを順序付けする演算がありません。
memory_order_consume
消費演算を実行します。
memory_order_acquire
フェンス (fence) を獲得します。
memory_order_release
フェンス (fence) を解放します。
memory_order_acq_rel
フェンス (fence) を獲得して解放します。
memory_order_seq_cst
連続して一貫しているフェンス (fence) を獲得して解放します。

以前に記述されたマクロは、 ordermemory_order_seq_cst であるとき、 _explicit() マクロと同一です。

コンパイラのサポート

これらの不可分な操作は、それらが、タイプに一般的に実装されていなければならず、しばしば特別のハードウェアの命令を使用しなければならないので、一般的にコンパイラによって実装されます。このインタフェースは、ほとんどのコンパイラによって採用されていないので、 < stdatomic.h> ヘッダは、前方互換性を提供するために既存のコンパイラに本質的なものの上に、これらのマクロを実装しています。

これは、異なるバリアのタイプのためのサポートのようなインタフェースの特定の状況が単に無視されるかもしれないことを意味します。 GCC を使用するとき、すべての不可分の演算は、あたかもそれらが memory_order_seq_cst を使用しているかのように、実行されます。

このインタフェースによって提供される不可分な演算を使用する代わりに、 ISO/IEC 9899:2011 (“ISO C11”) によって、不可分の変数を、組み込みの言語演算子を使用して直接修正することができます。より古いコンパイラに対してにこの振る舞いを、エミュレートすることはできません。これらの変数への故意でない不可分でないアクセスを防ぐために、このヘッダファイルは、より古いコンパイラを使用するとき、構造体に不可分の変数を置きます。

本質的に不可分の組み込みのためのサポートが不足しているアーキテクチャで GCC を使用するとき、これらのマクロは、フォールバックルーチンへの関数呼び出しを行います。これらのフォールバックルーチンは、CPU によってサポートされているなら、 32 ビットと 64 ビットのデータタイプのためだけに実装されます。

関連項目

pthread(3), atomic(9)

規格

これらのマクロは、 ISO/IEC 9899:2011 (“ISO C11”) に適合することを試みています。

歴史

これらのマクロは、 FreeBSD 10.0 で登場しました。

作者

Ed Schouten <ed@FreeBSD.org>, David Chisnall <theraven@FreeBSD.org>
December 27, 2011 FreeBSD