第 4 章 µITRON4.0 仕様の機能 79
4.4 同期・通信機能
4.4.1 セマフォ
セマフォは,使用されていない資源の有無や数量を数値で表現することによ り,その資源を使用する際の排他制御や同期を行うためのオブジェクトであ る.セマフォ機能には,セマフォを生成/削除する機能,セマフォの資源を獲 得/返却する機能,セマフォの状態を参照する機能が含まれる.セマフォはID 番号で識別されるオブジェクトである.セマフォのID番号をセマフォIDと呼 ぶ.
セマフォは,対応する資源の有無や数量を表現する資源数と,資源の獲得を待 つタスクの待ち行列を持つ.資源を返却する側(イベントを知らせる側)で は,セマフォの資源数を1つ増やす.一方,資源を獲得する側(イベントを待 つ側)では,セマフォの資源数を1つ減らす.セマフォの資源数が足りなくなっ た場合(具体的には,資源数を減らすと資源数が負になる場合),資源を獲得 しようとしたタスクは,次に資源が返却されるまでセマフォ資源の獲得待ち状 態となる.セマフォ資源の獲得待ち状態になったタスクは,そのセマフォの待 ち行列につながれる.
また,セマフォに対して資源が返却され過ぎるのを防ぐために,セマフォ毎に 最大資源数を設定することができる.最大資源数を越える資源がセマフォに返 却されようとした場合(具体的には,セマフォの資源数を増やすと最大資源数 を越える場合)には,エラーを報告する.
セマフォ機能に関連して,次のカーネル構成定数を定義する.
TMAX_MAXSEM セマフォの最大資源数の最大値
セマフォ生成情報およびセマフォ状態のパケット形式として,次のデータ型を 定義する.
typedef struct t_csem {
ATR sematr ; /*セマフォ属性*/
UINT isemcnt ; /*セマフォの資源数の初期値*/
UINT maxsem ; /*セマフォの最大資源数*/
/*実装独自に他のフィールドを追加してもよい*/
} T_CSEM ;
typedef struct t_rsem {
ID wtskid ; /*セマフォの待ち行列の先頭のタスク のID番号*/
UINT semcnt ; /*セマフォの現在の資源数*/
/*実装独自に他のフィールドを追加してもよい*/
} T_RSEM ;
セマフォ機能の各サービスコールの機能コードは次の通りである.
TFN_CRE_SEM –0x21 cre_semの機能コード
TFN_ACRE_SEM –0xc2 acre_semの機能コード
TFN_DEL_SEM –0x22 del_semの機能コード
TFN_SIG_SEM –0x23 sig_semの機能コード
TFN_ISIG_SEM –0x75 isig_semの機能コード
TFN_WAI_SEM –0x25 wai_semの機能コード
TFN_POL_SEM –0x26 pol_semの機能コード
TFN_TWAI_SEM –0x27 twai_semの機能コード
TFN_REF_SEM –0x28 ref_semの機能コード
【スタンダードプロファイル】
スタンダードプロファイルでは,セマフォを動的に生成/削除する機能
(cre_sem,acre_sem,del_sem),セマフォの状態を参照する機能(ref_sem)を 除いて,セマフォ機能をサポートしなければならない.
スタンダードプロファイルでは,セマフォの最大資源数として,少なくとも
65535以上の値が指定できなければならない.スタンダードプロファイルでは
TMAX_MAXSEMを定義する必要はないが,定義する場合には65535以上の値
となる.
【仕様決定の理由】
スタンダードプロファイルでTMAX_MAXSEMを定義する必要がないとした
のは,TMAX_MAXSEMを参照する必要があるのはセマフォを生成する時であ
るのに対して,スタンダードプロファイルではセマフォを動的に生成する機能 をサポートする必要がないためである.
CRE_SEM セマフォの生成(静的API) 【S】
cre_sem セマフォの生成
acre_sem セマフォの生成(ID番号自動割付け)
【静的API】
CRE_SEM ( ID semid, { ATR sematr, UINT isemcnt, UINT maxsem } ) ;
【C言語API】
ER ercd = cre_sem ( ID semid, T_CSEM *pk_csem ) ; ER_ID semid = acre_sem ( T_CSEM *pk_csem ) ;
【パラメータ】
ID semid 生成対象のセマフォのID番号(acre_sem以外)
T_CSEM * pk_csem セマフォ生成情報を入れたパケットへのポイ
ンタ(CRE_SEMではパケットの内容を直接記 述する)
pk_csemの内容(T_CSEM型)
ATR sematr セマフォ属性
UINT isemcnt セマフォの資源数の初期値
UINT maxsem セマフォの最大資源数
(実装独自に他の情報を追加してもよい)
【リターンパラメータ】
cre_semの場合
ER ercd 正常終了(E_OK)またはエラーコード acre_semの場合
ER_ID semid 生成したセマフォのID番号(正の値)またはエ
ラーコード
【エラーコード】
E_ID 不正ID番号(semidが不正あるいは使用できない;cre_sem のみ)
E_NOID ID番号不足(割付け可能なセマフォIDがない;acre_sem
のみ)
E_RSATR 予約属性(sematrが不正あるいは使用できない)
E_PAR パラメータエラー(pk_csem,isemcnt,maxsemが不正)
E_OBJ オブジェクト状態エラー(対象セマフォが登録済み;
cre_semのみ)
【機能】
semidで指定されるID番号を持つセマフォを,pk_csemで指定されるセマフォ生
成情報に基づいて生成する.sematrはセマフォの属性,isemcntはセマフォ生成
後の資源数の初期値,maxsemはセマフォの最大資源数である.
CRE_SEMにおいては,semidは自動割付け対応整数値パラメータ,sematrはプ
リプロセッサ定数式パラメータである.
acre_semは,生成するセマフォのID番号をセマフォが登録されていないID番号
の中から割り付け,割り付けたID番号を返値として返す.
sematrには,(TA_TFIFO‖TA_TPRI)の指定ができる.セマフォの待ち行列は,
TA_TFIFO(=0x00)が指定された場合にはFIFO順,TA_TPRI(=0x01)が指
定された場合にはタスクの優先度順となる.
isemcntにmaxsemよりも大きい値が指定された場合には,E_PARエラーを返す.
また,maxsemに0が指定された場合や,セマフォの最大資源数の最大値
(TMAX_MAXSEM)よりも大きい値が指定された場合にも,E_PARエラーを 返す.
【µITRON3.0仕様との相違】
セマフォ生成情報から拡張情報を削除した.また,isemcntとmaxsemのデータ 型をINTからUINTに変更した.
acre_semは新設のサービスコールである.
del_sem セマフォの削除
【C言語API】
ER ercd = del_sem ( ID semid ) ;
【パラメータ】
ID semid 削除対象のセマフォのID番号
【リターンパラメータ】
ER ercd 正常終了(E_OK)またはエラーコード
【エラーコード】
E_ID 不正ID番号(semidが不正あるいは使用できない)
E_NOEXS オブジェクト未生成(対象セマフォが未登録)
【機能】
semidで指定されるセマフォを削除する.
【補足説明】
対象セマフォに対して資源の獲得を待っているタスクがある場合の扱いにつ いては,3.8節を参照すること.
sig_sem セマフォ資源の返却 【S】【B】
isig_sem 【S】【B】
【C言語API】
ER ercd = sig_sem ( ID semid ) ; ER ercd = isig_sem ( ID semid ) ;
【パラメータ】
ID semid 資源返却対象のセマフォのID番号
【リターンパラメータ】
ER ercd 正常終了(E_OK)またはエラーコード
【エラーコード】
E_ID 不正ID番号(semidが不正あるいは使用できない)
E_NOEXS オブジェクト未生成(対象セマフォが未登録)
E_QOVR キューイングオーバフロー(最大資源数を越える返却)
【機能】
semidで指定されるセマフォに対して,資源を1つ返却する.具体的には,対象
セマフォに対して資源の獲得を待っているタスクがある場合には,待ち行列の 先頭のタスクを待ち解除する.この時,対象セマフォの資源数は変化しない.
また,待ち解除されたタスクに対しては,待ち状態に入ったサービスコールの 返値としてE_OKを返す.資源の獲得を待っているタスクがない場合には,対 象セマフォの資源数に1を加える.
セマフォの資源数に1を加えるとセマフォの最大資源数を越える場合には,
E_QOVRエラーを返す.非タスクコンテキストから呼び出された場合で,サー ビスコールを遅延実行する場合には,E_QOVRエラーを返すことを,実装定義 で省略することができる.
wai_sem セマフォ資源の獲得 【S】【B】
pol_sem セマフォ資源の獲得(ポーリング) 【S】【B】
twai_sem セマフォ資源の獲得(タイムアウトあり) 【S】
【C言語API】
ER ercd = wai_sem ( ID semid ) ; ER ercd = pol_sem ( ID semid ) ;
ER ercd = twai_sem ( ID semid, TMO tmout ) ;
【パラメータ】
ID semid 資源獲得対象のセマフォのID番号
TMO tmout タイムアウト指定(twai_semのみ)
【リターンパラメータ】
ER ercd 正常終了(E_OK)またはエラーコード
【エラーコード】
E_ID 不正ID番号(semidが不正あるいは使用できない)
E_NOEXS オブジェクト未生成(対象セマフォが未登録)
E_PAR パラメータエラー(tmoutが不正;twai_semのみ)
E_RLWAI 待ち状態の強制解除(待ち状態の間に rel_wai を受付;
pol_sem以外)
E_TMOUT ポーリング失敗またはタイムアウト(wai_sem以外)
E_DLT 待ちオブジェクトの削除(待ち状態の間に対象セマフォ
が削除;pol_sem以外)
【機能】
semidで指定されるセマフォから,資源を1つ獲得する.具体的には,対象セマ
フォの資源数が1以上の場合には,セマフォの資源数から1を減じ,自タスク を待ち状態とせずにサービスコールの処理を終了する.対象セマフォの資源数 が0の場合には,自タスクを待ち行列につなぎ,セマフォ資源の獲得待ち状態 に移行させる.この時,対象セマフォの資源数は0のまま変化しない.
他のタスクがすでに待ち行列につながっている場合,自タスクを待ち行列につ なぐ処理は次のように行う.セマフォ属性にTA_TFIFO(=0x00)が指定され ている場合には,自タスクを待ち行列の末尾につなぐ.TA_TPRI(=0x01)が 指定されている場合には,自タスクを優先度順で待ち行列につなぐ.同じ優先 度のタスクの中では,自タスクを最後につなぐ.
pol_semは,wai_semの処理をポーリングで行うサービスコール,twai_semは,
wai_semにタイムアウトの機能を付け加えたサービスコールである.tmoutに
は,正の値のタイムアウト時間に加えて,TMO_POL(=0)とTMO_FEVR(=
–1)を指定することができる.