今回は,タスクの状態やシステムの状態を制御する機能について,例題を示しながら説明します。例題は,いずれも基礎的な知識で解答できますので,第一区分となります。

例題1 テーマ:タスクの待ち状態と解除の方法

【問題】
T-Kernelのタスク付属同期機能に関する説明として間違っているものを以下の中からすべて選べ。

【選択肢】

  1. 他タスクの待ち状態を解除するtk_rel_waiシステムコールは,対象タスクが待ち状態でない場合には,待ち状態解除要求がキューイングされる。
  2. 他タスクの起床要求を行うtk_wup_tskシステムコールは,対象タスクがtk_slp_tskによる待ち状態でない場合には,起床要求がキューイングされる。
  3. 自タスクを起床待ち状態へ移行するtk_slp_tskシステムコールは,指定したタイムアウト時間が経過する間にtk_wup_tskが発行されなかった場合は,タイムアウトエラーとなる。
  4. タスク遅延を行うtk_dly_tskシステムコールは,遅延時間中にtk_wup_tskが実行されても,待ち解除は行われない。

正解(マウスでドラッグして文字を反転させてください)= 1

【解説】
 選択肢2と選択肢3は,正しい動作です。

 tk_wup_tskによる起床要求はキューイングされます。

 一般的には,何らかのイベントが発生するのを待ってから続きの処理を実行する場合に,tk_slp_tskを実行してイベントの発生を待ちます。イベントが発生したら,tk_wup_tskを実行して,tk_slp_tskで待っているタスクにイベントを通知します(図1)。もし,tk_slp_tskを実行した時点ですでにイベントが発生していた場合は処理を継続して実行しても構わないことになりますので,イベントを記録(キューイング)できるようになっています(図2)。

図1●tk_wup_tskによる起床要求
図1●tk_wup_tskによる起床要求
 
図2●起床要求のキューイング
図2●起床要求のキューイング

 tk_slp_tskには待ち時間を指定することができます。指定したタイムアウト時間が経過する間にtk_wup_tskが発行されれば,すなわち,イベントが発生すれば処理を継続します(図1,図2)。もし,tk_wup_tskが発行されないままタイムアウト時間が経過した場合は,イベントが発生しなかった場合の処理を実行することになります(図3)。

図3●タイムアウト
図3●タイムアウト

 この2つの動作はtk_slp_tskの戻り値によって区別できます。すなわち,tk_wup_tskによって待ち状態が解除された(条件成立)場合は正常終了(E_OK),タイムアウトによって待ち状態が解除された(条件不成立)場合はエラー終了(E_TMOUT)となります。


 選択肢1は間違いですので,正解は1となります。

 tk_rel_waiによる待ち解除要求はキューイングされません。

 tk_rel_waiは,一般的に,待ち状態を正常に解除することができなくなった場合などに使用します。待ち状態を強制的に解除されたタスクには戻り値としてE_RLWAIが返され,強制的に待ち状態を解除されたことを検出できるようになっています(図4)。逆に,対象タスクが待ち状態でない場合は待ち状態を解除する必要がありませんので,tk_rel_waiの戻り値としてはE_OBJが返され,待ち状態の強制解除が不要であることを検出できる仕組みになっています(図5)。

図4●待ち解除要求
図4●待ち解除要求
 
図5●待ち解除要求無効
図5●待ち解除要求無効

 なお,tk_wup_tskではtk_slp_tskによる待ち状態のみを解除しますが,tk_rel_waiではそれ以外の要因(tk_wai_flg,tk_wai_sem,tk_rcv_msg,tk_get_blk等)による待ち状態も解除することができます。これは,tk_wup_tskとtk_rel_waiの使用目的が異なっているためです。


 選択肢4は,正しい動作です。

 tk_dly_tskは,自タスクを一定時間待ち状態に移行させるために実行します。tk_slp_tskと違い,イベントの通知を待つ場合などには使用しません。tk_wup_tskとも無関係です。

 指定した遅延時間だけ自タスクを待ち状態にすることが目的ですので,指定した遅延時間だけ待つことができた場合に,待ち解除の条件が成立したとして正常終了(E_OK)します。もし,遅延時間が経過する前に待ちが解除された場合はエラー終了となります。


 一言で待ち状態と言っても,その目的は様々です。

 「結局は同じような動作になるのだから,どのシステムコールを利用しても同じだろう」という考え方は間違いです。

 tk_dly_tskを使うべきところでtk_slp_tskを使っているとか,イベントをtk_rel_waiで通知しているといったプログラムは混乱の元です。その位置での待ちは何を意味するのか。どのように待って,どのように解除するのが正しいのか。待ち解除の条件が成立するのはどのような場合で,どのような場合には成立しないのか。常にこういったことを考えながらプログラムを開発する必要があります。