GCC アトミック ビルトインを使用して単純な fetchAndSet を実装するための単純で効率的な方法を探しています。ここで最も近いのは__sync_lock_test_and_set
ビルトインですが、他の関数のように完全なメモリバリアを発行するわけではなく、他のすべての関数は操作 (add、sub、xor など) を実行するか、条件付き (比較およびスワップ機能)。任意のポインター データを保持する変数を操作しようとしているため、これらは機能しません。
私が思いついた最高のものは次のようなものでした:
type *fetchAndSet(type **loc, type *newvar) {
while (1) {
type *oldvar = __sync_fetch_and_add(loc, 0);
if (__sync_bool_compare_and_swap(loc, oldvar, newvar)) return oldvar;
}
}
... 言い換えれば、メモリの場所で値をアトミックにフェッチし、その古い値を新しい値に正常に置き換えるとすぐにループから抜け出します。この解決策にはあまり満足していません。なぜなら、これは単一のアトミック操作ではないからです。また、2 つ以上のスレッドが同じメモリ位置を争っている場合、飢餓の危険性が非常に高くなります。だから、私の質問:これを行うためのより良い方法はありますか?