Windows版 iTRONサービスコールの作成 (ミューテックス)
(その4)
ミューテックスをロックするサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
loc_mtx | ミューテックスをロックします。 |
ploc_mtx | ポーリング方式でミューテックスをロックします。 |
tloc_mtx | タイムアウト付きでミューテックスをロックします。 |
タイムアウトなしでミューテックスをロックするには以下のサービスコールを使用します。
ER loc_mtx( ID mtxid )
引数 | 説明 |
---|---|
mtxid | ミューテックスID番号。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のミューテックスID番号。 |
E_NOEXS | 指定したミューテックスID番号は登録されていない。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ミューテックスのロック (タイムアウトなし).
*
* @param [in] mtxid ミューテックスID番号.
*
* @retval エラーコード.
*/
ER loc_mtx( ID mtxid )
{
//! タイムアウトなしでミューテックスをロックする.
return tloc_mtx( mtxid, TMO_FEVR );
}
tloc_mtx()のタイムアウト設定に TMO_FEVR を指定して呼び出します。
ミューテックスがロックできない場合は、ミューテックスのロックが解除されるまでタスクをスリープさせます。
ポーリングでミューテックスをロックするには以下のサービスコールを使用します。
ER ploc_mtx( ID mtxid )
引数 | 説明 |
---|---|
mtxid | ミューテックスID番号。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のミューテックスID番号。 |
E_NOEXS | 指定したミューテックスID番号は登録されていない。 |
E_TMOUT | ミューテックスのロックが解除されない。 |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ミューテックスのロック (ポーリング).
*
* @param [in] mtxid ミューテックスID番号.
*
* @retval エラーコード.
*/
ER ploc_mtx( ID mtxid )
{
//! ミューテックスをロックできるかどうか調べる.
return tloc_mtx( mtxid, TMO_POL );
}
tloc_mtx()のタイムアウト設定に TMO_POL を指定して呼び出します。
ミューテックスがロックできない場合は、タスクをスリープさせずに戻り値をE_TMOUTとしてすぐにサービスコールから戻ります。
タイムアウト付きでミューテックスをロックするには以下のサービスコールを使用します。
ER tloc_mtx( ID mtxid, TMO tmout )
引数 | 説明 |
---|---|
mtxid | ミューテックスID番号。 |
tmout |
タイムアウトの設定値。
|
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のミューテックスID番号。 |
E_NOEXS | 指定したミューテックスID番号は登録されていない。 |
E_TMOUT | ミューテックスがロックできずにタイムアウト。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ミューテックスのロック (タイムアウトあり).
*
* @param [in] mtxid ミューテックスID番号.
* @param [in] tmout タイムアウト設定.
*
* @retval エラーコード.
*/
ER tloc_mtx( ID mtxid, TMO tmout )
{
ER ercd;
wi_CommonLock();
//! ミューテックスをロックする.
ercd = wi_LockMutex( mtxid, tmout );
wi_CommonUnlock();
return ercd;
}
指定したミューテックスID番号を引数としてミューテックスのロック関数を呼び出します。
ミューテックスがロックできない場合は、ミューテックスのロックが解除されるか、タイムアウトで設定した時間が経過するまでタスクをスリープさせます。
ミューテックスのロック関数
ミューテックスのロック関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief ミューテックスをロックする.
*
* @param [in] id ミューテックスID番号.
* @param [in] tmout タイムアウト設定.
*
* @retval エラーコード.
*/
ER wi_LockMutex( INT id, TMO tmout )
{
INT tsk_id;
ER ercd;
WIMTXOBJ *p;
//! ミューテックスIDのオブジェクトを取得する.
p = (WIMTXOBJ *)wi_FindObject( id, TMAX_MAXMTX, ObjList, &ercd );
if( !p ){
return ercd;
}
//! 非コンテキストのタスクから呼び出された場合はエラーにする.
tsk_id = wi_GetActiveTaskId();
if( tsk_id == 0 ){
return E_CTX;
}
//! 多重ロックはエラーにする.
if( p->LockId == tsk_id ){
return E_ILUSE;
}
//! ミューテックスがロックされていなければ、ロックして終了する.
if( p->LockId == 0 ){
p->LockId = tsk_id;
return E_OK;
}
//! ロックが解除されるまでタスクをスリープさせる.
ercd = wi_TaskWait( id, TTW_MTX, tmout, p->Attribute, &(p->WaitQue) );
if( ercd == E_OK ){
p->LockId = tsk_id;
}
return ercd;
}
ミューテックスのロック関数は以下のような処理を行います。
- 引数で指定されたミューテックスID番号に該当するミューテックス・オブジェクトを取り出します。
- 非タスクコンテキストから呼び出された場合はエラー終了します。
- ミューテックスがロックされていなければ、ミューテックスをロックして正常終了します。
- 他のタスクがミューテックスのロックを解除するか、タイムアウトになるまでタスクをスリープさせます。
- タスクのスリープから復帰したときに正常終了で復帰した場合のみ、ミューテックスをロックします。