mmap() - メモリーのページのマップ

標準

標準/拡張機能 C/C++ 依存項目

XPG4.2
Single UNIX Specification、バージョン 3
z/OS®UNIX

両方  

形式

#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/mman.h>

void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);

機能説明

mmap() 関数は、プロセスのアドレス・スペース (len バイト) と、オフセット offlen バイトのファイル記述子 fildes に関連したファイルとの間のマッピングを確立します。呼び出しの形式は以下のとおりです。

pa=mmap(addr, len, prot, flags, fildes, off); 

pa の値は、次で詳しく 説明する addr 引数と flags の値を使う 未指定関数です。mmap() 呼び出しが正常に実行されると、その結果 として pa が戻されます。[pa, pa + len] と [off, off + len] でとられる アドレス範囲は、プロセスの可能なアドレス・スペースおよびファイルの 可能なアドレス・スペース (必ずしも現行のアドレス・スペースとは限らない) にそれぞれ 適したものでなければなりません。

mmap() の呼び出し後にマップ・ファイルのサイズが 変更されると、ファイルの追加部分または削除部分に対応する マップ領域部分の参照結果は未指定となります。

prot 引数は、読み取り、書き込み、実行、またはこれらのアクセスの組み合わせが、マップ中のページに許可されるかどうかを判別します。保護オプションは、次のように <sys/mman.h> 形式で定義されます。
PROT_READ
ページを読み取ることができる。
PROT_WRITE
ページに書き込むことができる。
PROT_EXEC
ページを実行することができる。
PROT_NONE
ページにアクセスすることができる。

インプリメンテーションではアクセス許可のすべての 組み合わせを実施する必要はありません。ただし、書き込みは PROT_WRITE が 設定されている場合にだけ許可されるようにします。

flags 引数は、マップ・ページの処理に関するその他の情報を提供します。オプションは、次のように <sys/mman.h> 形式で定義されます。
MAP_SHARED
変更の共用。
MAP_PRIVATE
変更は専用。
MAP_FIXED
addr を正確に解釈。
__MAP_MEGA
メガバイト増分でのマップ。

MAP_PRIVATE フラグと MAP_SHARED フラグは、メモリー領域への書き込み参照の可視性を制御します。これらのフラグの 1 つを正確に指定する必要があります。マッピング型は、fork にわたって保存されます。

MAP_SHARED が flags で設定されている場合、呼び出しプロセスによるメモリー領域への書き込み参照は、ファイルを変更することができ、任意のプロセスによるファイルの同一部分のすべての MAP_SHARED マッピング で可視になります。

MAP_PRIVATE が flags で設定されている場合、呼び出しプロセスによるメモリー領域への書き込み参照は、ファイルを変更しません。また、ファイルの同一部分の ほかのマッピングのいずれのプロセスに対して 可視にもなりません。

MAP_SHARED を使ってメモリー領域をマップしたプロセス によって加えられたマップ・データのすべての変更内容は、共有されます。また、同一のファイル・オフセット範囲をマップした ほかのプロセスに対して可視になります。

MAP_FIXED が flags 引数に指定されている場合、インプリメンテーションは、pa の値が正確に addr でなければならないということが通知されます。MAP_FIXED が設定されている場合、mmap() は (void*)-1 を戻し、errno に EINVAL を設定することがあります。MAP_FIXED 要求が正常に実行された場合、mmap() で確立されたマッピングは、[pa, pa + len] の範囲のプロセスのページ用の直前のマッピングを置き換えます。

MAP_FIXED が設定されていない場合、インプリメンテーション は未指定方式で addr を使用し pa に 到達します。そのように選ばれた pa は、インプリメンテーション でファイルへの len バイトのマッピングが 適切であると考えるアドレス・スペースのエリアになります。すべてのインプリメンテーションでは、次の制約に 従って、0 の値の addr を、pa の自由な 選択を完了するインプリメンテーションを認めるものとして 解釈します。ゼロ以外の値の addr は、マッピングの行われる 近くのプロセス・アドレスの示唆と見なされます。インプリメンテーションで pa 用に値を選択すると、アドレス 0 でマッピングを行うことも、現存する任意の マッピングの置き換えも、動的メモリー割り振りエリアへのマップも 行いません。

off 引数は、_SC_PAGESIZE または _SC_PAGE_SIZE が渡される場合、sysconf() が戻す値に従って位置合わせとサイズ変更が行われるという制約を受けます。MAP_FIXED が指定されている場合は、addr 引数も これらの制約を受けます。インプリメンテーションは、ページ全体にわたって マッピング命令を実行します。そのため、引数 len がサイズまたは位置合わせの制約を 満たす必要がなくても、インプリメンテーションで は [pa, pa + len] の範囲で 指定された任意の部分ページを (任意のマッピング命令で) インクルードします。

