仮想記憶機能は、いくつかの関数の組み合わせによって使用し、制御します。この節は、これらの呼び出しを要約して説明し、それらの使用例を示します。
mmap(2) は、プロセスのアドレス空間への名前付きファイルシステムオブジェクト (またはその一部) のマッピングを確立します。これは、基本的なメモリ管理機能で、非常に簡単です。まず、ファイルを open(2) し、次に適当なアクセスオプションと共用オプションで mmap(2) し、後は必要な作業を行います。
mmap(2) によって確立されるマッピングは、指定されたアドレス範囲の以前のマッピングを置き換えます。
MAP_SHARED および MAP_PRIVATE フラグは、マッピングのタイプを指定します。いずれか 1 つを指定しなければなりません。MAP_SHARED を指定すると、書き込みがマッピングされているオブジェクトを修正します。変更を有効にするための追加操作は必要ありません。MAP_PRIVATE を指定すると、マッピングされている領域への最初の書き込みでページのコピーが作成され、すべての書き込みはそのコピーを参照します。実際に修正されたページだけがコピーされます。
マッピングのタイプは、fork(2) を実行した場合も保持されます。
mmap(2) 呼び出しに使用するファイル記述子は、マッピングが確立した後は開いたままにする必要はありません。ファイル記述子を閉じても、マッピングが munmap(2) によって取り消されるまで、または新しいマッピングで置き換えられるまで、このマッピングは有効です。
切り捨ての呼び出しによってファイルが短くされて、マッピングがファイルの終わりを越えてしまった場合は、ファイルの存在しない領域にアクセスすると、SIGBUS シグナルが発生します。
/dev/zero をマッピングすると、mmap(2) で指定した大きさの仮想記憶のブロッキングに 0 を設定します。次のプログラムは、システムが選択したアドレスにスクラッチ記憶領域のブロッキングを作成する例を示しています。
int fd; caddr_t result; if ((fd = open("/dev/zero", O_RDWR)) == -1) return ((caddr_t)-1); result = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); (void) close(fd); |
デバイスまたはファイルは、マッピングによってアクセスした場合だけ役立つことがあります。この例としては、ビットマップ表示をサポートするフレームバッファデバイスがあります。この場合、表示管理アルゴリズムは、表示アドレスに直接ランダムアクセスできる場合に効率的に機能します。
munmap(2) は呼び出しプロセスから、指定したアドレス範囲内のページのすべてのマッピングを削除します。munmap(2) は、マッピングされたオブジェクトには影響しません。
SunOS 5.0 から 5.8 の仮想記憶システムは、プロセッサのメモリがファイルシステムのオブジェクトからのデータをバッファリングするキャッシュシステムです。キャッシュの状態を制御または照会するためのインタフェースがあります。
mincore(2) は、メモリページが指定された範囲のマッピングの対象となるアドレス空間にあるかどうか調べます。mincore(2) がチェックした後でも、データを戻すまでの間にページの状態が変わる可能性があるため、戻された情報は古くなっていることがあります。ロッキングされたページだけが、メモリに残っていることが保証されます。
mlock(3C) は、指定されたアドレス範囲にあるページを物理メモリでロッキングします。(このプロセスまたは他のプロセスで) ロッキングされたページを参照しても、入出力操作を必要とするページフォルトが生じることはありません。この操作は物理資源を拘束し、通常のシステム操作を破壊する可能性があるため、mlock(3C) を使用できるのはスーパーユーザだけに制限されています。設定に依存するページ制限だけがメモリ内にロッキングされます。この制限を越えると、mlock(3C) 呼び出しは失敗します。
munlock(3C) は、物理ページのロッキングを解放します。1 つのマッピングのアドレス範囲で複数の mlock(3C) 呼び出しを行なっている場合も、1 回の munlock(3C) 呼び出しだけでロッキングが解放されます。ただし、同じページの異なったマッピングが mlock(3C) で処理されている場合は、すべてのマッピングへのロッキングが解放されるまでページのロッキングは解除されません。
ロッキングは、マッピングが mmap(2) 操作で置き換えられるか、munmap(2) で削除された場合にも解放されます。
MAP_PRIVATE マッピングに伴う「書き込み時コピー」イベントの際に、ロッキングはページ間を移転されるため、MAP_PRIVATE マッピングを含むアドレス範囲のロッキングは、「書き込み時コピー」のリダイレクトに合わせて透過的に保持されます (リダイレクトについては、前出の mmap(2) を参照してください)。
mlockall(3C) と munlockall(3C) は、mlock(3C) と munlock(3C) に似ていますが、アドレス空間全体を操作します。mlockall(3C) はアドレス空間にあるすべてのページにロッキングを設定し、munlockall(3C) は mlock(3C) と mlockall(3C) のどちらで設定されたかに関係なく、アドレス範囲にあるすべてのページのロッキングを解除します。
msync(3C) は、指定されたアドレス範囲にある修正されたすべてのページを、そのアドレスによってマッピングされているオブジェクトにフラッシュします。これは、ファイルに対する fsync(3C) 操作と同様です。
sysconf(3C) は、システムに依存するメモリページの大きさを戻します。移植性を保つため、アプリケーションにページの大きさを指定する定数を組み込まないでください。同じ命令セットの実装においてもページの大きさが異なることは珍しくありません。
mprotect(2) は、指定されたアドレス範囲にあるすべてのページに指定された保護を割り当てます。割り当てられた保護は、対象となるオブジェクトに認められている権限を越えることはできません。
brk(2) と sbrk(2) は、記憶領域をプロセスのデータセグメントに追加するために呼び出されます。
プロセスは brk(2) と sbrk(2) を呼び出して、この領域を操作できます。
caddr_t brk(caddr_t addr); caddr_t sbrk(intptr_t incr); |
brk(2) は、呼び出し側によって使用されていない最小値のデータセグメント位置を addr に設定します (システムのページサイズの最小倍数に丸められます)。
代替関数である sbrk(2) は、incr バイトを呼び出し側のデータ空間に追加し、新しいデータ領域の開始位置へのポインタを戻します。