yohhoyの日記

技術的メモをしていきたい日記

C++11 atomic_flagプリミティブ

C++11標準ライブラリでは最もプリミティブなatomic変数としてstd::atomic_flagを提供する。これは “std::atomic<bool>から極限まで機能を削ったatomic変数” とも解釈できる。

2021-03-09追記:C++20標準ライブラリでは利便性のためtest操作やwaitnotify_*操作が追加された。atomic_flag型のロックフリー保証は維持される。詳細は提案文書 P0995R1 を参照のこと。
atomic_flag型はセット(set)/クリア(clear)の2状態を持ち、初期化用定数マクロと限定された2種類の状態操作しか提供しない。

  • ATOMIC_FLAG_INITマクロによるクリア状態での変数初期化
  • test_and_set操作: セット状態に変更し、変更前の状態を戻り値(bool)として返す
  • clear操作: クリア状態に変更する

このatomic_flag型に対する操作は、C++標準規格により必ずロックフリー(lock-free)であることが保証される。逆に言うと、C++標準規格ではstd::atomic<bool>型に対する操作がロックフリーであることは保証されない*1

N3337 29.7/p1-2より引用(プロトタイプ宣言は簡略化)。

namespace std {
  typedef struct atomic_flag {
    bool test_and_set() noexcept;
    void clear() noexcept;
    atomic_flag() noexcept = default;
    atomic_flag(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) = delete;
  } atomic_flag;

  bool atomic_flag_test_and_set(atomic_flag*) noexcept;
  void atomic_flag_clear(atomic_flag*) noexcept;

  #define ATOMIC_FLAG_INIT  /*implementation-defined*/
}

1 The atomic_flag type provides the classic test-and-set functionality. It has two states, set and clear.
2 Operations on an object of type atomic_flag shall be lock-free. [Note: Hence the operations should also be address-free. No other type requires lock-free operations, so the atomic_flag type is the minimum hardware-implemented type needed to conform to this International standard. The remaining types can be emulated with atomic_flag, though with less than ideal properties. -- end note]

関連URL

*1:atomic<bool> 型に対する操作がロックフリーであるか否かは、処理系が提供する ATOMIC_BOOL_LOCK_FREE マクロ値(コンパイル時)、および atomic<bool>::is_lock_free 関数の戻り値(実行時)にて判定可能。