linuxのメモ

Linux kernelの実装を解説していきます (対象ver 4.5)

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が定義されるが、__retoldインラインアセンブラ内では%aexレジスタにひも付き同じ値となる

そしてcmpxchgアセンブラ命令により以下の処理を実行し、__retの値を返す

  • ptr == old
    • ptrnewを代入
  • ptr != old
    • __retptrを代入

従って、比較値が元の値と同じ場合はoldを返し、異なる場合はoldと異なる比較値自身を返す