(toppers-users 1527) Fi4の(i)set_flag、同期・通信関連del_系サービスコールでのdispatchについて

Kominami Yasuo NBC00224 @ nifty.com
2004年 7月 11日 (日) 23:25:57 JST


小南です。

本日Fi4のソースを読んでいたところ、気になる点を見つけましたので質問さ
せて下さい。

一言で言うと、「複数のタスクが同時に待ち解除されたとき、dispatch
をどのタイミングで行なうべきか」です。

これは(i)set_flagおよび同期・通信関連のdel_系サービスコール
すなわち、del_sem、del_flg、del_dtq、del_mbx、
del_mtx、del_mbf、del_porに関わることです。

μITRON4.0仕様(Ver.4.02.00)で関連するところは、
「3.8 オブジェクトの登録とその解除」と上記各サービスコールの規定です。

仕様上は「待ち行列につながれていた順序で待ち解除する」、「実行可能状態に移
項したタスクで同じ優先度を持つものの間では、待ち行列の中で前につながれてい
たタスクの方が高い優先順位を持つことになる」です。
「待ち解除」については「3.2 タスク状態とスケジューリング規則」に「タス
クの待ち解除とは、タスクが待ち状態のときは実行可能状態に、二重待ち状態の時
は強制待ち状態に移項させることをいう」とあります。

この仕様に対し、Fi4では待ち行列からタスクを1個取り出し待ち解除を行なう
たびに、dispatchを呼んでいます。
待ち行列上のタスクの優先度がすべて同じか後になるほど優先度が下がる場合、あ
るいは該当サービスコールを呼び出したタスクの優先度の方が、待ち状態のタスク
よりも高い場合にはこの方法でいいと思います。
しかし、サービスコールを呼び出したタスクの優先度の方が低く、かつ、待ち行列
の後ろにあるタスクの優先度が高ければ、この方法でディスパッチを行なうと(意
図せざる、回避不可能な)優先度逆転が発生すると思います。

同時に待ち状態が解除されるのですから、本来なら同時に実行可能状態になるべき
です。
しかし現実には遂次にしか処理できないため、上記の仕様となったと思います。
そのためここで問題になるのは「待ち解除はディスパッチまで含むのか、含まない
のか」ということになります。

私としては個々のタスクの待ち解除にはディスパッチを含めず、すべてのタスクが
待ち解除された後にディスパッチされるべきだと思います。理由は上記の優先度逆
転の発生を防ぐためです。

しかしμITRON4.0仕様では、複数のタスクの同時に発生した状態変化に伴う
ディスパッチのタイミングについて特に書かれていません。
逆に「高い優先度のタスクは、実行可能状態に移行すると同時にディスパッチが起
こり実行状態になる」という意味の記述があるため、Fi4の実装の方が仕様に則っ
ているとも言えます。

けれどもこの記述は、ある瞬間には一つのタスクの状態しか変化しないと言う前堤
に立っているからだと思います。
複数のタスクが待ち解除される場合は、これらとは区別し、「3.5.6 ディス
パッチ保留状態の間のタスク状態」のようにディスパッチ保留されるべきではない
でしょうか。

----------- 
小南 靖雄
ykominami @ nifty.com
(NBC00224 @ nifty.com)