2.10.2. malloc のサポート

malloc()realloc()calloc()free() は、ヒープの抽象データ型を使用して構築されています。 あらかじめ提供されている 2 種類のヒープの実装である、ヒープ 1 とヒープ 2 のいずれかを選択できます。

malloc()realloc()calloc() のデフォルトの実装では、8 バイト境界で整列されたヒープが保持されます。

ヒープ 1: 標準ヒープ実装

デフォルトの実装であるヒープ 1 では、最も小さくかつ単純なヒープマネージャを実装しています。 ヒープは、昇順アドレスで保持され、1 つにリンクされた一連の未使用ブロックとして管理されます。 割り当て方式には、アドレスによる最初適合方式が使用されます。

この実装ではオーバーヘッドを低く抑えられますが、未使用ブロックの数が増えるに従って、malloc() または free() にかかるコストも大きくなります。 割り当て可能な最小ブロックは 4 バイトであり、それに加えて 4 バイトのオーバーヘッドがかかります。 100 個を超える未割り当てブロックが必要な場合は、ヒープ 2 を使用することを推奨します。

ヒープ 2: 代替ヒープ実装

ヒープ 2 はコンパクトな実装であり、未使用ブロックの数が増えるに従って malloc() または free() のコストが対数的に増大します。 割り当て方式には、アドレスによる最初適合方式が使用されます。 割り当て可能な最小ブロックは 12 バイトであり、それに加えて 4 バイトのオーバーヘッドがかかります。

ヒープ 2 は、何百という未使用ブロックがあっても処理時間のパフォーマンスをほぼ一定に保つ必要がある場合にお勧めします。 この代替標準実装を選択するには、以下のいずれかを使用します。

  • アセンブリ言語の IMPORT __use_realtime_heap

  • C 言語の #pragma import(__use_realtime_heap)

ヒープ 2 の使用

ヒープ 2 のリアルタイムヒープ実装では、ヒープ用に確保する最大のアドレス空間をあらかじめ決めておく必要があります。 アドレスの範囲が狭くなればなるほど、アルゴリズムの効率性が増します。

デフォルトでは、ヒープ範囲にはそのヒープの開始位置(__rt_initial_stackheap() または __rt_heap_extend() によってヒープマネージャに渡される、最初のメモリチャンクの開始位置として定義されます)から 16MB が割り当てられます。

ヒープの上下限は以下によって指定されます。

struct __heap_extent
{
    unsigned base, range;
};	
	
__value_in_regs struct __heap_extent __user_heap_extent(	
             unsigned defaultbase, unsigned defaultsize);

__user_heap_extent() の関数プロトタイプは rt_misc.h に収録されています。

ヒープ 1 のアルゴリズムでは、ヒープ範囲の上下限を指定する必要がないため、この関数は呼び出されません。

以下の場合には、__user_heap_extent() を再定義する必要があります。

  • 16MB のアドレス空間を超える範囲のヒープを必要とする場合

  • 使用するメモリモデルにおいて、最初に提供されるメモリブロックよりも下位アドレスのメモリブロックが提供される可能性がある場合

ヒープに使用するアドレス空間の範囲が狭いと事前にわかっている場合、__user_heap_extent() を再定義する必要はありませんが、再定義するとヒープアルゴリズムの速度を上げることができます。

入力パラメータは、このルーチンが定義されていない場合に使用されるデフォルト値となります。 例えば、デフォルトのベース値を変更せずに、サイズだけを調整することも可能です。

Note

返されるサイズフィールドは 2 の累乗でなければなりません。 ライブラリではこの確認が行われないため、この要件を満たしていないと、予想外のエラーが発生します。 サイズとしてゼロが返されると、ヒープ範囲が 4GB に設定されます。

ベアマシン C からのヒープ実装の使用

main() を定義しておらず、C ライブラリを初期化しないアプリケーション内でヒープ実装を使用するには、以下を行って下さい。

  1. _init_alloc(base, , top) を呼び出して、ヒープとして管理するメモリの上限と下限を定義します。

  2. 関数 unsigned __rt_heap_extend(unsigned size, void **block) を定義して、ヒープが一杯になったときにヒープを拡張するための呼び出しを処理します。

alloca()

alloca() は、malloc() と同じように動作しますが、alloca() ではガベージコレクションが自動的に実行されます(alloca()を参照)。

Copyright © 2007 ARM Limited. All rights reserved.ARM DUI 0349AJ
Non-Confidential