インプリメンテーションはメモリー領域の最後の 部分ページを常に 0 で充てんします。さらに、インプリメンテーションでは、ファイルの マップ部分の最後より後の、ファイルの最終ページの 変更部分に書き込むことはしません。mmap() により確立された マッピングがファイルの最終バイトを含むページ以降に 拡張する場合、最終ページより後ろのページへのマッピングにおける アプリケーション参照は、SIGBUS シグナルまたは SIGSEGV シグナルの 送達という結果になります。

mmap() 関数は、ファイル記述子 fildes に関連したファイルへのエクストラ参照を追加します。この参照は、このファイル記述子に関する後続の close() により除去されることはありません。この参照が取り除かれるのは、ファイルへのマッピングが なくなったときです。

マップ・ファイルの st_atime フィールドは、mmap() 呼び出しと、それに対応する munmap() 呼び出しの間で、いつでも更新のマークを付けることができます。マップ領域への初期の読み取り参照または書き込み参照により、ファイルの set_atime フィールドに更新のマークがまだ付いて いない場合に、更新のマークを付けることができます。

MAP_SHARED および PROT_WRITE を使ってマップされたファイルの st_ctime および st_mtime フィールドには、マップ領域への書き込み参照と、ファイルの該当部分に対する MS_ASYNC または MS_SYNC を使った、任意のプロセスによる次の msync() 呼び出しとの間の間隔の stime ポイントで、更新のマークが付けられます。そのような呼び出しがない場合、基礎ファイルが結果的に変更されていると、これらのフィールドには、書き込み参照後にいつでも更新のマークを付けることができます。

プロセスが終了する前に、メモリー・マップ領域がマップ解除されていない場合は、マップ領域内で変更されたデータは、プロセスの終了時に自動的にはディスクへ書き出されません。MAP_PRIVATE 領域にある変更された専用データは、廃棄されます。マップ領域が MAP_SHARED である場合は、変更されたデータは、引き続きキャッシュに存在し (同じファイル・ オフセット範囲が共用されている場合)、最終的には、別のプロセスで msync() を使ってディスクへ書き出すことができます。ただし、MAP_SHARED と同じファイル・オフセット範囲を共用するプロセスがほかにない 場合、その変更データは廃棄されます。

マップすることができるメモリー領域の数に関して、インプリメンテーションに依存した制限 (プロセスごと、またはシステムごと) のある場合があります。 そのような制限が課せられた場合、プロセスによってマップすることができるメモリー領域の数が、shmat() の使用で減るかどうかは、インプリメンテーションに依存します。

__MAP_MEGA オプションを指定すると、システムはファイルが メガバイト増分でマップされるようにストレージを割り振ります。この オプションはラージ・ファイルにだけ使用してください。 メガバイトの半分を超えるファイルならば、このオプションを使用することにより パフォーマンスの向上を期待することができます。このオプションを使用する場合、mmaps と munmaps は メガバイト境界のメガバイト範囲にあります。

__MAP_MEGA を指定すると、マップされたデータへの変更はすべて 共用されます。マップされたデータへの変更内容は、同じファイル・オフセット範囲をマップする他のすべてのプロセスで可視になります。つまり、__MAP_MEGA の動作は MAP_SHARED に似ています。__MAP_MEGA は、MAP_PRIVATE および MAP_SHARED と両立しません。 MAP_PRIVATE または MAP_SHARED を __MAP_MEGA と同時に指定すると、__MAP_MEGA は失敗し、errno に EINVAL が設定されます。

__MAP_MEGA オプションは MAP_FIXED と共に指定されることがあります。

map_address パラメーター: マップ・アドレスが ゼロでなく、さらに __MAP_MEGA が指定されている場合、MAP_FIXED 以外の要求が 出されると、カーネルにより map_address でマッピングが作成され、最も近いメガバイト境界に切り捨てられます。これが正常に実行されない場合、カーネルは map_address ゼロが指定されたかのように動作します。MAP_FIXED 要求の場合は、map_address の値は セグメント・サイズの倍数 (メガバイト倍数) でなければなりません。 そうでない場合は、mmap 要求は失敗し、errno に EINVAL が 設定されます。

map_length パラメーター: __MAP_MEGA を 指定すると、マッピング操作がセグメント全体 (メガバイト・チャンク) で 実行されます。長さがセグメント・サイズの倍数でない場合は、最後のセグメントの後書き部分全体もユーザー・ストレージにマップされます。

