Ada 2020 (17日目) - Nonblocking/Yield

後半戦、メインディッシュは検証関係になります。

経緯

parallel により簡単に並列化できるようになったため、並列化まわりの検証が重要になっています。

今までもpragma Detect_Blocking は用意されていましたが「デッドロック(potentially blocking)しそうならコンパイルエラーか実行時 Program_Error にしろ」程度しか書かれておらず正直このpragmaが何をやるべきか何をやっているのかさっぱりわかりません。 GNATでも実装はされていて何かしら追加のチェックをしているっぽいです。 何をやっているのかはドキュメント化されていません。 Janus/Adaには実装されていないようです。

Ada 2020での改善

Nonblockingアスペクト/Yieldアスペクト

サブプログラムの中で何も待たないことを表明できる Nonblocking と、スレッドの実装がノンプリエンティブな環境でも最低1回は確実に他スレッドに実行を譲ることを表明できる Yield というふたつのアスペクトが追加されました。

このふたつは排他です。 両方同時に指定することはできません。 どちらも指定されていない場合はブロッキングするかどうかはわからないという意味ですね。

Nonblocking なサブプログラムからは同じく Nonblocking なサブプログラムしか呼べません。 Pure と似た性質です。 Nonblocking を付けてコンパイルが通っている限りはスレッド関係はノータッチであり少なくともそこでデッドロックはしないと確信できます。 (ビジーループは別。)

Yield なサブプログラムでは少なくとも1回はdelay文等を使うか Ada.Dispatching.Yield 等の同じく Yield の付いたサブプログラムを呼ぶ必要があります。 if文等で迂回するのは駄目です。

これらの情報はpragma Detect_Blocking の助けになるかもしれませんしならないかもしれません。

Nonblocking はサブプログラムの他、型やパッケージにも付けられます。 型に付けた場合はRAII経由でブロッキングしないという意味です。 パッケージに付けた場合はその中の全ての型やサブプログラムに適用されます。 Yield はサブプログラムにのみ付けられます。

ところで高階関数ではこれらの性質をその場では決定できません。

アスペクトの記法で例えば with Inline と書いた場合、これは with Inline => True の省略です。 True の部分にはstaticな Boolean の式を書けます。 Nonblocking はこれを上手く活用してgenericの引数にも対応しています。

generic
   with function F (X : Integer) return Integer;
function G return Integer
  with Nonblocking => F'Nonblocking;

function G return Integer is
begin
   return F (0);
end G;

これがありなら Inline 等でもこのように指定したいですさせてください。 (願望です。 インライン関数かどうかの情報を F'Inline の形で読み取ることができません。)

通常の引数として渡されたクロージャにも対応することは検討されましたが却下されています。 Nonblocking が定数値ではなくなり呼び出しごとに評価しないといけなくなるからです。 どの道ソースコード上に引数として Nonblocking ではないサブプログラム名が現れた時点で弾くことはできますし。

関連AI

  • AI12-0064-2 Nonblocking subprograms

  • AI12-0241-1 Specifying Nonblocking for Language-Defined Units

  • AI12-0247-1 Potentially Blocking goes too far for Detect_Blocking

  • AI12-0279-1 Nonpreemptive dispatching needs more dispatching points

  • AI12-0299-1 The permission of D.2.1(10.1/2) allows too much

  • AI12-0319-1 Nonblocking for Unchecked_Deallocation is wrong

所感

このせいで標準ライブラリの定義のほとんどに with Nonblocking が付きまくってノイズです。 宣言と切り離せる旧来の属性の記法を使ってほしいのですが、委員会が(特にRandy先生が)アスペクト記法押しですので無理でしょうね……。