Windows版 iTRONサービスコールの作成 (固定長メモリプール)
(その2)

固定長メモリプールを生成する

固定長メモリプールを生成するサービスコールは以下のとおりです。


サービスコール名説明
cre_mpf

メモリプールID番号を指定して固定長メモリプールを生成します。

acre_mpf

メモリプールID番号を自動割付けで固定長メモリプールを生成します。

acre_mpf()はVer4.0のみサポートされています。

メモリプールID番号を指定して固定長メモリプールを生成する

メモリプール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()にてメモリバッファを確保します。
  • 確保したメモリバッファをメモリブロック単位に分割して、未使用メモリブロックキューに登録します。
  • 固定長メモリプール・リストに生成した固定長メモリプール・オブジェクトをリンクして処理を終了します。


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