MALLOC(9)

,

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

書式
<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() 関数はカーネルアドレス空間の初期化されていないメモリを 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_NOWAIT
    リソースの不足のため直ちに要求を満たすことができない場合は、 malloc(), realloc(), reallocf() が NULL を返すようにします。 通常は、 他のプロセスによるリソースの開放を待つためにスリープ状態にされます。 このフラグがセットされていれば、 malloc() はブロックせずに NULL を返します。 M_WAITOK が 0 に定義されていることに注意してください。 これはブロッキング操作がデフォルトだということです。 割り込みコンテキストでの動作時には M_NOWAIT が必要であることにも注意してください。

M_ASLEEP
    リソースの不足のため直ちに要求を満たすことができない場合は、 malloc(), realloc(), reallocf() が asleep() を呼ぶようにします。 M_ASLEEP の単独での使用は実用的ではなく、常に M_NOWAIT との論理和(OR)をとって 本関数 に asleep() を呼ばせ、直ちに NULL を返させます。 呼び出し側がある時点で await() を呼び、割り当てのリトライをすることが期待されています。 当のルーチンに依存して、呼び出し側で一時的な失敗を上位に連鎖的に伝搬し、実際に 本関数 がキューに入れた非同期のウェイトをブロックする 幾つかの別の高レベルルーチンをもつことを決めることも出来ます。

M_WAITOK
    リソースを待つことが可能(OK)であることを示します。 都合の悪いことに 0 と定義されているので、直接この値に対して比較したり、 フラグとして論理積(AND)をとったりしないように注意されなければなりません。 デフォルトの操作はメモリの割り当てが成功するまでブロックします。 M_NOWAIT が指定されると malloc(), realloc(), reallocf() は単に NULL を返すことが出来ます。

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

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

type は MALLOC_DECLARE() と MALLOC_DEFINE() マクロを通じて malloc_type_t 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(), realloc(), reallocf() はすべてのタイプのオブジェクトの格納に適切なように整列された カーネル仮想アドレスを返すか、 または要求が満足できず (すなわち M_NOWAIT がセットされていることを意味します) に NULL を返します。 M_ASLEEP がセットされていて 関数 が NULL を返す場合、副作用として asleep() が呼び出されます。

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

関連項目
vmstat(8)

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

•   panic: “malloc: bogus type”
•   panic: “malloc: allocation too large”
•   panic: “malloc: wrong bucket”
•   panic: “malloc: lost data”
•   panic: “free: address 0x%x out of range”
•   panic: “free: type %d out of range”
•   panic: “free: unaligned addr <description of object>”
•   panic: “free: item modified”
•   panic: “free: multiple free[s]”
•   “Data modified on freelist: <description of object>”