Ada 202x (17日目) - Nonblocking/Yield ===================================== .. post:: Dec 17, 2019 :tags: ada, ada_2022 後半戦、メインディッシュは検証関係になります。 経緯 ---- ``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`` の引数にも対応しています。 .. code-block:: ada 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; .. container:: inserted 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先生が)アスペクト記法押しですので無理でしょうね……。 .. _`AI12-0064-2`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0064-2.txt .. _`AI12-0241-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0241-1.txt .. _`AI12-0247-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0247-1.txt .. _`AI12-0279-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0279-1.txt .. _`AI12-0299-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0299-1.txt .. _`AI12-0319-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0319-1.txt