mmap(2) FreeBSD 一般コマンドマニュアル

mmap

前のページ 上に戻る 次のページ

mmap




書式

     #include <sys/types.h>
     #include <sys/mman.h>

     void *
     mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);


解説

     mmap() 関数は、 addr を始点として最大で len バイトの連続するページに、 fd
     によって記述されるオブジェクトのバイトオフセット offset の位置から始まる
     部分をマップされるようにします。 len がページサイズの倍数でない場合、マッ
     プされた領域は指定の範囲を越えて拡張されるかもしれません。このような拡張
     によってマップされたオブジェクトの末端を越えた部分は 0 で埋められます。

     addr が 0 でない場合、これはシステムへのヒントとして使用されます (システ
     ムの便宜のために、領域の実際のアドレスは指定されたアドレスとは違う可能性
     があります)。 addr が 0 の場合、アドレスはシステムによって選択されます。
     領域の実際の開始アドレスが返されます。 mmap が処理に成功すると、確保され
     たアドレス範囲の以前のマッピングは削除されます。

     保護 (領域へのアクセス許可) は prot 引数で、以下の値の論理和 (or) を取っ
     た値で指定します。

     PROT_NONE   ページはアクセスできません。
     PROT_READ   ページは読取りできます。
     PROT_WRITE  ページは書込みできます。
     PROT_EXEC   ページは実行可能です。

     flags パラメータは、マップされたオブジェクトのタイプ、マッピングオプショ
     ン、およびマップされたページのコピーに対して行なわれた修正が、プロセスに
     固有であるかまたは他からの参照と共有されるかを指定します。共有、マッピン
     グタイプ、およびオプションは、以下の値の論理和 (or) を取った値で flags 引
     数に指定します。

     MAP_ANON          どの特定のファイルとも対応していない匿名メモリをマップ
                       します。 MAP_ANON を作成するのに使用されるファイル記述
                       子は -1 である必要があります。 offset パラメータは無視
                       されます。

     MAP_FIXED         システムが、指定されたアドレスと異なるアドレスを選択す
                       ることを許容しません。指定されたアドレスが使用できない
                       場合、 mmap() は処理に失敗します。 MAP_FIXED が指定され
                       ている場合、 addr はページサイズの倍数である必要があり
                       ます。このオプションの使用はお勧めできません。

     MAP_HASSEMAPHORE  領域にセマフォが含まれている可能性があること、特殊な処
                       理が必要な可能性があることをカーネルに通知します。

     MAP_NOCORE        領域はコアファイルに含まれません。

     MAP_NOSYNC        はこの VM マップを経由して汚されたデータを、無闇にでは
                       りませんが、いくつかのプラットフォームではデフォルトで
                       同じ動作をするように実装されているかも知れません。

                       警告!  ftruncate(2) を使いファイルを拡張してから、つま
                       りファイルに大きな穴を空けてから、その穴を共有 mmap()
                       を修正して埋める場合、深刻なファイル断片化が生じる可能
                       性があります。この断片化を避けるために、 mmap() でその
                       領域を修正する前に、新規に拡張した領域に 0 を write()
                       して、ファイルのバッキングストアを事前に割り当てておく
                       必要があります。ディスクへのフラッシュが全くランダムに
                       生じるため、断片化問題に特に敏感なのは、 MAP_NOSYNC ペ
                       ージです。

                       同じことが、 MAP_NOSYNC を使いファイルベースの共有メモ
                       リストアを実装する場合にもいえます。 ftruncate() して
                       バッキングストアを作るのではなく、0 を write() してバッ
                       キングストアを作ることを推奨します。たとえば、 ``dd
                       if=filename of=/dev/null bs=32k'' を使うなどして巨大な
                       ファイルをシーケンシャルに読み込みながら、 ``iostat 1''
                       を呼び出すことで得られる KB/t (転送 1 回あたりのキロバ
                       イト数) を観察することでファイル断片化のテストが可能で
                       す。

                       fsync(2) 関数はすべての汚染されたデータとファイルに関連
                       づけられたメタデータ (NOSYNC の汚れた VM データを含む)
                       を物理的媒体にフラッシュします。 sync(8) コマンドと
                       sync(2) システムコールは、汚染された NOSYNC VM のデータ
                       を通常フラッシュしません。 msync(2) システムコールは
                       BSD で整合性のあるファイルシステムのバッファキャッシュ
                       が実装されたので廃止されました。しかしながら、汚れた VM
                       ページとファイルシステムを結びつけ、物理的媒体にすぐに(
                       後程ではなく)フラッシュさせる用途に使われることもありま
                       す。

     MAP_PRIVATE       修正はプロセス固有に行なわれます。

     MAP_SHARED        修正は共有されます。

     MAP_STACK         このオプションが利用できるのは、システムのカーネルをコ
                       ンパイルするときに VM_STACK を定義してコンパイルした場
                       合だけです。これは i386 についてだけデフォルトです。他
                       のアーキテクチャでこのオプションを有効にしたい場合は、
                       /etc/make.conf 内で -DVM_STACK を COPTFLAGS に追加する
                       方法を検討してください。 MAP_STACK は MAP_ANON および 0
                       の offset 指定を含みます。 fd は -1 でなければならず、
                       prot には少なくとも PROT_READ と PROT_WRITE が入ってい
                       る必要があります。このオプションは、スタックの先頭を開
                       始点とし下方に伸びる、サイズが最大で len バイトまで伸び
                       るメモリ領域を作成します。スタックの先頭は、呼び出しか
                       ら返された開始アドレスに len バイトを加えたものになりま
                       す。最も伸びた場合のスタックの下端は、呼び出しによって
                       返される開始アドレスになります。

     mmap() は次の場合に失敗します。

     [EACCES]           フラグ PROT_READ が prot パラメータの一部として指定さ
                        れましたが、 fd が読取り用に開かれていませんでした。フ
                        ラグ MAP_SHARED と PROT_WRITE が flagsprot パラメ
                        ータの一部として指定されましたが、 fd は書込み用に開か
                        れていませんでした。

     [EBADF]            fd が有効な開かれたファイルの記述子ではありません。

     [EINVAL]           MAP_FIXED が指定されて addr パラメータがページ境界に整
                        列されていないか、または指定のアドレスの一部がユーザプ
                        ロセスの有効なアドレス空間の外になります。

     [EINVAL]           len が負でした。

     [EINVAL]           MAP_ANON が指定されて fd パラメータが -1 ではありませ
                        んでした。

     [EINVAL]           MAP_ANON が指定されておらず、 fd が通常のファイルまた
                        はキャラクタ型特殊ファイルを参照していませんでした。

     [EINVAL]           offset がページ境界に整列していませんでした (後述する
                        「 バグの章」を参照)。

     [ENOMEM]           MAP_FIXED が指定されて addr パラメータが与えられない、
                        もしくは sysctl 値 vm.nax_proc_mmap で指定されたプロセ
                        ス毎の mmap 限界に達しました。 MAP_ANON が指定されて利
                        用できるメモリが不充分でした。


関連項目

     madvise(2), mincore(2), mlock(2), mprotect(2), msync(2), munlock(2),
     munmap(2), getpagesize(3)


バグ

     len は 2GB に限定されます。2GB をわずかに上回るマッピングは機能しません
     が、 2GB, 4GB, 6GB, および 8GB よりわずかに少ないファイルサイズについて (
     ファイルサイズ % 2GB) のサイズのウィンドウをマップできます。

     制約は多彩な理由から生じています。そのほとんどは、パフォーマンス上の著し
     いペナルティのため、 FreeBSD では VM システム内で 64 ビットのオフセットを
     使用したくないことと関係しています。したがって FreeBSD は 32 ビットのペー
     ジインデックスを使用しており、これによって FreeBSD では最高で 8TB までの
     ファイルサイズを利用できます。実際にはさらに制約が課されて使用可能サイズ
     は 1TB までですが、これは、ファイルシステムコード内のバグによるものです (
     ブロック番号計算を行なっているときの桁落ち)。

     2GB 制限のもうひとつの理由は、ファイルシステムメタデータが負のオフセット
     に存在できるということです。

     現在われわれはページ境界に整列したファイルオフセットのみを処理できます。


ABELNET VPSサービス