MMAP(2) FreeBSD システムコールマニュアル MMAP(2)
名称
mmap − メモリの割り当て、またはファイルまたはデバイスのメモリへのマップ |
ライブラリ
標準 C ライブラリ (libc, −lc) |
書式
#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
ページはアクセスできません。 flags 引数は、マップされたオブジェクトのタイプ、マッピングオプション、お よびマップされたページのコピーに対して行われた修正が、プロセスに固有であ るかまたは他からの参照と共有されるかを指定します。共有、マッピングタイ プ、およびオプションは、以下の値の論理和 (or) を取った値で flags 引数に指 定します: MAP_ANON MAP_FIXED MAP_HASSEMAPHORE MAP_INHERIT MAP_NOCORE MAP_NOSYNC 警告! 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 close(2) システムコールはページをアンマップしません。詳細については munmap(2) を参照してください。 現在の設計ではプロセスはスワップ空間の位置を指定できません。将来は、追加 のマッピングタイプ MAP_SWAP を定義するかもしれません。この場合、ファイル 記述子引数にはスワップを行うべきファイルまたはデバイスを指定します。 戻り値 |
正常に完了すると、 mmap() は、マップされた領域を指すポインタを返します。 そうでない場合は値 MAP_FAILED が返され、エラーを示すために errno が設定さ れます。 |
エラー
mmap() システムコールは次の場合に失敗します: |
[EACCES]
フラグ PROT_READ が prot 引数の一部として指定されまし たが、 fd が読取り用に開かれていませんでした。フラグ MAP_SHARED と PROT_WRITE が flags と prot 引数の一部と して指定されましたが、 fd は書込み用に開かれていません でした。 [EBADF] [EINVAL] [EINVAL] [EINVAL] [EINVAL] [EINVAL] [ENOMEM] 関連項目 |
madvise(2), mincore(2), minherit(2), mlock(2), mprotect(2), msync(2), munlock(2), munmap(2), getpagesize(3), make.conf(5) |
バグ
len 引数は 2GB に限定されます。 2GB をわずかに上回るマッピングは機能しま せんが、 2GB, 4GB, 6GB および 8GB よりわずかに少ないファイルサイズについ て (ファイルサイズ % 2GB) のサイズのウィンドウをマップできます。 制約は多彩な理由から生じています。そのほとんどは、パフォーマンス上の著し いペナルティのため、 FreeBSD では VM システム内で 64 ビットのオフセットを 使用したくないことと関係しています。したがって FreeBSD は 32 ビットのペー ジインデックスを使用しており、これによって FreeBSD では最高で 8TB までの ファイルサイズを利用できます。実際にはさらに制約が課されて使用可能サイズ は 1TB までですが、これは、ファイルシステムコード内のバグによるものです ( ブロック番号計算を行っているときの桁落ち)。 2GB 制限のもうひとつの理由は、ファイルシステムメタデータが負のオフセット に存在できるということです。 0 バイトを mmap() しようとしても何の効果もなく、単に成功します。一方、0 バイトを munmap() しようとすると [EINVAL] が返されることに注意してくださ い。 FreeBSD 10.0 November 17, 2001 FreeBSD 10.0 |