9.3	 可変長メモリ・プール
 RI600PXでは,処理プログラムから動的なメモリ操作要求が行われた際に利用するメモリ領域として“可変長メモリ・プール”を提供しています。
 
 なお,可変長メモリ・プールに対する動的なメモリ操作は,任意サイズの可変長メモリ・ブロックを単位として行われます。
 
 現在のRI600PXの実装では,実際に獲得されるメモリ・ブロックのサイズは,最大で12種類のバリエーションから選択されます。このバリエーションは,可変長メモリ・プール生成時に指定した最大メモリ・ブロック・サイズを元に,あらかじめ規定された24種類のサイズの中から選択されます。
表9−1に,メモリ・ブロックサイズのバリエーションを示します。ただし,この振る舞いは将来変更される可能性があります。
 
 表9−1  メモリ・ブロック・サイズのバリエーション
 
 
| 
 | 
 | 
 | 
 最大メモリ・ブロック・サイズ=0x20000の場合
  
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
| 
 | 
 | 
 | 
 | 
 
 可変長メモリ・プールは,以下のいずれかの方法で生成します。
 
 2 )	 
cre_mplまたは
acre_mplサービスコールによる生成
cre_mplは,パラメータ
pk_cmplが指す領域に設定された可変長メモリ・プール生成情報にしたがって,パラメータ
mplidで指定された可変長メモリ・プールIDの可変長メモリ・プールを生成します。
acre_mplは,パラメータ
pk_cmplが指す領域に設定された可変長メモリ・プール生成情報にしたがって可変長メモリ・プールを生成し,生成された可変長メモリ・プールIDを返します。
指定する可変長メモリ・プール生成情報は,以下の通りです。
 
 -	 可変長メモリ・プール属性(
mplatr)
「タスク待ちキューはFIFO順(TA_TFIFO)」のみを指定できます。
 
 -	 可変長メモリ・プール領域のサイズ(バイト数)(
mplsz),可変長メモリ・プール領域の先頭アドレス(
mpl)
可変長メモリ・プールの先頭アドレスは,4バイト境界でなければなりません。
可変長メモリ・プール領域は,メモリ・ブロックにアクセスするタスクがアクセス可能なメモリオブジェクト内としてください。
 
 以下に,代表としてacre_mplの記述例を示します。
 
 
 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 
 
 #define MPLSZ     1024                  /*可変長メモリ・プール領域のサイズ(バイト数)*/
 
 #define MAXBLKSZ  128                   /*最大メモリ・ブロック・サイズ(バイト数)*/
 
 
 
 #pragma section B BU_SH                 /*可変長メモリ・プール領域のセクション*/
 
 static UW mpl_area[ MPLSZ/sizeof(UW)];  /* 可変長メモリ・プール領域*/
 
 #pragma section
 
 
 
 #pragma task Task1                      /*備考参照*/
 
 void Task1 ( VP_INT exinf );            /*備考参照*/
 
 void Task1 ( VP_INT exinf )
 
 {
         ID      mplid;                  /*変数の宣言*/
         T_CMPL  pk_cmpl = {             /*変数の宣言,初期化*/
                      TA_TFIFO,      /*可変長メモリ・プール属性(mplatr)*/
                      MPLSZ,         /*可変長メモリ・プール領域のサイズ(バイト数)(mplsz)*/
                      (VP)mpl_area,  /*可変長メモリ・プール領域の先頭アドレス(mpl)*/
                      MAXBLKSZ       /*最大メモリ・ブロック・サイズ(バイト数)(maxblksz)*/
        };
         ............
         mplid = acre_mpl ( &pk_cmpl );   /*可変長メモリ・プールの生成*/
         ............
 }
 
 | 
 
 備考	 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。
 
 
 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 #pragma task Task1                      /*備考参照*/
 
 void Task1 ( VP_INT exinf );            /*備考参照*/
 
 void Task1 ( VP_INT exinf )
 
 {
         ID      mplid = 8;              /*変数の宣言,初期化*/
 
 
         ............
         ............
 
         del_mpl( mplid );               /*可変長メモリ・プールの削除*/
 }
 
 | 
 
 備考	 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。
 
 可変長メモリ・ブロックの獲得は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
 
 RI600PXでは,可変長メモリ・ブロックを獲得する際,メモリ・クリア処理を行っていません。したがって,獲得された可変長メモリ・ブロックの内容は不定となります。
 
 -	 
