Ada 202x (17日目) - Nonblocking/Yield¶
後半戦、メインディッシュは検証関係になります。
経緯¶
parallel
により簡単に並列化できるようになったため、並列化まわりの検証が重要になっています。
今までもpragma Detect_Blocking
は用意されていましたが「デッドロック(potentially blocking)しそうならコンパイルエラーか実行時 Program_Error
にしろ」程度しか書かれておらず正直このpragmaが何をやるべきか何をやっているのかさっぱりわかりません。
GNATでも実装はされていて何かしら追加のチェックをしているっぽいです。
何をやっているのかはドキュメント化されていません。
Janus/Adaには実装されていないようです。
Ada 202xでの改善¶
Nonblockingアスペクト/Yieldアスペクト¶
サブプログラムの中で何も待たないことを表明できる Nonblocking
と、スレッドの実装がノンプリエンティブな環境でも最低1回は確実に他スレッドに実行を譲ることを表明できる Yield
という2つのアスペクトが追加されました。
この2つは排他です。 両方同時に指定することはできません。 どちらも指定されていない場合はブロッキングするかどうかはわからないという意味ですね。
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;
genericの引数との論理積は常に取られるようになりましたので、このようにわざわざ書く必要はなくなりました。
これがありなら 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先生が)アスペクト記法押しですので無理でしょうね……。