コンテンツにスキップ

C言語/標準ライブラリ/stdatomic.h

出典: フリー教科書『ウィキブックス(Wikibooks)』
このページ「C言語/標準ライブラリ/stdatomic.h」は、まだ書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にトークページへどうぞ。


ヘッダー <stdatomic.h> では、いくつかのマクロが定義されており、スレッド間で共有されるデータに対してアトミック操作(atomic operation; 不可分操作)を行うためのいくつかの型や関数が宣言されています[1]

マクロ __STDC_NO_ATOMICS__ を定義している実装は、このヘッダーを提供する必要はなく、また、その機能をサポートする必要もありません[1]

マクロ

[編集]

アトミック・ロックフリー・マクロ( atomic lock-free macros )[1]

ATOMIC_BOOL_LOCK_FREE
ATOMIC_CHAR_LOCK_FREE
ATOMIC_CHAR16_T_LOCK_FREE
ATOMIC_CHAR32_T_LOCK_FREE
ATOMIC_WCHAR_T_LOCK_FREE
ATOMIC_SHORT_LOCK_FREE
ATOMIC_INT_LOCK_FREE
ATOMIC_LONG_LOCK_FREE
ATOMIC_LLONG_LOCK_FREE
ATOMIC_POINTER_LOCK_FREE

これらは,#if 前処理ディレクティブでの使用に適した定数式に展開され,対応する原子型(符号付きおよび符号なしの両方)のロックフリー特性を示します。

ATOMIC_FLAG_INIT

これはatomic_flag型のオブジェクトのイニシャライザに展開されます。

[編集]
memory_order

は、列挙型であり、その列挙者はメモリ順序制約を識別します。

atomic_flag

ロックフリーのプリミティブ・アトミック・フラグを表す構造体タイプである「アトミック・フラグ」や、整数型のアトミック・アナログがいくつかあります。

関数と関数型マクロ

[編集]

以下のシノプスでは

  • Aは、原子型を指します。
  • Cは、対応する非原子型を指します。
  • M は、算術演算のもう一方の引数の型を表します。

アトミックな整数型の場合、M は C です。アトミックなポインタ型の場合、M は ptrdiff_t です。

  • _explicit で終わらない関数は、対応する _explicit 関数と同じセマンティクスを持ち、memory_order 引数に memory_order_seq_cst を指定します。

<stdatomic.h> で宣言されたジェネリック関数が、マクロであるか、外部リンクで宣言された識別子であるかは不定( unspecified )です。

実際の関数にアクセスするためにマクロ定義を抑制した場合や 実際の関数にアクセスするためにマクロ定義が抑制されたり、プログラムがジェネリック関数の名前で外部識別子を定義した場合、その動作は未定義( undefined )です。

初期化

[編集]

The ATOMIC_VAR_INIT マクロ

[編集]
形式
#include <stdatomic.h>
#define ATOMIC_VAR_INIT(C value)
説明
ATOMIC_VAR_INIT マクロは、value と初期化互換性のある型の原子オブジェクトを初期化するのに適したトークンシーケンスに展開されます。
明示的に初期化されていない自動記憶期間を持つ原子オブジェクトは、最初は不確定な状態です。
しかし、静的またはスレッドローカルな記憶期間を持つオブジェクトのデフォルト(ゼロ)初期化は、有効な状態を生成することが保証されています。
atomic_int guide = ATOMIC_VAR_INIT(42);

atomic_init 総称関数

[編集]
形式
#include <stdatomic.h>
void atomic_init(volatile A *obj, C value);
説明
atomic_init総称関数は、objが指すアトミック・オブジェクトをvalueという値に初期化するとともに、実装がアトミック・オブジェクトに対して保持する必要のある追加の状態を初期化します。
この関数はアトミック・オブジェクトを初期化しますが、データレースを回避することはできません。初期化される変数への同時アクセスは、たとえアトミックな操作であってもデータレースとなります。
abort関数やraise関数の呼び出し以外でシグナルが発生した場合、シグナルハンドラがatomic_initジェネリック関数を呼び出した場合の動作は未定義です。
戻り値
atomic_init総称関数は、値を返しません。

順序と一貫性

[編集]

フェンス

[編集]

フェンスと呼ばれる同期プリミティブの1つです。

ロックフリー・プロパティ

[編集]

アトミック整数型

[編集]

アトミック型における操作

[編集]

アトミックフラッグ型とその操作

[編集]

Library summary
#define ATOMIC_VAR_INIT(C value)
void atomic_init(volatile A *obj, C value);
type kill_dependency(type y);
void atomic_thread_fence(memory_order order);
void atomic_signal_fence(memory_order order);
_Bool atomic_is_lock_free(const volatile A *obj);
void atomic_store(volatile A *object, C desired);
void atomic_store_explicit(volatile A *object, C desired, memory_order order);
C atomic_load(const volatile A *object);
C atomic_load_explicit(const volatile A *object, memory_order order);
C atomic_exchange(volatile A *object, C desired);
C atomic_exchange_explicit(volatile A *object, C desired, memory_order order);
_Bool atomic_compare_exchange_strong(volatile A *object, C *expected, C desired);
_Bool atomic_compare_exchange_strong_explicit(volatile A *object, C *expected,
C desired, memory_order success, memory_order failure);
_Bool atomic_compare_exchange_weak(volatile A *object, C *expected, C desired);
_Bool atomic_compare_exchange_weak_explicit(volatile A *object, C *expected, C desired, memory_order success, memory_order failure);
C atomic_fetch_key(volatile A *object, M operand);
C atomic_fetch_key_explicit(volatile A *object, M operand, memory_order order);
_Bool atomic_flag_test_and_set(volatile atomic_flag *object);
_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order);
void atomic_flag_clear(volatile atomic_flag *object);
void atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order);

参考文献

[編集]
  1. ^ 1.0 1.1 1.2 N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E). ISO/IEC JTC1/SC22/WG14. p. 249, §7.17 Atomics <stdatomic.h>. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf.