Windows版 iTRONサービスコールの作成 (セマフォ)
(その2)
セマフォを生成するサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
cre_sem | セマフォID番号を指定してセマフォを生成します。 |
acre_sem | セマフォID番号を自動割付けでセマフォを生成します。 |
※ acre_sem()はVer4.0のみサポートされます。
セマフォID番号を指定してセマフォを生成するには以下のサービスコールを使用します。
※ Ver3.0とVer4.0では構造体のメンバが若干異なりますので注意してください。
ER cre_sem( ID semid, const T_CSEM *pk_csem )
引数 | 説明 |
---|---|
semid | セマフォID番号。 |
pk_csem | セマフォ生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のセマフォID番号。 |
E_PAR | パラメータエラー。 |
E_OBJ | 指定したセマフォID番号は登録済み。 |
Ver3.0のセマフォ生成情報構造体(T_CSEM)は以下のとおりです。
メンバ名 | 説明 |
---|---|
exinf | 拡張情報。 |
sematr |
セマフォの属性。 タスクの待ち行列に格納する方式を指定します。
|
isemcnt | セマフォの初期値。 |
maxsem | セマフォの最大値。 |
Ver4.0のセマフォ生成情報構造体(T_CSEM)は以下のとおりです。
メンバ名 | 説明 |
---|---|
sematr |
セマフォの属性。 タスクの待ち行列に格納する方式を指定します。
|
isemcnt | セマフォの初期値。 |
maxsem | セマフォの最大値。 |
Ver3.0とVer4.0で構造体のメンバが異なるので、それぞれのサービスコールのエントリ関数内で構造体のメンバを取り出してから、セマフォ生成処理を呼び出しています。
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief セマフォの生成.
*
* @param [in] semid セマフォID番号.
* @param [in] pk_csem セマフォ生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER cre_sem( ID semid, const T_CSEM *pk_csem )
{
ER ercd;
WISEMOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_csem ){
return E_PAR;
}
//! セマフォ生成情報をコピーする.
memset( &obj, 0, sizeof(WISEMOBJ) );
obj.Attribute = pk_csem->sematr;
obj.SemCnt = pk_csem->isemcnt;
obj.MaxCnt = pk_csem->maxsem;
obj.ExtInfo = pk_csem->exinf;
wi_CommonLock();
//! セマフォを生成する.
ercd = wi_CreateSemaphore( semid, &obj );
wi_CommonUnlock();
return ercd;
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief セマフォの生成.
*
* @param [in] semid セマフォID番号.
* @param [in] pk_csem セマフォ生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER cre_sem( ID semid, const T_CSEM *pk_csem )
{
ER ercd;
WISEMOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_csem ){
return E_PAR;
}
//! セマフォ生成情報をコピーする.
memset( &obj, 0, sizeof(WISEMOBJ) );
obj.Attribute = pk_csem->sematr;
obj.SemCnt = pk_csem->isemcnt;
obj.MaxCnt = pk_csem->maxsem;
wi_CommonLock();
//! セマフォを生成する.
ercd = wi_CreateSemaphore( semid, &obj );
wi_CommonUnlock();
return ercd;
}
セマフォID番号を自動割付けでセマフォを生成する (Ver4.0のみ)
セマフォID番号を自動割付けでセマフォを生成するには以下のサービスコールを使用します。
ER_ID acre_sem( const T_CSEM *pk_csem )
引数 | 説明 |
---|---|
pk_csem | セマフォ生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_PAR | パラメータエラー。 |
E_NOID | ID番号不足。 |
上記以外の正数 | 生成したセマフォのID番号。(正常終了) |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief セマフォの生成 (ID番号自動割り付け).
*
* @param [in] pk_csem セマフォ生成情報構造体のポインタ.
*
* @retval セマフォID番号またはエラーコード.
*/
ER_ID acre_sem( const T_CSEM *pk_csem )
{
ID semid;
ER_ID ercd;
WISEMOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_csem ){
return E_PAR;
}
//! セマフォ生成情報をコピーする.
memset( &obj, 0, sizeof(WISEMOBJ) );
obj.Attribute = pk_csem->sematr;
obj.SemCnt = pk_csem->isemcnt;
obj.MaxCnt = pk_csem->maxsem;
wi_CommonLock();
for( semid = 1; semid < TMAX_MAXSEM; semid++ ){
//! セマフォを生成する.
ercd = wi_CreateSemaphore( semid, &obj );
if( ercd == E_OK ){
ercd = semid;
break;
}
}
if( ercd == E_OBJ ){
ercd = E_NOID;
}
wi_CommonUnlock();
return ercd;
}
セマフォID番号を自動割付けでセマフォを生成する関数は以下のような処理を行います。
- cre_sem()と同様に、サービスコールのエントリ関数内で引数の構造体のメンバをコピーし、セマフォ生成関数を呼び出します。
- 生成するセマフォのID番号を1~TMAX_MAXSEMに+1づつカウントアップして、空いているID番号を探してセマフォを生成します。
- セマフォが生成できた場合、戻り値を生成したセマフォのID番号にして処理を終了します。
- 1~TMAX_MAXSEMの全てのID番号が使用中の場合、エラーコードが「E_OBJ(セマフォ登録済み)」となるので、これを「E_NOID(ID番号不足)」に置き換えてエラー終了します。
セマフォ生成関数
セマフォを生成する関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief セマフォの生成.
*
* @param [in] id セマフォID番号.
* @param [in] obj セマフォ構造体のポインタ.
*
* @retval エラーコード.
*/
ER wi_CreateSemaphore( INT id, const WISEMOBJ *obj )
{
ER ercd;
WISEMOBJ *p;
//! 引数が不正な場合はエラーにする.
if( obj->SemCnt > obj->MaxCnt || obj->MaxCnt == 0 ){
return E_PAR;
}
//! セマフォ・オブジェクトを作成する.
p = (WISEMOBJ *)wi_CreateObject( id, TMAX_MAXSEM, sizeof(WISEMOBJ), obj, ObjList, &ercd );
if( !p ){
return ercd;
}
//! リストにセマフォを追加する.
wi_AddObject( (WIHDR *)p, &ObjList );
return E_OK;
}
セマフォを生成する関数は以下のような処理を行います。
- 不正な引数のチェックを行います。セマフォ・カウンタの初期値がカウンタの最大値よりも大きかったり、カウンタの最大値が 0 の場合はエラーにします。
- 新しいセマフォを生成します。
- セマフォ・リストに生成したセマフォ・オブジェクトをリンクして処理を終了します。
ちなみに...
今回は使用しませんでしたが、Windowsでセマフォを生成するAPIは以下のAPIです。
HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName )
引数 | 説明 |
---|---|
lpSemaphoreAttributes | 作成するセマフォのセキュリティ記述子。 |
lInitialCount | 作成するセマフォの初期のカウント値。 |
lMaximumCount | 作成するセマフォの最大カウント値。 |
lpName | 作成するセマフォの名前。 |
成功すると作成したセマフォのオブジェクト・ハンドルが戻り値として返ります。失敗した場合はNULLが返ります。
セマフォを破棄するときは、CloseHandle()を使用します。