フォーラム: 開発者 (スレッド #3106)

動的生成オブジェクトのメモリ (2003-08-05 10:43 by hamayan #5481)

お世話になっています。

今ちょっと困っているのが、acre_mbxです。
カーネルヒープを8Kbyte程度取り、acre_mbxと、del_mbxを繰り返すと、
ある所からメモリ不足となり、新たに生成できない状態になります。

コードはこんなコードで試しました。
while(1)
{
mbxid = acre_mbx( &pk_cmbx );
if( mbxid < 0 )
{
エラーメッセージの表示
}
else del_mbx(mbxid);
}
ヒープ領域のフラグメントか?とも思えるのですが、誰か他にお試しいただけないでしょうか。

RE: 動的生成オブジェクトのメモリ (2003-08-05 13:13 by ryuz #5484)

お世話になります。渕上です。

 HOSのバグっぽいですね。

 del_mbx で優先度管理用の領域を開放忘れてる
みたいです。
 優先度付きで使われてますよね(多分)?
#5481 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 13:18 by hamayan #5485)

いつもお世話になっています。

優先度は設定していません。
pk_cmbxは、
T_CMBX pk_cmbx = {TA_TFIFO | TA_MFIFO};
としています。
#5484 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 13:23 by hamayan #5486)

あれ、なんかパラメーター足りないですね。
#5485 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 13:33 by hamayan #5487)

パラメータを
T_CMBX pk_cmbx = {TA_TFIFO | TA_MFIFO, 1, NULL };
としてみました。

やはりTA_MPRIを指定していないので、後ろのパラメーターは関係無いですね。
#5486 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 15:17 by ryuz #5491)

すいません、TA_MFIFOでも1個分確保してました。

del_mbx.c のメモリ開放のところに

kernel_fre_mem(mbxcb_rom->mprihd);

を加えてみて頂けませんでしょうか?
すぐに試せなくて...

ご迷惑お掛けいたします。
#5487 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 15:49 by hamayan #5492)

お世話になっています。
お忙しい所、対応有り難うございます。

こんな感じで追加しました。
/* メモリの解放 */
kernel_fre_mem(mbxcb_ram);
KERNEL_MBXID_TO_MBXCB_RAM(mbxid) = NULL;
/*2003/08/05 追加指示 by Ryuzさん*/
kernel_fre_mem(mbxcb_ram->mbxcb_rom->mprihd);

順調です。
#5491 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 16:18 by ryuz #5493)

 お世話になります。渕上です。

 失礼、順序指定が抜けてましたね (^^;;

/* メモリの解放 */
kernel_fre_mem(mbxcb_ram->mbxcb_rom->mprihd);
kernel_fre_mem(mbxcb_ram);
KERNEL_MBXID_TO_MBXCB_RAM(mbxid) = NULL;

のように mbxcb_ram の開放の前にお願いします。
実際はクリティカルセクション(割禁区間)を抜ける
間ではヒープは壊れないので、実動作上問題ない
はずですが、気持ち悪いので (^^;;

 ちなみに cre_xxx や del_xxx はメモリ確保や開放
処理と、オブジェクト追加の間に割り込み解除を一瞬
挟むことも可能でして、このあたりが最大割込み
禁止時間を引っ張ってます(ヒープ処理は重いので)
# 今後の課題ですね...

 本当は空き領域検索途中で割り解除を入れるとか、
フラグメンテーションの起こりにくいアルゴリズムに
変えるとかするのがRTOSの本流なのでしょうけど
もともと動的生成自体そんなに使わないだろうと
タカくくっていたもので...
#5492 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 16:33 by hamayan #5494)

お世話になっています。

> のように mbxcb_ram の開放の前にお願いします。
> 実際はクリティカルセクション(割禁区間)を抜ける
> 間ではヒープは壊れないので、実動作上問題ない
> はずですが、気持ち悪いので (^^;;

(^.^)了解です。

> もともと動的生成自体そんなに使わないだろうと
> タカくくっていたもので...

有るとついつい使っちゃうんですよー
折角有るのに、HOS JSPではちと寂しい。

もっとも、オブジェクトの動的生成を乱用すると、やはりフラグメントの危険は有りますがね。
#5493 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-05 19:16 by m-arai #5495)

RE: 動的生成オブジェクトのメモリ (2003-08-05 19:23 by hamayan #5496)

早!

いつも有り難うございます。
#5495 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-06 19:13 by m-arai #5502)

ふと思いついたのですが、

src/kernel/mbx/kcre_mbx.c:

/* メールボックスコントロールブロック(動的生成用) */
typedef struct t_kernel_mbxcb
{
T_KERNEL_MBXCB_RAM mbxcb_ram; /* メールボックスコントロールブロック(RA
M部) */
T_KERNEL_MBXCB_ROM mbxcb_rom; /* メールボックスコントロールブロック(RO
M部) */
T_MSG *mprihd[0]
} T_KERNEL_MBXCB;

として、kernel_alc_memするサイズを+TSZ_MPRIHD(maxmpri)
してやり、mbxcb_rom->mprihd = mxcb->mprihd;
すれば、メモリ効率が少し良くなりますし、解放も1回で
済みますね。

ただ、*mprihd[0]という表現は古いコンパイラでは使えな
い(*)ものもあるので、実際には生成情報のmprihdがNULL
の場合には*mprihd[1]が追加されたT_KERNEL_MBXCB_PH
(仮)を使ってメモリ確保を行うようにする等の対処が必
要でしょう。
(*)gcc(と多分C99対応を謳ったもの)なら可能。

と、ここまで書いたんならさっさとコード出せやってこと
になるかと思いますが、このフォローを書いているうちに
熱が出てきたようなので寝ます。皆様も夏風邪にはお気を
つけ下さい。
#5496 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-06 20:24 by ryuz #5503)

お世話になります。Ryuzです。

 そうですね、コンフィギュレータとかもサイズ0の
配列が使えたら楽なのにと思った部分はあった記憶が...
今のところC97(でしたっけ?)完全準拠もウリの
1つなので、苦しいところです。

 ただやろうと思えば、サイズ0の配列を使わなくても
同じ事は可能です。

mbxcb_rom->mprihd = mxcb->mprihd
でわなく
mbxcb_rom->mprihd = (T_MSG *)((B*)mxcb + sizeof(mxcb))

とすれば...

可読性とのトレードオフはありますが、効率の上がる
実装ならトライしたいですね。
 うーむ、この辺がHOSの甘いところですね。
#5502 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-06 20:25 by ryuz #5504)

うち間違い C97 -> C79
それでも自信無し... (^^;;
#5503 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-06 20:34 by ryuz #5505)


だはは、一般に言うANSI-Cは
ANSI X3.159-1989
ですね。C89か? 79だと FORTRAN77 の時代か (--;;
# 末尾の9だけおぼろげに記憶にあったんですが...

ちなみに C99 とは
ISO/IEC 9899:1999 - Programming Language C
http://seclan.dll.jp/c99d/


(おまけ EC++)
http://www.caravan.net/ec2plus/
# うう、日本語ページが消えている ToT


お馬鹿でごみんなさい
#5504 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-06 20:47 by m-arai #5506)

まだ起きてました。

>mbxcb_rom->mprihd = mxcb->mprihd
>でわなく
>mbxcb_rom->mprihd = (T_MSG *)((B*)mxcb + sizeof(mxcb))
>とすれば...

これだと、アライメントが保証されない可能性がありま
せんか?バイト単位のデータなら問題はないのですが。

早く寝なければ…
#5503 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-06 21:13 by ryuz #5507)

 厳密には sizeof が保証してくれるのはT_KERNEL_MBXCBなので、T_KERNEL_MBXCBがバイト要素のみで、T_MSGがint要素など含んでいると危険な可能性もありますね。
 となると

 ((UB*)mbxcb + (sizeof(mbxcb) + sizeof(T_MSG) - 1) - (sizeof(mbxcb) + sizeof(T_MSG) - 1) % sizeof(T_MSG))

 ならOKかな (--;;;;
#5506 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-07 21:23 by m-arai #5512)

[ #2728 ] 僅かに節約できるかもしれないkcre_mbx
https://sourceforge.jp/tracker/index.php?func=detail&aid=2728&group_id=183&atid=780

テストはしてませんmOm
#5507 への返信

RE: 動的生成オブジェクトのメモリ (2003-08-07 23:15 by hamayan #5513)

やって見ましたが、良さそうですよ。
#5512 への返信

RE: 動的生成オブジェクトのメモリ (2003-09-10 21:14 by m-arai #5831)

特に問題も無いようなので、commitしました。

http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/hos/hos/hos-v4/src/kernel/mbx/kcre_mbx.c.diff?r1=1.6&r2=1.7
#5513 への返信