ファイル記述子: ファイル記述子は マップされるファイルを識別します。既にマップされているファイルを マップしようとするとき、そのファイルが既に __MAP_MEGA の別の仕様で マップされていた場合は、現在のマップ要求は失敗し、errno に EINVAL-MMapTypeMismatch が設定されます。つまり、ある時点であるファイルを __MAP_MEGA オプション付きで マップすることができ、__MAP_MEGA オプションなしでマップすることも できますが、両方を同時に行うことはできません。

__MAP_MEGA マッピングの場合、指定ファイル記述子で表されるファイルへの最初のマップであれば、ファイルが読み取り用にオープンされていたか 書き込み用にオープンされていたかに応じて、この mmap または将来の mmap および mprotects によりファイルに指定される保護オプション、あるいはこのプロセスまたは同じファイルをマップする他のプロセスで 指定する保護オプションが決定されます。ファイルが 書き込み用ではなく読み取り用にオープンされていた場合は、PROT_READ、PROT_EXEC、または PROT_NONE だけが許可されます。 ファイルが書き込み用にオープンされていた場合は、すべての保護オプションが許可されます。通常のファイルのみマップできます。 NFS あるいは DFS を介してアクセスされるリモート・ファイルはマップできないことにも注意し てください。

Protect_options: Protect_options の指定は、__MAP_MEGA オプションを指定してファイルをマップする場合にグローバルな 効果を持ちます。指定された Protect_option は、現在同じファイル・オフセット範囲にマップされているすべてのプロセスに対して 直ちに有効になります。

z/OS UNIX の大規模ファイルのサポート: AMODE 64 C/C++ アプリケーションの場合は、z/OS UNIX の大規模ファイルが自動的にサポートされます。AMODE 31 C/C++ アプリケーションは、オプション LANGLVL(LONGLONG) を指定してコンパイルされなければなりません。また、ヘッダーがインクルードされる前に _LARGE_FILES フィーチャー・テスト・マクロを定義して、2 GB のサイズより大きい z/OS UNIX ファイルをこの関数が操作できるようにしなければなりません。ファイル・サイズとオフセット・フィールドは、63 ビットの幅に拡張されます。したがって、_LARGE_FILES フィーチャー・テスト・マクロの定義も行うには、ファイルを操作する他のいずれかの関数が必要です。

使用上の注意

  1. mmap() 関数は、共用メモリー・オブジェクトも型付きメモリー・オブジェクトもサポートしません。

戻り値

正常に実行された場合、mmap() は、マッピングの行われたアドレスを戻します。

正常に実行されなかった場合、mmap() は MAP_FAILED を戻して、errno を次のいずれかの値に設定します。
エラー・コード
説明
EACCES
指定された保護にかかわらず、fildes 引数が読み取り用にオープンされていません。あるいは、PROT_WRITE が MAP_SHARED 型マッピングで 指定されましたが、fildes が書き込み用にオープンされていません。
EBADF
fildes 引数は、有効なオープン・ファイル記述子では ありません。
EINVAL
addr 引数 (MAP_FIXED が指定された場合) または off が、sysconf() で戻されたページ・サイズの倍数になっていません。あるいは、これらがインプリメンテーションで無効と考えられています。

flags の値が 無効 (MAP_PRIVATE も MAP_SHARED も設定されていません) です。

EMFILE
マップ領域の数がインプリメンテーションに依存した 制限 (プロセスごと、またはシステムごと) を超えてしまいます。
ENODEV
fildes 引数が、mmap() でサポートされない型 のファイルを示しています。
ENOMEM
MAP_FIXED が指定された場合、[addr, addr + range [addr, addr + len], rounding len] の範囲がプロセスのアドレス・スペースに 許可されたものを超えています。あるいは、MAP_FIXED が 指定されなかった場合、アドレス・スペースに、マッピングを行うための十分なスペースがありません。
ENXIO
[off, off + len] の範囲の アドレスが fildes には無効です。
EOVERFLOW
ファイルは通常ファイルであり、off プラス len の値はオープン・ファイルで設定されたオフセットの最大値を超えます。
注: z/OS V1.9 以降、 環境変数 _EDC_EOVERFLOW は、z/OS UNIX ファイルの EOVERFLOW 条件の検出に関する mmap() の動作を制御するために使用できます。デフォルトでは、 フィールドに関連した最大オフセットを超えた場合、mmap() は EOVERFLOW を設定しません。_EDC_EOVERFLOW が YES に設定された場合、mmap() は オーバーフロー条件を確認します。

関連情報