Ada 2020 (32日目) - Atomic

終わらない……。

Atomicへの部分アクセス

Ada 2020では Atomic (または Volatile)ではない型が Atomic (または Volatile)の型の要素になっていた場合、アクセスはアトミックに行われることが確定しました。 従来は曖昧だった部分です。

declare
   type Unsigned_4 is mod 2 ** 4; -- not atomic type
   type T is -- atomic type
      record
         A, B, C, D : Unsigned_4;
      end record
        with Atomic, Pack;
  X : T;
  Y : Unsigned_4;
begin
   Y := X.A; -- atomic

genericの引数

Ada 2020では generic の引数の型に AtomicAtomic_ComponentsVolatileVolatile_ComponentsIndependentIndependent_Components といった同期関係のアスペクトが指定できるようになりました。

仮引数にこれらが指定されていた場合には実引数にも同じものが指定されている型を渡さなければなりません。

generic
   type T is (<>)
     with Atomic;
package Pkg1 is
   -- 以降省略

Atomic操作を行うライブラリ

確かに型に Atomic アスペクトを付けるだけで読み書き自体はアトミックにはなるのですが、実際のロックフリーなアルゴリズムでは読み書き分岐等をセットにした操作が必要になります。

従来はコンパイラの Intrinsic 関数が用いられていました。 gccであれば __sync_*__atomic_* のビルトイン関数群が利用できます。

当然これらは処理系ごとにバラバラです。

Ada 2020ではそのためのライブラリが追加されました。

System.Atomic_Operations

ライブラリの親となる空のパッケージです。

System.Atomic_Operations.Arithmetic

加減算を行い演算前の値を返す関数や演算後の値を返す関数群です。

gccの __atomic_fetch_add__atomic_add_fetch 等に相当します。

generic パッケージになっていて引数に操作対象のAtomic型を取ります。

System.Atomic_Operations.Exchange

所謂swapやcompare-and-swapです。

gccの __atomic_exchange__atomic_compare_exchange 等に相当します。

generic パッケージになっていて引数に操作対象のAtomic型を取ります。

System.Atomic_Operations.Test_And_Set

アトミックな(少なくとも)1ビットのフラグ型です。

gccの __atomic_test_and_set__atomic_clear に相当します。

Exchange があれば簡単に実現可能ではありますがその場合ユーザーが適切な型をCPUに合わせて宣言しないといけないため、専用の型も含めて用意されています。

関連AI

  • AI12-0128-1: Exact size access to parts of composite atomic objects

  • AI12-0234-1: Compare-and-swap for atomic objects

  • AI12-0282-1: Atomic, Volatile, and Independent generic formal types

  • AI12-0321-1: Support for Arithmetic Atomic Operations and Test and Set