アトミックな比較とスワップを使用したいのですが、等しいのではなく、メモリ位置が古い値と等しくない場合にのみスワップしたいと考えています。Cで可能ですか?
2 に答える
これはどう:
void compare_and_swap_if_not_equal(word_t const required_non_value, word_t const new_value, word_t* ptr_to_shared_variable) {
for (;;) {
word_t const snapshot_value = *ptr_to_shared_variable;
if (required_non_value == snapshot_value) {
break;
// or (sleep and) 'continue;', if you want to wait for the stored value to be different
// -- but you might of course miss a transient change to a different state and back.
} else {
if (compare_and_swap_if_equal(ptr_to_shared_variable, snapshot_value, new_value)) {
// we know the stored value was different; if this 'theory' still matches reality: swap! done!
break;
}
}
}
}
未テスト。未コンパイル。私はそれが好きなので、「const」を使用しました:)。「word_t」は型のプレースホルダーです。実際の型がどうあるべきかわかりません。また、stdatomic.h で「compare_and_swap_if_equal」がどのように呼び出されるのかわかりません。
(追加) atomic_compare_exchange_weak() がチケットです。何らかの理由で、'expected' 引数へのポインタを取るため、上記のコードを次のように変更する必要があります。
if (atomic_compare_exchange_weak(ptr_to_shared_variable, &snapshot_value, new_value)) ...
「弱い」バージョンは上記のコードで機能するはずです。間違って「false」を返すと、ループに別のトリップが追加されるだけです。まだコンパイルもテストもされていません。自宅でこのコードに頼らないでください。
アーキテクチャによって異なりますが、一般に C ではこれを行うことはできません。
通常、比較とスワップは、メモリ内の場所からアトミックにロードし、メモリ内の場所が指定した既存の値と一致する場合にその場所に値を格納する命令で実装されます。
少なくとも x86 では、値が一致しない場合にのみこのロードを実行するための規定はありません。また、なぜそのようなことをしたいのかは明らかではありません。おそらく、別のアーキテクチャがこのようなものをサポートするでしょうが、それはアーキテクチャに依存し、移植可能な方法で C で実行できるものではありません。