atomic操作 - __raw_cmpxchg()
概要
比較値が古い値と等しい場合に新しい値に書き換える
詳細
以下の値を引数として持つ
- 比較元の値のポインタ : ptr
- 元の値 : old
- 新しい値 : new
- 比較元の値の大きさを示す値 : size
- atomicに操作を行うか決める : lock
拡張インラインアセンブラにより以下のコードが展開される
lock cmpxchg new, ptr;
lockにLOCKプリフィクスを示す文字列が指定されていた場合はatomicに実行されることになる
また、sizeの値によりcmpxchgに以下のsuffixが付加される
- 1byte : b
- 2byte : w
- 4byte : l
- 8byte : q
sizeの値が8byteを超えた場合は不正なサイズとして__cmpxchg_wrong_size()が実行され、値の書き換えは行われない
このマクロ内で返り値のポインタ__retが定義されるが、__retとoldはインラインアセンブラ内では%aexレジスタにひも付き同じ値となる
そしてcmpxchgアセンブラ命令により以下の処理を実行し、__retの値を返す
- ptr == old
- ptrにnewを代入
- ptr != old
- __retにptrを代入
従って、比較値が元の値と同じ場合はoldを返し、異なる場合はoldと異なる比較値自身を返す