名前空間
変種
操作

atomic_compare_exchange_weak, atomic_compare_exchange_strong, atomic_compare_exchange_weak_explicit, atomic_compare_exchange_strong_explicit

From cppreference.com
< C‎ | atomic
ヘッダ<stdatomic.h>で定義
_Bool atomic_compare_exchange_strong( volatile A* obj,
                                      C* expected, C desired );
(1) (C11 以降)
_Bool atomic_compare_exchange_weak( volatile A *obj,
                                    C* expected, C desired );
(2) (C11 以降)
_Bool atomic_compare_exchange_strong_explicit( volatile A* obj,

                                               C* expected, C desired,
                                               memory_order succ,

                                               memory_order fail );
(3) (C11 以降)
_Bool atomic_compare_exchange_weak_explicit( volatile A *obj,

                                             C* expected, C desired,
                                             memory_order succ,

                                             memory_order fail );
(4) (C11 以降)

obj が指すメモリの内容と `expected` が指すメモリの内容を比較し、それらがビット単位で等しい場合は、前者を `desired` に置き換えます(読み取り-変更-書き込み操作を実行します)。そうでない場合は、`obj` が指すメモリの実際のコンテンツを `*expected` にロードします(ロード操作を実行します)。

読み取り-変更-書き込み操作とロード操作のメモリモデルは、それぞれ `succ` と `fail` です。(1-2)のバージョンでは、デフォルトで memory_order_seq_cst が使用されます。

関数の弱い形式((2) および (4))は、偽陽性で失敗することが許可されています。つまり、たとえ等しくても *obj != *expected であるかのように動作します。比較交換がループ内にある場合、弱いバージョンは一部のプラットフォームでパフォーマンスが向上します。弱い比較交換がループを必要とし、強い比較交換が不要な場合は、強い方が好ましいです。

これは、すべてのアトミックオブジェクト型Aに対して定義された汎用関数です。引数は、非volatileなアトミックオブジェクトとvolatile(例: メモリマップドI/O)なアトミックオブジェクトの両方のメモリアドレスを受け入れるために、volatileアトミック型へのポインタです。volatileアトミックオブジェクトにこの操作を適用する場合、volatileセマンティクスが保持されます。CAに対応する非アトミック型です。

汎用関数の名前がマクロであるか、外部リンケージで宣言された識別子であるかは未指定です。実際の関数にアクセスするためにマクロ定義が無効にされた場合(例: (atomic_compare_exchange)(...) のように括弧で囲まれた場合)、またはプログラムが汎用関数の名前を持つ外部識別子を定義した場合、その動作は未定義です。

目次

[編集] パラメータ

obj - テストおよび変更するアトミックオブジェクトへのポインタ
expected - アトミックオブジェクトに期待される値へのポインタ
desired - アトミックオブジェクトが期待どおりの場合に格納する値
succ - 比較が成功した場合の読み取り-変更-書き込み操作のメモリ同期順序。すべての値が許可されます。
fail - 比較が失敗した場合のロード操作のメモリ同期順序。memory_order_release または memory_order_acq_rel にすることはできず、`succ` よりも強い順序を指定することはできません。

[編集] 戻り値

比較の結果:`*obj` が `*exp` と等しかった場合は true、それ以外の場合は false

[編集] 注記

atomic_compare_exchange_* ファミリの動作は、以下がアトミックに実行されたかのようです。

if (memcmp(obj, expected, sizeof *obj) == 0) {
    memcpy(obj, &desired, sizeof *obj);
    return true;
} else {
    memcpy(expected, obj, sizeof *obj);
    return false;
}

[編集] 参考文献

  • C17標準 (ISO/IEC 9899:2018)
  • 7.17.7.4 The atomic_compare_exchange generic functions (p: 207)
  • C11標準 (ISO/IEC 9899:2011)
  • 7.17.7.4 The atomic_compare_exchange generic functions (p: 283-284)

[編集] 関連項目

アトミックオブジェクトの値と値を交換する
(関数) [編集]
C++ ドキュメントatomic_compare_exchange_weak, atomic_compare_exchange_strong, atomic_compare_exchange_weak_explicit, atomic_compare_exchange_strong_explicit
English 日本語 中文(简体) 中文(繁體)