Windows版 iTRONサービスコールの作成 (セマフォ)
(その2)

セマフォを生成する

セマフォを生成するサービスコールは以下のとおりです。


サービスコール名説明
cre_sem

セマフォID番号を指定してセマフォを生成します。

acre_sem

セマフォID番号を自動割付けでセマフォを生成します。

※ acre_sem()はVer4.0のみサポートされます。

セマフォID番号を指定してセマフォを生成する

セマフォ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

セマフォの属性。

タスクの待ち行列に格納する方式を指定します。

  • TA_TFIFOの場合、タスクの待ち行列をFOFO順にします。
  • TA_TPRIの場合、タスクの待ち行列をタスク優先度順にします。
isemcnt

セマフォの初期値。

maxsem

セマフォの最大値。

Ver4.0のセマフォ生成情報構造体(T_CSEM)は以下のとおりです。

メンバ名説明
sematr

セマフォの属性。

タスクの待ち行列に格納する方式を指定します。

  • TA_TFIFOの場合、タスクの待ち行列をFOFO順にします。
  • TA_TPRIの場合、タスクの待ち行列をタスク優先度順にします。
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()を使用します。



Windowsは米国Microsoft Corporationの登録商標です。