ZONE(9)

名称
uma_zcreate, uma_zalloc, uma_zfree, uma_zdestroy, uma_zone_set_max - ゾーンアロケータ

書式
<sys/param.h> <sys/queue.h> <vm/uma.h> uma_zone_t uma_zcreate(char *name, int size, uma_ctor ctor, uma_dtor dtor, uma_init uminit, uma_fini fini, int align, u_int16_t flags) void * uma_zalloc(uma_zone_t zone, int flags) void uma_zfree(uma_zone_t zone, void *item) void uma_zdestroy(uma_zone_t zone) void uma_zone_set_max(uma_zone_t zone, int nitems)

解説
ゾーンアロケータは動的に大きさが決められる類似した大きさの項目の集合を 管理するための効率的なインタフェースを提供します。 ゾーンアロケータは実行時に割り当てられたゾーンはもちろん、 予め割り当てられているゾーンに対しても使用することが出来、またそのため、 他のメモリ管理ルーチンよりもブートプロセスのより早い段階で利用可能です。

ゾーンは伸張性のある同一の大きさの項目の集合です。 ゾーンアロケータはどの項目が使用中かそうでないのかを見失わないようにし、 ゾーンから 項目を割り当てるための関数および解放して戻す (後での使用のために項目を 利用可能にする) ための関数を提供します。

構造体をゾーンアロケータで管理し、 割り当ての間に埋め込み済みのフィールドを残すことにより 型が固定となるゾーンの特性を使用したい場合、 ゾーンアロケータが内部で使用する先頭 2 つのポインタを この構造体が予約しておく必要があります。

    struct my_item {
            struct my_item  *z_rsvd1;
            struct my_item  *z_rsvd2;
            /* 構造体の残りの部分 */
    };

そうしない場合、各々の割当ての後でこれらのエントリが壊れたとみなすべきです。 項目の最初の割当ての後では、0 にクリアされています。 しかしそれに続く割当てでは、 最近解放されたものが内容として残っているでしょうが、 前述のフィールドは例外です。

uma_zcreate() 関数は、これから項目が割当てられることが可能な新しいゾーンを作成します。 name 引数はデバッグおよびステータスのためのテキストのゾーン名です。 このメモリは、ゾーンの割当てが解放されるまでは、解放されるべきではありません。

引数 ctor と dtor は、それぞれ uma_zalloc() と uma_zfree() の呼び出し時に uma サブシステムから呼ばれる、コールバック関数です。 これらの目的は、資源の割り当て時と解放時に必要となる、 初期化および破壊のためのフックを提供することです。 ctor および dtor のコールバックの良い使い方としては、 割り当てられたオブジェクトのグローバルカウントの調整があるでしょう。

引数 uminit と fini は、ゾーンからのオブジェクト割り当ての最適化に使用されます。 これらは、要求実現またはメモリ圧迫の理由により、 uma サブシステムが複数の項目を割り当てまたは解放する必要があるときに、 呼び出されます。 uminit および fini のコールバックの良い使い方としては、 オブジェクトに含まれるミューテックスの初期化と破壊があるでしょう。 これにより、オブジェクトが uma サブシステムのオブジェクトから返されたときに、 既に初期化済みのミューテックスを再使用可能となります。 これらは、各 uma_zalloc() や uma_zfree() の呼び出し時には呼び出されず、 複数のオブジェクトに対してバッチ的に呼び出されます。

項目はそのゾーンへのポインタを伴なう uma_zalloc() の呼出しによって割当てられ、 flags 引数に malloc(9) として文書化された選択されたフラグを設定されます。 その項目はそのゾーンに解放し戻されます。 成功の場合には項目へのポインタを返します。 ゾーン中の全項目が使用中で且つアロケータがゾーンを拡張できない稀な場合か、 M_NOWAIT が明示されている場合、 NULL を返します。

項目はそのゾーンへのポインタおよびその項目へのポインタを伴なった uma_zfree() の呼び出しによって、割当てられていたゾーンに解放し戻されます。

空である作成されたゾーンは、 uma_zdestroy() を使用して、そのゾーンのために割当てられた全てのメモリを解放して、 破壊されることが可能です。 そのゾーンから uma_zalloc() によって割当てられた項目は、その前に uma_zfree() によって解放されなければなりません。

uma_zone_set_max() の目的は、 zone 引数によって指定されたゾーンに対して専用にできるメモリの最大量を 制限することです。 nitems 引数にはそのゾーン内の項目の上限を与えます。 この制限は、割り当てられた項目、開放された項目、および CPU 毎の キャッシュ内にある開放された項目を含む、そのゾーンの中の項目のトータル数です。 複数の CPU を持つシステム上では、メモリの不足がない時にでさえ、 指定された数の項目を割り当てることが不可能であることがあります。 なぜならば、制限に引っかかる時点で、残りの全ての開放されている項目が、 他の CPU のキャッシュの中にあるかもしれないからです。

戻り値
uma_zalloc() 関数は項目へのポインタを、またはゾーンの未使用項目が不足してアロケータが ゾーンを拡張できない場合に NULL を、返します。

関連項目
malloc(9)

歴史
ゾーンアロケータは FreeBSD 3.0 ではじめて登場しました。 スラブアロケータとしての機能のため、 FreeBSD 5.0 で根本的に変更されました。

作者
-nosplit ゾーンアロケータは John S. Dyson が書きました。 ゾーンアロケータは、スラブアロケータとしての機能のため、 Jeff Roberson <jeff@FreeBSD.org> が大部分を書き直しました。

このマニュアルページは Dag-Erling Smørgrav <des@FreeBSD.org> が書きました。 UMA のために Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org> が変更しました。