get_mpl(待つ)
パラメータ
mplidで指定された可変長メモリ・プールからパラメータ
blkszで指定されたサイズの可変長メモリ・ブロックを獲得し,その先頭アドレスをパラメータ
p_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象可変長メモリ・プールから可変長メモリ・ブロックを獲得することができなかった(要求サイズ分の連続する空き領域が存在しなかった)場合には,可変長メモリ・ブロックの獲得は行わず,自タスクを対象可変長メモリ・プールの待ちキューにキューイングしたのち,RUNNING状態からWAITING状態(可変長メモリ・ブロック獲得待ち状態)へと遷移させます。
なお,可変長メモリ・ブロック獲得待ち状態の解除は,以下の場合に行われます。
 
  
| 
 | 
 | 
 rel_mplの発行により,対象可変長メモリ・プールに要求サイズを満足する可変長メモリ・ブロックが返却された。
  
 | 
 | 
 送信待ちキュー先頭のタスクが,以下のいずれかによって待ち状態を強制的に解除された。
  
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
 
 
 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 #pragma task Task1                      /*備考5参照*/
 
 void Task1 ( VP_INT exinf );            /*備考5参照*/
 
 void Task1 ( VP_INT exinf )
 
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mplid = 1;              /*変数の宣言,初期化*/
         UINT    blksz = 256;            /*変数の宣言,初期化*/
         VP      p_blk;                  /*変数の宣言*/
 
 
         ............
         ............
 
 
                                         /*可変長メモリ・ブロックの獲得*/
         ercd = get_mpl ( mplid, blksz, &p_blk );
 
 
         if ( ercd == E_OK ) {
                 ............            /*正常終了処理*/
                 ............
                                         /*可変長メモリ・ブロックの返却*/
                 rel_mpl ( mplid, p_blk );
         } else if ( ercd == E_RLWAI ) {
                 ............            /*強制終了処理*/
                 ............
         }
 
 
         ............
         ............
 }
 
 | 
 
 備考2	 自タスクを対象可変長メモリ・プールの待ちキューにキューイングする際のキューイング方式は,FIFO順に行われます。
 
 備考3	 獲得したメモリ・ブロックの内容は不定です。
 
 備考4	 獲得するメモリ・ブロックのアライメント数は,可変長メモリ・プールの生成方法によって異なります。
 
 備考5	 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。
 
 -	 
pget_mpl,
ipget_mpl(ポーリング)
パラメータ
mplidで指定された可変長メモリ・プールからパラメータ
blkszで指定されたサイズの可変長メモリ・ブロックを獲得し,その先頭アドレスをパラメータ
p_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象可変長メモリ・プールから可変長メモリ・ブロックを獲得することができなかった(要求サイズ分の連続する空き領域が存在しなかった)場合には,可変長メモリ・ブロックの獲得は行わず,戻り値としてE_TMOUTを返します。
以下に,本サービス・コールの記述例を示します。
 
 
 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 #pragma task Task1                      /*備考4参照*/
 
 void Task1 ( VP_INT exinf );            /*備考4参照*/
 
 void Task1 ( VP_INT exinf )
 
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mplid = 1;              /*変数の宣言,初期化*/
         UINT    blksz = 256;            /*変数の宣言,初期化*/
         VP      p_blk;                  /*変数の宣言*/
 
 
         ............
         ............
 
 
                                         /*可変長メモリ・ブロックの獲得*/
         ercd = pget_mpl ( mplid, blksz, &p_blk );
 
 
         if ( ercd == E_OK ) {
                 ............            /*ポーリング成功処理*/
                 ............
 
 
                                         /*可変長メモリ・ブロックの返却*/
                 rel_mpl ( mplid, p_blk );
         } else if ( ercd == E_TMOUT ) {
                 ............            /*ポーリング失敗処理*/
                 ............
         }
 
 
         ............
         ............
 }
 
 | 
 
 備考2	 獲得したメモリ・ブロックの内容は不定です。
 
 備考3	 獲得するメモリ・ブロックのアライメント数は,可変長メモリ・プールの生成方法によって異なります。
 
 備考4	 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。
 
 -	 
tget_mpl(タイムアウト付きで待つ)
パラメータ
mplidで指定された可変長メモリ・プールからパラメータ
blkszで指定されたサイズの可変長メモリ・ブロックを獲得し,その先頭アドレスをパラメータ
p_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象可変長メモリ・プールから可変長メモリ・ブロックを獲得することができなかった(要求サイズ分の連続する空き領域が存在しなかった)場合には,可変長メモリ・ブロックの獲得は行わず,自タスクを対象可変長メモリ・プールの待ちキューにキューイングしたのち,RUNNING状態からタイムアウト付きのWAITING状態(可変長メモリ・ブロック獲得待ち状態)へと遷移させます。
なお,可変長メモリ・ブロック獲得待ち状態の解除は,以下の場合に行われます。
 
  
| 
 | 
 | 
 rel_mplの発行により,対象可変長メモリ・プールに要求サイズを満足する可変長メモリ・ブロックが返却された。
  
 | 
 | 
 送信待ちキュー先頭のタスクが,以下のいずれかによって待ち状態を強制的に解除された。
  
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
 パラメータ tmoutで指定された待ち時間が経過した。
  
 | 
 | 
