第 4 章 µITRON4.0 仕様の機能 79
4.5 拡張同期・通信機能
4.5.1 ミューテックス
ミューテックスは,共有資源を使用する際にタスク間で排他制御を行うための オブジェクトである.ミューテックスは,排他制御に伴う上限のない優先度逆 転を防ぐための機構として,優先度継承プロトコル(priority inheritance protocol)
と優先度上限プロトコル(priority ceiling protocol)をサポートする.ミューテッ クス機能には,ミューテックスを生成/削除する機能,ミューテックスをロッ ク/ロック解除する機能,ミューテックスの状態を参照する機能が含まれる.
ミューテックスはID番号で識別されるオブジェクトである.ミューテックス のID番号をミューテックスIDと呼ぶ.
ミューテックスは,ロックされているかどうかの状態と,ロックを待つタスク の待ち行列を持つ.また,カーネルは,各ミューテックスに対してそれをロッ クしているタスクを,各タスクに対してそれがロックしているミューテックス の集合を管理する.タスクは,資源を使用する前に,ミューテックスをロック する.ミューテックスが他のタスクにロックされていた場合には,ミューテッ クスがロック解除されるまで,ミューテックスのロック待ち状態となる.
ミューテックスのロック待ち状態になったタスクは,そのミューテックスの待 ち行列につながれる.タスクは,資源の使用を終えると,ミューテックスの ロックを解除する.
ミューテックスは,ミューテックス属性にTA_INHERIT(=0x02)を指定する ことにより優先度継承プロトコルを,TA_CEILING(=0x03)を指定すること により優先度上限プロトコルをサポートする.TA_CEILING属性のミューテッ クスに対しては,そのミューテックスをロックする可能性のあるタスクの中で 最も高いベース優先度を持つタスクのベース優先度を,ミューテックス生成時 に上限優先度として設定する.TA_CEILING属性のミューテックスを,その上 限優先度よりも高いベース優先度を持つタスクがロックしようとした場合,
E_ILUSEエラーとなる.また,TA_CEILING属性のミューテックスをロックし
ているかロックを待っているタスクのベース優先度を,chg_priによってその ミューテックスの上限優先度よりも高く設定しようとした場合,chg_priが
E_ILUSEエラーを返す.
これらのプロトコルを用いた場合,上限のない優先度逆転を防ぐために,
ミューテックスの操作に伴ってタスクの現在優先度を変更する.優先度継承プ ロトコルと優先度上限プロトコルに厳密に従うなら,タスクの現在優先度を,
次に挙げる優先度の最高値に常に一致するように変更する必要がある.これ を,厳密な優先度制御規則と呼ぶ.
• タスクのベース優先度
• タスクがTA_INHERIT属性のミューテックスをロックしている場合,
それらのミューテックスのロックを待っているタスクの中で,最も高 い現在優先度を持つタスクの現在優先度
• タスクがTA_CEILING属性のミューテックスをロックしている場合,
それらのミューテックス中で,最も高い上限優先度を持つミューテッ クスの上限優先度
ここで,TA_INHERIT属性のミューテックスを待っているタスクの現在優先度
が,ミューテックス操作かchg_priによるベース優先度の変更に伴って変更さ れた場合,そのミューテックスをロックしているタスクの現在優先度の変更が 必要になる場合がある.これを推移的な優先度継承と呼ぶ.さらにそのタスク
が,別のTA_INHERIT属性のミューテックスを待っていた場合には,その
ミューテックスをロックしているタスクに対して推移的な優先度継承の処理 が必要になる場合がある.
µITRON4.0仕様では,上述の厳密な優先度制御規則に加えて,現在優先度を変 更する状況を限定した優先度制御規則(これを簡略化した優先度制御規則と呼 ぶ)を規定し,どちらを採用するかは実装定義とする.具体的には,簡略化し た優先度制御規則においては,タスクの現在優先度を高くする方向の変更はす べて行うのに対して,現在優先度を低くする方向の変更は,タスクがロックし ているミューテックスがない時(または,なくなった時)にのみ行う(この場 合には,タスクの現在優先度をベース優先度に一致させる).より具体的には,
次の状況でのみ現在優先度を変更する処理を行えばよい.
• タスクがロックしているTA_INHERIT属性のミューテックスを,その タスクよりも高い現在優先度を持つタスクが待ち始めた時
• タスクがロックしている TA_INHERIT 属性のミューテックスを待っ ているタスクが,前者のタスクよりも高い現在優先度に変更された時 • タスクが,そのタスクの現在優先度よりも高い上限優先度を持つ
TA_CEILING属性のミューテックスをロックした時
• タスクがロックしているミューテックスがなくなった時
• chg_priによりタスクのベース優先度を変更した場合で,そのタスクが
ロックしているミューテックスがないか,変更後のベース優先度が現 在優先度よりも高い時
ミューテックスの操作に伴ってタスクの現在優先度を変更した場合には,次の 処理を行う.優先度を変更されたタスクが実行できる状態である場合,タスク
の優先順位を,変更後の優先度にしたがって変化させる.変更後の優先度と同 じ優先度を持つタスクの間での優先順位は,実装依存である.優先度が変更さ れたタスクが何らかのタスク優先度順の待ち行列につながれている場合にも,
その待ち行列の中での順序を,変更後の優先度にしたがって変化させる.変更 後の優先度と同じ優先度を持つタスクの間での順序は,実装依存である.
タスクが終了する時に,そのタスクがロックしているミューテックスが残って いる場合には,それらのミューテックスをすべてロック解除する.ロックして いるミューテックスが複数ある場合には,それらをロック解除する順序は実装 依存である.ロック解除の具体的な処理内容については,unl_mtxの機能説明 を参照すること.
ミューテックス生成情報およびミューテックス状態のパケット形式として,次 のデータ型を定義する.
typedef struct t_cmtx {
ATR mtxatr ; /*ミューテックス属性*/
PRI ceilpri ; /*ミューテックスの上限優先度*/
/*実装独自に他のフィールドを追加してもよい*/
} T_CMTX ;
typedef struct t_rmtx {
ID htskid ; /*ミューテックスをロックしているタ
スクのID番号*/
ID wtskid ; /*ミューテックスの待ち行列の先頭の
タスクのID番号*/
/*実装独自に他のフィールドを追加してもよい*/
} T_RMTX ;
ミューテックス機能の各サービスコールの機能コードは次の通りである.
TFN_CRE_MTX –0x81 cre_mtxの機能コード
TFN_ACRE_MTX –0xc6 acre_mtxの機能コード
TFN_DEL_MTX –0x82 del_mtxの機能コード
TFN_LOC_MTX –0x85 loc_mtxの機能コード
TFN_PLOC_MTX –0x86 ploc_mtxの機能コード
TFN_TLOC_MTX –0x87 tloc_mtxの機能コード
TFN_UNL_MTX –0x83 unl_mtxの機能コード
TFN_REF_MTX –0x88 ref_mtxの機能コード
【補足説明】
TA_TFIFO属性またはTA_TPRI属性のミューテックスは,最大資源数が1のセマ
フォ(バイナリセマフォ)と同等の機能を持つ.ただし,ミューテックスは,
ロックしたタスク以外はロック解除できない,タスク終了時に自動的にロック 解除されるなどの違いがある.
ここでいう優先度上限プロトコルは,広い意味での優先度上限プロトコルで,
最初に優先度上限プロトコルとして提案されたアルゴリズムではない.厳密に は,highest locker protocolなどと呼ばれているアルゴリズムである.
ミューテックスの操作に伴ってタスクの現在優先度を変更した結果,優先度を 変更されたタスクのタスク優先度順の待ち行列の中での順序が変化した場合,
優先度を変更されたタスクないしはその待ち行列で待っている他のタスクの 待ち解除が必要になる場合がある(snd_mbfの機能説明とget_mplの機能説明を 参照).
【µITRON3.0仕様との相違】
ミューテックス機能は,µITRON4.0仕様において新たに導入した機能である.
ミューテックスをセマフォとは別のオブジェクトとして導入したのは,計数型 セマフォで優先度継承プロトコルをサポートするのが難しいためである.
【仕様決定の理由】
ミューテックスの操作に伴ってタスクの現在優先度を変更した場合に,変更後 の優先度と同じ優先度を持つタスクの間での優先順位を実装依存としたのは,
次の理由による.アプリケーションによっては,ミューテックス機能による現 在優先度の変更が頻繁に発生する可能性があり,それに伴ってタスク切替えが 多発するのは望ましくない(同じ優先度を持つタスクの間での優先順位を最低 とすると,不必要なタスク切替えが起こる).理想的には,タスクの優先度で はなく優先順位を継承するのが望ましいが,このような仕様にすると実装上の オーバヘッドが大きくなるため,実装依存とすることにした.