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 |
タイムアウトの設定値。
|
戻り値 | 説明 |
---|---|
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)。 |
戻り値 | 説明 |
---|---|
WAIT_OBJECT_0 | オブジェクトがシグナル状態になりました。 |
WAIT_TIMEOUT | タイムアウト時間経過しました。 |
WAIT_ABANDONED | オブジェクトが削除されました。 |