7.3 可変長メモリ・プール
RI600V4では,処理プログラムから動的なメモリ操作要求が行われた際に利用するメモリ領域として“可変長メモリ・プール”を提供しています。

なお,可変長メモリ・プールに対する動的なメモリ操作は,任意サイズの可変長メモリ・ブロックを単位として行われます。

7.3.1 可変長メモリ・プールの生成

RI600V4では,可変長メモリ・プールの静的な生成のみサポートしています。処理プログラムからサービス・コールを発行して動的に生成することはできません。

可変長メモリ・プールの静的生成とは,システム・コンフィギュレーション・ファイルで静的API“variable_memorypool[]”を使用して可変長メモリ・プールを定義することをいいます。

静的API“variable_memorypool[]”の詳細は,「19.15 可変長メモリ・プール情報(variable_memorypool[])」を参照してください。

7.3.2 可変長メモリ・ブロックのサイズ

RI600V4の現在の実装では,実際に獲得されるメモリ・ブロックのサイズは,最大で12種類のバリエーションから選択されます。このバリエーションは,可変長メモリ・プール情報(variable_memorypool[])可変長メモリ・ブロック・サイズの上限(max_memsize)を元に,あらかじめ規定された24種類のサイズの中から選択されます。以下に,メモリ・ブロックサイズのバリエーションを示します。ただし,この振る舞いは将来変更される可能性があります。

表7−1  メモリ・ブロック・サイズのバリエーション

項番

メモリ・ブロックのサイズ

(16進数)

例1:

max_memsize=0x100の場合

例2:

max_memsize=0x20000の場合

1

12 (0xC)



×

2

36 (0x24)



×

3

84 (0x54)





4

180 (0xB4)





5

372 (0x174)

×



6

756 (0x2F4)

×



7

1524 (0x5F4)

×



8

3060 (0xBF4)

×



9

6132 (0x17F4)

×



10

12276 (0x2FF4)

×



11

24564 (0x5FF4)

×



12

49140 (0xBFF4)

×



13

98292 (0x17FF4)

×



14

196596 (0x2FFF4)

×



15

393204 (0x5FFF4)

×

×

16

786420 (0xBFFF4)

×

×

17

1572852 (0x17FFF4)

×

×

18

3145716 (0x2FFFF4)

×

×

19

6291444 (0x5FFFF4)

×

×

20

12582900 (0xBFFFF4)

×

×

21

25165812 (0x17FFFF4)

×

×

22

50331636 (0x2FFFFF4)

×

×

23

100663284 (0x5FFFFF4)

×

×

24

201326580 (0xBFFFFF4)

×

×



7.3.3 可変長メモリ・ブロックの獲得

可変長メモリ・ブロックの獲得は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

RI600V4では,可変長メモリ・ブロックを獲得する際,メモリ・クリア処理を行っていません。したがって,獲得された可変長メモリ・ブロックの内容は不定となります。

- get_mpl(待つ)

- pget_mplipget_mpl(ポーリング)

- tget_mpl(タイムアウト付きで待つ)

- get_mpl(待つ)
パラメータmplidで指定された可変長メモリ・プールからパラメータblkszで指定されたサイズの可変長メモリ・ブロックを獲得し,その先頭アドレスをパラメータp_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象可変長メモリ・プールから可変長メモリ・ブロックを獲得することができなかった(要求サイズ分の連続する空き領域が存在しなかった)場合には,可変長メモリ・ブロックの獲得は行わず,自タスクを対象可変長メモリ・プールの待ちキューにキューイングしたのち,RUNNING状態からWAITING状態(可変長メモリ・ブロック獲得待ち状態)へと遷移させます。
なお,可変長メモリ・ブロック獲得待ち状態の解除は,以下の場合に行われます。




 
可変長メモリ・ブロック獲得待ち状態の解除操作

戻り値

rel_mplの発行により,対象可変長メモリ・プールに要求サイズを満足する可変長メモリ・ブロックが返却された。

E_OK

送信待ちキュー先頭のタスクが,以下のいずれかによって待ち状態を強制的に解除された。

- rel_waiの発行により,待ち状態を強制的に解除された。

- irel_waiの発行により,待ち状態を強制的に解除された。

- ter_tskの発行により,待ち状態を強制的に解除された。

- tget_mplのパラメータtmoutで指定された待ち時間が経過した。

E_OK

rel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

irel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

vrst_mplの発行により,対象可変長メモリ・プールがリセットされた。

EV_RST



以下に,本サービス・コールの記述例を示します。

 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600が出力するヘッダ・ファイルの定義*/
 
 void task ( 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 ) {
                 ............            /*強制終了処理*/
                 ............
         }
 
         ............
         ............
 }


備考1 実際に獲得されるメモリ・ブロックのサイズについては,「7.3.2 可変長メモリ・ブロックのサイズ」を参照してください。

備考2 自タスクを対象可変長メモリ・プールの待ちキューにキューイングする際のキューイング方式は,FIFO順に行われます。

備考3 獲得したメモリ・ブロックの内容は不定です。

備考4 獲得するメモリ・ブロックのアライメント数は1です。アライメント数を4とするには,可変長メモリ・プール情報(variable_memorypool[])メモリ・プール領域に付与するセクション名(mpl_section)に個別のセクション名を指定し,リンク時にそのセクションを4バイト境界アドレスに配置してください。

