第6章 メモリ・プール管理機能
本章では,RI78V4が提供しているメモリ・プール管理機能について解説しています。
RI78V4におけるメモリ・プール管理機能では,
カーネル初期化部において静的に確保されたメモリ領域を管理対象としています。
なお,RI78V4では,機能単位にモジュール化された管理オブジェクトの割り付け先(セクション名)を規定しています。
以下に,RI78V4が規定しているセクション名の一覧を示します。
- .kernel_systemセクション
RI78V4の核となる処理部,および,RI78V4が提供するサービス・コールの本体処理部が割り付けられる領域です。
- .kernel_system_timer_nセクション
システム・タイマ割り込み処理部,および,far分岐情報が割り付けられる領域です。
- .kernel_infoセクション
RI78V4のバージョンなどといった情報が割り付けられる領域です。
- .kernel_const/.kernel_const_fセクション
動的に変化することのないOS資源に関する初期情報が,システム情報テーブルや割り込み情報定義ファイルとして割り付けられる領域です。
- .kernel_stackセクション
システム・スタック,および,タスク・スタックが割り付けられる領域です。
- .kernel_dataセクション
RI78V4が提供する機能を実現するうえで必要となる情報,および,動的に変化するOS資源に関する情報が管理オブジェクトとして割り付けられる領域です。
- .kernel_data_initセクション
RI78V4の初期化情報が割り付けられる領域です。
- .kernel_work0,.kernel_work1,.kernel_work2,.kernel_work3セクション
データキューのデータ,固定長メモリ・プールが割り付けられる領域です。
- .kernel_data_trace_nセクション
トレース・データが割り付けられる領域です。
- .kernel_const_trace_fセクション
トレース・データの取得に必要な情報が割り付けられる領域です。
- .kernel_system_trace_fセクション
トレース・データ取得処理部が割り付けられる領域です。
- .kernel_sbssセクション
RI78V4が使用するSADDR領域です。
RI78V4では,処理プログラムから動的なメモリ操作要求が行われた際に利用可能なメモリ領域として“固定長メモリ・プール”を提供しています。
なお,固定長メモリ・プールに対する動的なメモリ操作は,固定サイズのメモリ・ブロックを単位として行います。
RI78V4では,固定長メモリ・プールの生成方法を“
カーネル初期化部において静的に生成する”に限定しています。
したがって,RI78V4では,固定長メモリ・プールを処理プログラムからサービス・コールを発行するなどして動的に生成することはできません。
- 静的な生成
固定長メモリ・プールの静的な生成は,システム・コンフィギュレーション・ファイルに
固定長メモリ・プール情報を定義することにより実現されます。
RI78V4では,
カーネル初期化部において,情報ファイルに格納されているデータをもとに固定長メモリ・プールの生成処理を実行し,管理対象とします。
RI78V4では,
カーネル初期化部において静的に生成された固定長メモリ・プールを処理プログラムからサービス・コールを発行するなどして動的に削除することはできません。
メモリ・ブロックの獲得(永久待ち,ポーリング,タイムアウト付き)は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
get_mpf
パラメータ
mpfidで指定された固定長メモリ・プールからメモリ・ブロックを獲得し,その先頭アドレスをパラメータ
p_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールからメモリ・ブロックを獲得することができなかった(空きメモリ・ブロックが存在しなかった)場合には,メモリ・ブロックの獲得処理は実行されず,自タスクを対象固定長メモリ・プールの待ちキューにメモリ・ブロックの獲得要求順(FIFO順)でキューイングします。
これにより,自タスクは,レディ・キューから外れ,RUNNING状態からWAITING状態(メモリ・ブロック待ち状態)へと遷移します。
なお,メモリ・ブロック待ち状態の解除は,以下の場合に行われ,メモリ・ブロック待ち状態からREADY状態へと遷移します。
|
|
rel_mpfの発行により,対象固定長メモリ・プールにメモリ・ブロックが返却された
|
|
rel_waiの発行により,メモリ・ブロック待ち状態を強制的に解除された
|
|
|
|
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
func_task ( VP_INT exinf )
{
ER ercd; /*変数の宣言*/
ID mpfid = ID_mpfA; /*変数の宣言,初期化*/
VP p_blk; /*変数の宣言*/
............
............
/*メモリ・ブロックの獲得(永久待ち)*/
ercd = get_mpf ( mpfid, &p_blk );
if ( ercd == E_OK ) {
............ /*正常終了処理*/
............
/*メモリ・ブロックの返却*/
rel_mpf ( mpfid, p_blk );
} else if ( ercd == E_RLWAI ) {
............ /*強制終了処理*/
............
}
............
............
}
|
-
pget_mpf
パラメータ
mpfidで指定された固定長メモリ・プールからメモリ・ブロックを獲得し,その先頭アドレスをパラメータ
p_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールからメモリ・ブロックを獲得することができなかった(空きメモリ・ブロックが存在しなかった)場合には,メモリ・ブロックの獲得処理は実行されず,戻り値として“E_TMOUT”が返されます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
func_task ( VP_INT exinf )
{
ER ercd; /*変数の宣言*/
ID mpfid = ID_mpfA; /*変数の宣言,初期化*/
VP p_blk; /*変数の宣言*/
............
............
/*メモリ・ブロックの獲得(ポーリング)*/
ercd = pget_mpf ( mpfid, &p_blk );
if ( ercd == E_OK ) {
............ /*ポーリング成功処理*/
............
/*メモリ・ブロックの返却*/
rel_mpf ( mpfid, p_blk );
} else if ( ercd == E_TMOUT ) {
............ /*ポーリング失敗処理*/
............
}
............
............
}
|
-
tget_mpf
パラメータ
mpfidで指定された固定長メモリ・プールからメモリ・ブロックを獲得し,その先頭アドレスをパラメータ
p_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールからメモリ・ブロックを獲得することができなかった(空きメモリ・ブロックが存在しなかった)場合には,メモリ・ブロックの獲得処理は実行されず,自タスクを対象固定長メモリ・プールの待ちキューにメモリ・ブロックの獲得要求順(FIFO順)でキューイングします。
これにより,自タスクは,レディ・キューから外れ,RUNNING状態からWAITING状態(メモリ・ブロック待ち状態)へと遷移します。
なお,メモリ・ブロック待ち状態の解除は,以下の場合に行われ,メモリ・ブロック待ち状態からREADY状態へと遷移します。
|
|
rel_mpfの発行により,対象固定長メモリ・プールにメモリ・ブロックが返却された
|
|
rel_waiの発行により,メモリ・ブロック待ち状態を強制的に解除された
|
|
|
|
パラメータ tmoutで指定された待ち時間が経過した
|
|
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
func_task ( VP_INT exinf )
{
ER ercd; /*変数の宣言*/
ID mpfid = ID_mpfA; /*変数の宣言,初期化*/
VP p_blk; /*変数の宣言*/
TMO tmout = 3600; /*変数の宣言,初期化*/
............
............
/*メモリ・ブロックの獲得(タイムアウト付き)*/
ercd = tget_mpf ( mpfid, &p_blk, tmout );
if ( ercd == E_OK ) {
............ /*正常終了処理*/
............
/*メモリ・ブロックの返却*/
rel_mpf ( mpfid, p_blk );
} else if ( ercd == E_RLWAI ) {
............ /*強制終了処理*/
............
} else if ( ercd == E_TMOUT ) {
............ /*タイムアウト処理*/
............
}
............
............
}
|
備考 待ち時間
tmoutにTMO_FEVRが指定された際には“
get_mpfと同等の処理”を,TMO_POLが指定された際には“
pget_mpfと同等の処理”を実行します。
メモリ・ブロックの返却は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
rel_mpf
パラメータ
mpfidで指定された固定長メモリ・プールにパラメータ
blkで指定されたメモリ・ブロックを返却します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールの待ちキューにタスクがキューイングされていた場合には,メモリ・ブロックの返却処理は実行されず,該当タスク(待ちキューの先頭タスク)にメモリ・ブロックが渡されます。
これにより,該当タスクは,待ちキューから外れ,WAITING状態(メモリ・ブロック待ち状態)からREADY状態へ,またはWAITING-SUSPENDED状態からSUSPENDED状態へと遷移します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
func_task ( VP_INT exinf )
{
ER ercd; /*変数の宣言*/
ID mpfid = ID_mpfA; /*変数の宣言,初期化*/
VP blk; /*変数の宣言*/
............
............
ercd = get_mpf ( mpfid, &blk ); /*メモリ・ブロックの獲得*/
if ( ercd == E_OK ) {
............ /*正常終了処理*/
............
rel_mpf ( mpfid, blk ); /*メモリ・ブロックの返却*/
} else if ( ercd == E_RLWAI ) {
............ /*強制終了処理*/
............
}
............
............
}
|
備考1 本サービス・コールを発行した際,待ちキューの先頭タスクがREADY状態へと遷移する場合は,該当タスクの優先度に対応したレディ・キューの最後尾にキューイングし直す処理もあわせて実行されます。
備考2 RI78V4では,メモリ・ブロックを返却する際,メモリ・ブロックのクリア処理を行っていません。したがって,返却されたメモリ・ブロックの内容は不定となります。
固定長メモリ・プールの状態参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
ref_mpf
パラメータ
mpfidで指定された固定長メモリ・プールの固定長メモリ・プール状態情報(待ちタスクの有無など)をパラメータ
pk_rmpfで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
func_task ( VP_INT exinf )
{
ID mpfid = ID_mpfA; /*変数の宣言,初期化*/
T_RMPF pk_rmpf; /*データ構造体の宣言*/
ID wtskid; /*変数の宣言*/
UINT fblkcnt; /*変数の宣言*/
............
............
ref_mpf ( mpfid, &pk_rmpf ); /*固定長メモリ・プールの状態参照*/
wtskid = pk_rmpf.wtskid; /*待ちタスクの有無の獲得*/
fblkcnt = pk_rmpf.fblkcnt; /*空きメモリ・ブロックの総数の獲得*/
............
............
}
|