| 
 | 
 | 
 
 
 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 #pragma task Task1                      /*備考6参照*/
 
 void Task1 ( VP_INT exinf );            /*備考6参照*/
 
 void Task1 ( VP_INT exinf )
 
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mplid = 1;              /*変数の宣言,初期化*/
         UINT    blksz = 256;            /*変数の宣言,初期化*/
         VP      p_blk;                  /*変数の宣言*/
         TMO     tmout = 3600;           /*変数の宣言,初期化*/
 
 
         ............
         ............
 
 
                                         /*可変長メモリ・ブロックの獲得*/
         ercd = tget_mpl ( mplid, blksz, &p_blk, tmout );
 
 
         if ( ercd == E_OK ) {
                 ............            /*正常終了処理*/
                 ............
 
 
                                         /*可変長メモリ・ブロックの返却*/
                 rel_mpl ( mplid, p_blk );
         } else if ( ercd == E_RLWAI ) {
                 ............            /*強制終了処理*/
                 ............
         } else if ( ercd == E_TMOUT ) {
                 ............            /*タイムアウト処理*/
                 ............
         }
 
 
         ............
         ............
 }
 
 | 
 
 備考2	 自タスクを対象可変長メモリ・プールの待ちキューにキューイングする際のキューイング方式は,FIFO順に行われます。
 
 備考3	 獲得したメモリ・ブロックの内容は不定です。
 
 備考4	 獲得するメモリ・ブロックのアライメント数は,可変長メモリ・プールの生成方法によって異なります。
 
 備考6	 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。
 
 可変長メモリ・ブロックの返却は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
 
 -	 
rel_mpl
パラメータ
mplidで指定された可変長メモリ・プールにパラメータ
blkで指定された可変長メモリ・ブロックを返却します。
可変長メモリ・ブロックを返却したあと,対象可変長メモリ・プールの待ちキューにキューイングされているタスクをキューの先頭から調べていき,待ちタスクが要求するサイズのメモリを割り当てられる場合はメモリを割り当てます。この動作を待ちキューにタスクがなくなるか,メモリが割り当てられなくなるまで繰り返します。これにより,メモリを獲得できたタスクは,待ちキューから外れ,WAITING状態(可変長メモリ・ブロック獲得待ち状態)からREADY状態へ,またはWAITING-SUSPENDED状態からSUSPENDED状態へと遷移します。
以下に,本サービス・コールの記述例を示します。
 
 
 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 #pragma task Task1                      /*備考2参照*/
 
 void Task1 ( VP_INT exinf );            /*備考2参照*/
 
 void Task1 ( VP_INT exinf )
 
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mplid = 1;              /*変数の宣言,初期化*/
         UINT    blksz = 256;            /*変数の宣言,初期化*/
         VP      blk;                    /*変数の宣言*/
 
 
         ............
         ............
 
 
                                         /*可変長メモリ・ブロックの獲得*/
         ercd = get_mpl ( mplid, blksz, &blk );
 
 
         if ( ercd == E_OK ) {
                 ............            /*正常終了処理*/
                 ............
 
 
                 rel_mpl ( mplid, blk ); /*可変長メモリ・ブロックの返却*/
         } else if ( ercd == E_RLWAI ) {
                 ............            /*強制終了処理*/
                 ............
         }
 
 
         ............
         ............
 }
 
 | 
 
 備考1	 RI600PXでは,
blkに関して簡易的なエラー検出しか行っていません。
blkには,必ず正しい値を指定してください。
blkがエラー検出されない不正な値の場合,以後の動作は保証されません。
 
 備考2	 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。
 
 可変長メモリ・プール詳細情報の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
 
 -	 
ref_mpl,
iref_mpl
パラメータ
mplidで指定された可変長メモリ・プールの可変長メモリ・プール詳細情報(待ちタスクの有無,空き可変長メモリ・ブロックの合計サイズなど)をパラメータ
pk_rmplで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
 
 
 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 #pragma task Task1                      /*備考2参照*/
 
 void Task1 ( VP_INT exinf );            /*備考2参照*/
 
 void Task1 ( VP_INT exinf )
 
 {
         ID      mplid = 1;              /*変数の宣言,初期化*/
         T_RMPL  pk_rmpl;                /*データ構造体の宣言*/
         ID      wtskid;                 /*変数の宣言*/
         SIZE    fmplsz;                 /*変数の宣言*/
         UINT    fblksz;                 /*変数の宣言*/
 
 
         ............
         ............
 
 
         ref_mpl ( mplid, &pk_rmpl );    /*可変定長メモリ・プール詳細情報の参照*/
 
 
         wtskid = pk_rmpl.wtskid;        /*待ちタスクの有無の獲得*/
         fmplsz = pk_rmpl.fmplsz;        /*空き領域の合計サイズの獲得*/
         fblksz = pk_rmpl.fblksz;        /*獲得可能なメモリ・ブロックの最大サイズの獲得*/
 
 
         ............
         ............
 }
 
 | 
 
 備考2	 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。