- pget_mplipget_mpl(ポーリング)
パラメータmplidで指定された可変長メモリ・プールからパラメータblkszで指定されたサイズの可変長メモリ・ブロックを獲得し,その先頭アドレスをパラメータp_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象可変長メモリ・プールから可変長メモリ・ブロックを獲得することができなかった(要求サイズ分の連続する空き領域が存在しなかった)場合には,可変長メモリ・ブロックの獲得は行わず,戻り値としてE_TMOUTを返します。
以下に,本サービス・コールの記述例を示します。




 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600が出力するヘッダ・ファイルの定義*/
 
 void task ( 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 ) {
                 ............            /*ポーリング失敗処理*/
                 ............
         }
 
         ............
         ............
 }


備考1 実際に獲得されるメモリ・ブロックのサイズについては,「7.3.2 可変長メモリ・ブロックのサイズ」を参照してください。

備考2 獲得したメモリ・ブロックの内容は不定です。

備考3 獲得するメモリ・ブロックのアライメント数は1です。アライメント数を4とするには,可変長メモリ・プール情報(variable_memorypool[])メモリ・プール領域に付与するセクション名(mpl_section)に個別のセクション名を指定し,リンク時にそのセクションを4バイト境界アドレスに配置してください。

- tget_mpl(タイムアウト付きで待つ)
パラメータmplidで指定された可変長メモリ・プールからパラメータblkszで指定されたサイズの可変長メモリ・ブロックを獲得し,その先頭アドレスをパラメータp_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象可変長メモリ・プールから可変長メモリ・ブロックを獲得することができなかった(要求サイズ分の連続する空き領域が存在しなかった)場合には,可変長メモリ・ブロックの獲得は行わず,自タスクを対象可変長メモリ・プールの待ちキューにキューイングしたのち,RUNNING状態からタイムアウト付きのWAITING状態(可変長メモリ・ブロック獲得待ち状態)へと遷移させます。
なお,可変長メモリ・ブロック獲得待ち状態の解除は,以下の場合に行われます。




 
可変長メモリ・ブロック獲得待ち状態の解除操作

戻り値

rel_mplの発行により,対象可変長メモリ・プールに要求サイズを満足する可変長メモリ・ブロックが返却された。

E_OK

送信待ちキュー先頭のタスクが,以下のいずれかによって待ち状態を強制的に解除された。

- rel_waiの発行により,待ち状態を強制的に解除された。

- irel_waiの発行により,待ち状態を強制的に解除された。

- ter_tskの発行により,待ち状態を強制的に解除された。

- tget_mplのパラメータtmoutで指定された待ち時間が経過した。

E_OK

rel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

irel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

vrst_mplの発行により,対象可変長メモリ・プールがリセットされた。

EV_RST

パラメータtmoutで指定された待ち時間が経過した。

E_TMOUT



以下に,本サービス・コールの記述例を示します。

 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600が出力するヘッダ・ファイルの定義*/
 
 void task ( 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 ) {
                 ............            /*タイムアウト処理*/
                 ............
         }
 
         ............
         ............
 }


備考1 実際に獲得されるメモリ・ブロックのサイズについては,「7.3.2 可変長メモリ・ブロックのサイズ」を参照してください。

備考2 自タスクを対象可変長メモリ・プールの待ちキューにキューイングする際のキューイング方式は,FIFO順に行われます。

備考3 獲得したメモリ・ブロックの内容は不定です。

備考4 獲得するメモリ・ブロックのアライメント数は1です。アライメント数を4とするには,可変長メモリ・プール情報(variable_memorypool[])メモリ・プール領域に付与するセクション名(mpl_section)に個別のセクション名を指定し,リンク時にそのセクションを4バイト境界アドレスに配置してください。

備考5 待ち時間tmoutTMO_FEVRが指定された際には“get_mplと同等の処理”を,TMO_POLが指定された際には“pget_mplと同等の処理”を実行します。

7.3.4 可変長メモリ・ブロックの返却

可変長メモリ・ブロックの返却は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- rel_mpl
パラメータmplidで指定された可変長メモリ・プールにパラメータblkで指定された可変長メモリ・ブロックを返却します。
可変長メモリ・ブロックを返却したあと,対象可変長メモリ・プールの待ちキューにキューイングされているタスクをキューの先頭から調べていき,待ちタスクが要求するサイズのメモリを割り当てられる場合はメモリを割り当てます。この動作を待ちキューにタスクがなくなるか,メモリが割り当てられなくなるまで繰り返します。これにより,メモリを獲得できたタスクは,待ちキューから外れ,WAITING状態(可変長メモリ・ブロック獲得待ち状態)からREADY状態へ,またはWAITING-SUSPENDED状態からSUSPENDED状態へと遷移します。
以下に,本サービス・コールの記述例を示します。



 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600が出力するヘッダ・ファイルの定義*/
 
 void task ( 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 ) {
                 ............            /*強制終了処理*/
                 ............
         }
 
         ............
         ............
 }


備考 RI600V4では,blkに関して簡易的なエラー検出しか行っていません。blkには,必ず正しい値を指定してください。blkがエラー検出されない不正な値の場合,以後の動作は保証されません。

7.3.5 可変長メモリ・プール詳細情報の参照

可変長メモリ・プール詳細情報の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- ref_mpliref_mpl
パラメータmplidで指定された可変長メモリ・プールの可変長メモリ・プール詳細情報(待ちタスクの有無,空き可変長メモリ・ブロックの合計サイズなど)をパラメータpk_rmplで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。


 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600が出力するヘッダ・ファイルの定義*/
 
 void task ( 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;        /*獲得可能なメモリ・ブロックの最大サイズの獲得*/
 
         ............
         ............
 }


備考 可変長メモリ・プール詳細情報T_RMPLについての詳細は,「【 可変長メモリ・プール詳細情報T_RMPLの構造 】」を参照してください。