スポンサーリンク

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

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

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

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

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

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

MAP_INHERIT
このフラグは正式に公表されたものとして扱われたことはな く、もはやサポートされていません。さらなる情報は minherit(2) を参照してください。

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

MAP_NOSYNC
はこの VM マップを経由して汚されたデータを、無闇にでは なく (通常はページャによって) 必要な時のみ物理的なメ ディアにフラッシュするようにします。普通、このオプショ ンにより、更新デーモンはこのマップで汚されたページをフ ラッシュしないようになります。これにより、ファイルバッ クアップされた共有メモリのマッピングを使用して無関係な プロセスの間でメモリアクセスを効率的に共有することがで きるようになります。このオプションがないと、汚された VM ページは頻繁 (通常 30-60 秒毎) にディスクにフラッシュさ れるかも知れず、そのような動作を必要としない場合 (例え ば IPC のためにファイルを用いた共有 mmap 領域を用いてい る場合) パフォーマンスに問題が出ることがあります。 MAP_NOSYNC を使っているかにかかわらず、 VM/ ファイルシ ステムの一貫性は保たれることに注意してください。このオ プションは UNIX プラットフォーム間で (まだ) 移植性はあ りませんが、いくつかのプラットフォームではデフォルトで 同じ動作をするように実装されているかも知れません。

警告! 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
MAP_STACK は MAP_ANON および 0 の offset 指定を含みま す。 fd 引数は -1 でなければならず、 prot には少なくと も PROT_READ と PROT_WRITE が入っている必要があります。 このオプションは、スタックの先頭を開始点とし下方に伸び る、サイズが最大で len バイトまで伸びるメモリ領域を作成 します。スタックの先頭は、呼び出しから返された開始アド レスに len バイトを加えたものになります。最も伸びた場合 のスタックの下端は、呼び出しによって返される開始アドレ スになります。

close(2) システムコールはページをアンマップしません。詳細については munmap(2) を参照してください。

現在の設計ではプロセスはスワップ空間の位置を指定できません。将来は、追加 のマッピングタイプ MAP_SWAP を定義するかもしれません。この場合、ファイル 記述子引数にはスワップを行うべきファイルまたはデバイスを指定します。

戻り値

正常に完了すると、 mmap() は、マップされた領域を指すポインタを返します。 そうでない場合は値 MAP_FAILED が返され、エラーを示すために errno が設定さ れます。

エラー

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 引数が与えられて いません。 MAP_ANON が指定されて利用できるメモリが不充 分でした。 sysctl 値 vm.nax_proc_mmap で指定されたプロ セス毎の mmap 限界に達しました。

関連項目

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

スポンサーリンク