(toppers-users 2450) Re: TOPPERS/FI4 のバグ

takaya_kakizaki @ gmx.yamaha.com takaya_kakizaki @ gmx.yamaha.com
2006年 6月 13日 (火) 17:25:01 JST


柿崎です。

>これは、include/t_services.hで定義されたsyscallマクロによる
>出力だと思います。
>その場合、同じt_services.hで定義された_t_perror関数を呼び出します。
>この関数の中で、エラーコードが0より小さい場合、すなわちE_OK以外の
>場合は、上記のメッセージを出力します。
>このマクロは簡易的なもので、エラーコードがE_OKか、E_OK以外かしか
>判断しません。
>tcal_porの場合、指定時間内にランデブが成立しなければE_OKではなく、
>E_TMOUTが返ってきます。

>具体的な返値が知りたいです。

一応、t_perrorはITRONのエラーコードは判別するはずです。
unknownとあるのでITRONのエラーコード以外のコードが出力されたことを
意味します。

具体的にエラーコードを調べてみましたら、
-1945091748,-1945083556
等、毎回呼び出すたびに異なる値を返します。
問題のコードの直後に
                if (winfo.winfo.wercd == E_OK) {
                        ercd = winfo.msgsz;
                } else {
                        ercd = winfo.winfo.wercd;
                }

こんな処理をおこなっているので、おそらくディスパッチを行わずに
制御が帰っているため(wobj_make_waitの待ち状態が解除されていない)
winfo.winfo.wercdの初期化がなされていない
のだと思います。

 
>> >このため、ディスパッチ保留状態であれば、ディスパッチは発生しません。
>> >ディスパッチが起こる状態で、かつディスパッチが必要である場合に、
>> >wait_completeはTRUEを返します。
>> 
>> >#TOPPERSのITRON仕様OSの実装では、タスクの状態変更を行う関数の返値は、
>> >#その時点でディスパッチが必要か必要でないかを示しています。
>> 
>> ディスパッチを発生させる要因はwait_completeではなく、
>> その前のwobj_make_waitにあるのですが、それでも成り立ちますか。
>
>はい。
>
>ITRON仕様と実装に話を分けます。
>
>ITRON仕様上は、ディスパッチを発生させる要因が存在すれば、ディスパッチ
>をさせないといけません。
>ただし、ディスパッチはディスパッチを行える状態の場合でないと行えません。
>したがって、タイミングは要因の発生と同時ではなく、ずれることがあります。
>
>
>ディスパッチ保留状態でない場合の処理に話をしぼると、実装の話になります。
>
>実装上は、ディスパッチを発生させる要因が生じたら、その直後にディスパッチ
>をするか、直後でなく他の処理も行ってから、ディスパッチをすべきかを判断し
>て、ディスパッチをするかですが、ソースコード上の見通しの良さと処理速度の
>トレードオフ範囲内の話だととらえています。
>サービスコールの不可分性も守られているわけですし。
>
>今回のような待ち解除もいろいろなサービスコールから呼び出される可能性が
>あるため、待ち解除の直後にディスパッチを行うとしたら、どういう状態で待ち
>解除を行ったかの条件判別が必要になる(それこそサービスコール毎に異なる処
理
>が必要になるかもしれません)と思います。

確かにそのとおりだと思います。

μITRON4.0のランデブの章では、ランデブの成立時にどのタイミングで
ディスパッチを行うかは言及していません。ただし、
「タスクAがcal_porを呼び出し、タスクBがacp_porを呼び出した時点でランデブが
成立し、タスクAを待ち状態としたまま、タスクBが待ち解除される。このとき
タスクAは、ランデブの終了待ち状態になっている。」
とあるので、タスクBの待ちが解除され、カーネル実行状態から離れたとき
タスクA : ランデブ終了待ち
タスクB : 実行可能状態(あるいは強制待ち状態)

という状態である必要があります。

具体的には

                wobj_make_wait((WOBJCB *)rdvcb, (WINFO_WOBJ *)&winfo);
                wait_complete(tcb);
                dispatch();

は許されるけれども、

                if(wait_complete(tcb)){
                        dispatch();
                }
                wobj_make_wait((WOBJCB *)rdvcb, (WINFO_WOBJ *)&winfo);
                dispatch();


等は許されないことになります。
(タスクAが実行可能状態になってしまうため)

                wobj_make_wait((WOBJCB *)rdvcb, (WINFO_WOBJ *)&winfo);
                dispatch();
                if(wait_complete(tcb)){
                        dispatch();
                }


これはどうなのでしょう?
ITRONの解釈が間違ってたらご指摘ください。
(今回のバグとは話がずれました)


ただしいかなる場合でも、サービスコールを呼び出したタスクが待ち状態に
遷移するときにディスパッチが行われないパスができてしまうと
今回のようにTOPPERSは破綻してしまいます。