MALLOC(9)

名称
malloc, MALLOC, free, FREE, realloc, reallocf, MALLOC_DEFINE, MALLOC_DECLARE - カーネルメモリマネージメントルーチン

書式
<sys/types.h> <sys/malloc.h> void * malloc(unsigned long size, struct malloc_type *type, int flags) MALLOC(space, cast, unsigned long size, struct malloc_type *type, int flags) void free(void *addr, struct malloc_type *type) FREE(void *addr, struct malloc_type *type) void * realloc(void *addr, unsigned long size, struct malloc_type *type, int flags) void * reallocf(void *addr, unsigned long size, struct malloc_type *type, int flags) MALLOC_DECLARE(type) <sys/param.h> <sys/malloc.h> <sys/kernel.h> MALLOC_DEFINE(type, shortdesc, longdesc)

解説
malloc() 関数はカーネルアドレス空間の初期化されていないメモリを size で指定された大きさの 1 つのオブジェクトとして割り当てます。

free() 関数は malloc() で先に割り当てられていた addr のアドレスのメモリを再使用するために解放します。 メモリは 0 にクリアされません。 addr が NULL の場合、 free() は何もしません。

realloc() 関数は、以前に割り当てられて addr で参照されるメモリの大きさを size バイトに変更します。 メモリの内容は、新サイズと旧サイズの小さい方までは、無変更となります。 戻り値は addr と違うかもしれないことに注意してください。 要求されたメモリが割り当て不能の場合、 NULL が返され、 addr で参照されるメモリは正当で無変更のままとなります。 addr が NULL の場合、 realloc() 関数は指定された大きさの malloc() と同等に振舞います。

reallocf() 関数は realloc() とまったく同じですが、 要求されたメモリを割り当て不能の場合に 渡されたポインタのメモリを解放する点が違います。

マクロ版の MALLOC() は機能的には

    (space) = (cast)malloc((u_long)(size), type, flags)

と同等で、 マクロ版 FREE() は

    free((addr), type)

と同等です。 標準Cライブラリの同義関数 (malloc(3)) とは異なり、カーネルバージョンは更に 2 つの引数をとります。 引数 flags は malloc() の操作上の特性を以下のようにみなします。

M_ZERO
    割り当てられたメモリが全て 0 で満たされるようにします。

M_NOWAIT
    リソースの不足のため直ちに要求を満たすことができない場合は、 malloc(), realloc(), および reallocf() が NULL を返すようにします。 割り込みコンテキストでの動作時には M_NOWAIT が要求されることに注意してください。

M_WAITOK
    はリソースを待つことが OK であることを示します。 この要求がすぐに満たされることが出来ない場合には、現在のプロセスは、 他のプロセスのよってリソースが開放されることを待つために、 スリープ状態に置かれます。 M_WAITOK が指定されると malloc(), realloc(), reallocf() 関数は NULL を返すことが出来ません。

M_USE_RESERVE
    要求されたメモリを獲得するために、 システムがリザーブ領域を使ってよいことを示します。 このオプションは以前は M_KERNEL と呼ばれていましたが、 より明示的に改名されました。 このオプションは軽視されていて、カーネルから徐々に削除されています。 そのため、新たなプログラミングでは使用されない様にするべきです。

厳密に M_WAITOK または M_NOWAIT のどちらかが指定されなければなりません。

引数 type はメモリの利用方法の統計をとるためと、 簡単なサニティチェックのために使われています。 これは複数の割り当てを識別するために使用することが可能です。 この統計は ‘vmstat -m’ で調べることが出来ます。

type は MALLOC_DECLARE() と MALLOC_DEFINE() マクロを通じて struct malloc_type typedef を使用して定義されます。

    /* sys/something/foo_extern.h */
    MALLOC_DECLARE(M_FOOBUF);
    /* sys/something/foo_main.c */
    MALLOC_DEFINE(M_FOOBUF, "foobuffers",
                  "Buffers to foo data into the ether");
    /* sys/something/foo_subr.c */
    ...
    MALLOC(buf, struct foo_buf *, sizeof *buf, M_FOOBUF, M_NOWAIT);

MALLOC_DEFINE() を使用するためには、 <sys/param.h> <(sys/types.h> の代わりに) および <sys/kernel.h> をインクルードしなければなりません。

戻り値
malloc(), realloc(), reallocf() 関数はすべてのタイプのオブジェクトの格納に適切なように整列された カーネル仮想アドレスを返すか、 または要求が満足できず (すなわち M_NOWAIT がセットされていることを意味します) に NULL を返します。

実装に関する注
1 ページまでの要求に対し、 メモリアロケータは、2 の累乗の大きさの量を割り当てます。 より大きな要求に対しては、1 個以上のページが割り当てられます。 この動作に依存してはなりませんが、 この情報がメモリ使用効率の最適化に有用かもしれません。

プログラマは malloc フラグの M_NOWAIT および M_WAITOK と、 mbuf(9) フラグの M_DONTWAIT および M_TRYWAIT を混乱しないように注意するべきです。

ロックすることの考慮
malloc(), realloc() および reallocf() は高速割り込みハンドラから呼び出されることは出来ません。 スレッド化された割り込みから呼び出される時には、 flag は M_NOWAIT を含んでいなければなりません。

Giant ではない mutex が保持されている間は、 malloc(), realloc() および reallocf() は M_WAITOK 付きで呼び出されてはなりません。 free() が呼び出される時には、ジャイアントロックが保持されていても 保持されていなくても構いません。

vnode(9) インタロックを保持している時の malloc() (M_NOWAIT 付であっても) または free() への全ての呼出しは、VM オブジェクトと vnode の相互獲得のために、 LOR (ロック順序の逆転) を引き起こします。

関連項目
vmstat(8), vnode(9)

診断
INVARIANTS コンフィギュレーションオプションを付けてコンパイルされたカーネルは、 割り当てられた領域以外への書き込みや malloc() 関数と free() 関数の不均衡な呼び出しなどにより生じたメモリ不正の検出を試みます。 一貫性チェックの失敗はパニックまたはシステムコンソールメッセージを出力します。