Windows版 iTRONサービスコールの作成 (固定長メモリプール)
(その2)
固定長メモリプールを生成するサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
cre_mpf | メモリプールID番号を指定して固定長メモリプールを生成します。 |
acre_mpf | メモリプールID番号を自動割付けで固定長メモリプールを生成します。 |
acre_mpf()はVer4.0のみサポートされています。
メモリプールID番号を指定して固定長メモリプールを生成するには以下のサービスコールを使用します。
Ver3.0とVer4.0では構造体のメンバが若干異なりますので注意してください。
ER cre_mpf( ID mpfid, const T_CMPF *pk_cmpf )
引数 | 説明 |
---|---|
mpfid | メモリプールID番号。 |
pk_cmpf | 固定長メモリプール生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のメモリプールID番号。 |
E_PAR | パラメータエラー。 |
E_OBJ | 指定したメモリプールID番号は登録済み。 |
Ver3.0の固定長メモリプール生成情報構造体(T_CMPF)は以下のとおりです。
メンバ名 | 説明 |
---|---|
exinf | 拡張情報。 |
mpfatr | 固定長メモリプールの属性。 |
mpfcnt | 固定長メモリプール全体のブロック数。 |
blfsz | 固定長メモリブロックのサイズ(バイト数)。 |
Ver4.0の固定長メモリプール生成情報構造体(T_CMPF)は以下のとおりです。
メンバ名 | 説明 |
---|---|
mpfatr | 固定長メモリプールの属性。 |
blkcnt | 固定長メモリプール全体のブロック数。 |
blfsz | 固定長メモリブロックのサイズ(バイト数)。 |
mpf | 固定長メモリプール領域の先頭アドレス。 |
Ver3.0とVer4.0で構造体のメンバが異なるので、それぞれのサービスコールのエントリ関数内で構造体のメンバを取り出してから、固定長メモリプール生成処理を呼び出しています。
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief 固定長メモリプールの生成.
*
* @param [in] mpfid メモリプールID番号.
* @param [in] pk_cmpf メモリプール生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER cre_mpf( ID mpfid, const T_CMPF *pk_cmpf )
{
ER ercd;
WIMPFOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_cmpf ){
return E_PAR;
}
//! 固定長メモリプール生成情報をコピーする.
memset( &obj, 0, sizeof(WIMPFOBJ) );
obj.ExtInfo = pk_cmpf->exinf;
obj.Attribute = pk_cmpf->mpfatr;
obj.BlockCnt = pk_cmpf->mpfcnt;
obj.BlockSize = pk_cmpf->blfsz;
wi_CommonLock();
//! 固定長メモリプールを生成する.
ercd = wi_CreateFixedMemPool( mpfid, &obj );
wi_CommonUnlock();
return ercd;
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief 固定長メモリプールの生成.
*
* @param [in] mpfid メモリプールID番号.
* @param [in] pk_cmpf メモリプール生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER cre_mpf( ID mpfid, const T_CMPF *pk_cmpf )
{
ER ercd;
WIMPFOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_cmpf ){
return E_PAR;
}
//! 固定長メモリプール生成情報をコピーする.
memset( &obj, 0, sizeof(WIMPFOBJ) );
obj.Attribute = pk_cmpf->mpfatr;
obj.BlockCnt = pk_cmpf->blkcnt;
obj.BlockSize = pk_cmpf->blfsz;
wi_CommonLock();
//! 固定長メモリプールを生成する.
ercd = wi_CreateFixedMemPool( mpfid, &obj );
wi_CommonUnlock();
return ercd;
}
メモリプールID番号を自動割付けで固定長メモリプールを生成する (Ver4.0のみ)
メモリプールID番号を自動割付けで固定長メモリプールを生成するには以下のサービスコールを使用します。
ER acre_mpf( const T_CMPF *pk_cmpf )
引数 | 説明 |
---|---|
pk_cmpf | 固定長メモリプール生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_PAR | パラメータエラー。 |
E_NOID | ID番号不足。 |
上記以外の正数 | 生成した固定長メモリプールのID番号。(正常終了) |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief 固定長メモリプールの生成 (ID番号自動割り付け).
*
* @param [in] pk_cmpf メモリプール生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER acre_mpf( const T_CMPF *pk_cmpf )
{
ID mpfid;
ER ercd;
WIMPFOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_cmpf ){
return E_PAR;
}
//! 固定長メモリプール生成情報をコピーする.
memset( &obj, 0, sizeof(WIMPFOBJ) );
obj.Attribute = pk_cmpf->mpfatr;
obj.BlockCnt = pk_cmpf->blkcnt;
obj.BlockSize = pk_cmpf->blfsz;
wi_CommonLock();
for( mpfid = 1; mpfid < TMAX_MAXMPF; mpfid++ ){
//! 固定長メモリプールを生成する.
ercd = wi_CreateFixedMemPool( mpfid, &obj );
if( ercd == E_OK ){
ercd = mpfid;
break;
}
}
if( ercd == E_OBJ ){
ercd = E_NOID;
}
wi_CommonUnlock();
return ercd;
}
メモリプールID番号を自動割付けで固定長メモリプールを生成する関数は以下のような処理を行います。
- cre_mpf()と同様に、サービスコールのエントリ関数内で引数の構造体のメンバをコピーし、固定長メモリプール生成関数を呼び出します。
- 生成するメモリプールのID番号を1~TMAX_MAXMPFに+1づつカウントアップして、空いているID番号を探して固定長メモリプールを生成します。
- 固定長メモリプールが生成できた場合、戻り値を生成した固定長メモリプールのID番号にして処理を終了します。
- 1~TMAX_MAXMPFの全てのID番号が使用中の場合、エラーコードが「E_OBJ(固定長メモリプール登録済み)」となるので、これを「E_NOID(ID番号不足)」に置き換えてエラー終了します。
固定長メモリプール生成関数
固定長メモリプール生成関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief 固定長メモリプールの生成.
*
* @param [in] id メモリプールID番号.
* @param [in] obj メモリプール・オブジェクト構造体のポインタ.
*
* @retval エラーコード.
*/
ER wi_CreateFixedMemPool( INT id, const WIMPFOBJ *obj )
{
INT i;
DWORD size;
WIHDR *ptr;
ER ercd;
WIMPFOBJ *p;
//! 固定長メモリプール・オブジェクトを作成する.
p = (WIMPFOBJ *)wi_CreateObject( id, TMAX_MAXMPF, sizeof(WIMPFOBJ), obj, ObjList, &ercd );
if( !p ){
return ercd;
}
//! 引数が不正な場合はエラーにする.
if( obj->BlockCnt <= 0 || obj->BlockSize <= 0 ){
return E_PAR;
}
//! メモリブロックの1ブロックのサイズを計算する.
size = obj->BlockSize + sizeof(WIHDR);
//! メモリプールのバッファを確保する.
p->MemBuf = (BYTE*)malloc( obj->BlockCnt * size );
if( !p->MemBuf ){
SAFE_RELEASE( p );
return E_NOMEM;
}
//! 確保したバッファをクリアする.
memset( p->MemBuf, 0, obj->BlockCnt * size );
//! 未使用メモリブロックキューにバッファを登録する.
ptr = (WIHDR *)(p->MemBuf);
for( i = 0; i < obj->BlockCnt - 1; i++ ){
ptr->Next = (WIHDR *)((DWORD)ptr + size);
ptr = (WIHDR *)((DWORD)ptr + size);
}
p->FreeQue = (WIHDR *)(p->MemBuf);
p->UsedQue = NULL;
p->WaitQue = NULL;
//! リストに固定長メモリプールを追加する.
wi_AddObject( (WIHDR *)p, &ObjList );
return E_OK;
}
固定長メモリプールを生成する関数は以下のような処理を行います。
- 不正な引数をチェックします。生成するメモリブロックの個数が0だったり、メモリブロックのサイズが 0 の場合はエラーにします。
- 新しい固定長メモリプールを生成します。
- 生成するメモリブロックの個数とメモリブロックのサイズからメモリプールで必要なバイト数を計算して、malloc()にてメモリバッファを確保します。
- 確保したメモリバッファをメモリブロック単位に分割して、未使用メモリブロックキューに登録します。
- 固定長メモリプール・リストに生成した固定長メモリプール・オブジェクトをリンクして処理を終了します。