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

セマフォ資源を獲得する

セマフォ資源を獲得するサービスコールは以下のとおりです。


サービスコール名説明
wai_sem

タイムアウトなしでセマフォ資源を獲得します。

pol_sem

ポーリング方式でセマフォ資源を獲得します。

twai_sem

タイムアウト付きでセマフォ資源を獲得します。

セマフォ資源を獲得する (タイムアウトなし)

タイムアウトなしでセマフォ資源を獲得するには以下のサービスコールを使用します。



    ER wai_sem( ID semid )
	

引数説明
semid

セマフォID番号。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のセマフォID番号。

E_NOEXS

指定したセマフォID番号は登録されていない。

E_CTX

非コンテキスト・タスクからの呼び出し。


・サービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  セマフォ資源の獲得 (タイムアウトなし).
 *
 *  @param  [in]    semid   セマフォID番号.
 *
 *  @retval エラーコード.
 */
ER      wai_sem( ID semid )
{
    //! タイムアウトなしでセマフォ資源を獲得する.
    return twai_sem( semid, TMO_FEVR );
}
	

twai_sem()のタイムアウト設定に TMO_FEVR を指定して呼び出します。

セマフォ資源が獲得できない場合は、他のタスクがsig_sem()を呼び出してセマフォ資源を返却するまでタスクをスリープさせます。

セマフォ資源を獲得する(ポーリング)

ポーリングでセマフォ資源を獲得するには以下のサービスコールを使用します。



    ER pol_sem( ID semid )
	

引数説明
semid

セマフォID番号。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のセマフォID番号。

E_NOEXS

指定したセマフォID番号は登録されていない。

E_TMOUT

セマフォ資源が獲得できない。


・サービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  セマフォ資源の獲得 (ポーリング).
 *
 *  @param  [in]    semid   セマフォID番号.
 *
 *  @retval エラーコード.
 */
ER      pol_sem( ID semid )
{
    //! 獲得待ちなしでセマフォ資源を獲得する.
    return twai_sem( semid, TMO_POL );
}
	

twai_sem()のタイムアウト設定に TMO_POL を指定して呼び出します。

セマフォ資源が獲得できない場合は、タスクをスリープさせずに戻り値をE_TMOUTとしてすぐにサービスコールから戻ります。

セマフォ資源を獲得する

タイムアウト付きでセマフォ資源を獲得するには以下のサービスコールを使用します。



    ER twai_sem( ID semid, TMO tmout )
	

引数説明
semid

セマフォID番号。

tmout

タイムアウトの設定値。

  • TMO_FEVRの場合、永久にsig_sem()を待ちます。
  • TMO_POLの場合、セマフォ資源が獲得できなくてもタスクをスリープしません。
  • その他の正数はタイムアウト値となります。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のセマフォID番号。

E_NOEXS

指定したセマフォID番号は登録されていない。

E_TMOUT

セマフォ資源が獲得できずにタイムアウト。

E_CTX

非コンテキスト・タスクからの呼び出し。


・サービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  セマフォ資源の獲得 (タイムアウトあり).
 *
 *  @param  [in]    semid   セマフォID番号.
 *  @param  [in]    tmout   タイムアウト設定.
 *
 *  @retval エラーコード.
 */
ER      twai_sem( ID semid, TMO tmout )
{
    ER ercd;

    wi_CommonLock();

    //! セマフォの資源を獲得する.
    ercd = wi_WaitSemaphore( semid, tmout );

    wi_CommonUnlock();
    return ercd;
}
	

指定したセマフォID番号のセマフォ資源を獲得します。

セマフォ資源が獲得できない場合は、他のタスクがsig_sem()を呼び出してセマフォ資源を返却するか、タイムアウトで設定した時間が経過するまでタスクをスリープさせます。

セマフォの資源を獲得する関数

セマフォの資源を獲得する関数のソースコードは以下のとおりです。



/****************************************************************************/
/*!
 *  @brief  セマフォ資源の獲得.
 *
 *  @param  [in]    id      セマフォID番号.
 *  @param  [in]    tmout   タイムアウト設定.
 *
 *  @retval エラーコード.
 */
ER      wi_WaitSemaphore( INT id, TMO tmout )
{
    ER          ercd;
    WISEMOBJ    *p;

    //! セマフォIDのオブジェクトを取得する.
    p = (WISEMOBJ *)wi_FindObject( id, TMAX_MAXSEM, ObjList, &ercd );
    if( !p ){
        return ercd;
    }
    //! セマフォ・カウンタが0でなければ、セマフォ資源を獲得させて終了する.
    if( p->SemCnt > 0 ){
        p->SemCnt--;
        return E_OK;
    }
    //! セマフォ資源が返却されるまでタスクをスリープさせる.
    ercd = wi_TaskWait( id, TTW_SEM, tmout, p->Attribute, &(p->WaitQue) );
    if( ercd == E_OK ){
        if( p->SemCnt > 0 ){
            p->SemCnt--;
        }
    }
    return ercd;
}
	

セマフォの資源を獲得する関数は以下のような処理を行います。

  • 引数で指定されたセマフォID番号に該当するセマフォ・オブジェクトを取り出します。
  • セマフォ・カウンタが0でなければセマフォ・カウンタを-1して正常終了します。
  • 他のタスクがセマフォ資源を返却するか、タイムアウトになるまでタスクをスリープさせます。
  • タスクのスリープから復帰したときに正常終了で復帰した場合のみ、セマフォ・カウンタを-1します。

ちなみに...

今回は使用しませんでしたが、Windowsでセマフォの資源を獲得するには WaitForSingleObject() などを使用します。



    DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds )
	

引数説明
hHandle

オブジェクト(セマフォ)のハンドル。

dwMilliseconds

タイムアウト時間(ms)。
INFINITE を指定するとオブジェクトがシグナル状態になるまで(セマフォの資源が獲得できるまで)スリープします。
0を指定するとオブジェクトが非シグナル状態でもスリープしないで返ります。

戻り値説明
WAIT_OBJECT_0

オブジェクトがシグナル状態になりました。

WAIT_TIMEOUT

タイムアウト時間経過しました。

WAIT_ABANDONED

オブジェクトが削除されました。



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