Open Source Web Development Tutorials - Dev Shed
LinuxのMMAPシステムコール
(2009/03/17公開)
ページサイズ
ページとは、個別の許可や動作の対象となりうるメモリの最小単位です。したがって、ページがメモリマッピングを構成するブロックであり、メモリマッピングがプロセスのアドレス空間を構成するブロックです。
mmap()システムコールはページ上で動作します。addrパラメータおよびoffsetパラメータは、共に、ページサイズの境界に合っている必要があります。すなわち、これらのパラメータはページサイズの整数の倍数でなくてはなりません。
つまり、マッピングはページの整数の倍数です。コールで指示したlenパラメータがページ境界に合っていない場合-おそらく、基底ファイルサイズがページサイズの倍数ではない-、マッピングは次の全ページに切り上げられます。有効な最後のバイトからマッピングの最後まで付加されるメモリのバイトは、ゼロで埋められます。この領域からの読み出しは、ゼロを返します。このメモリへの書き込みは、マッピングがMAP_SHAREDと指示されている場合でもファイルに影響を及ぼすことはなく、元のlenバイトだけがファイルに書き戻されます。
sysconf()
ページサイズの取得には、sysconf()を利用するのがPOSIXの標準的な方法です。sysconf()は、システム固有のさまざまな情報を読み出します。
#include <unistd.h>
long sysconf (int name);
sysconf()のコールは、コンフィグレーションアイテムnameの値を戻します。無効の場合は、-1を戻します。エラーの場合は、errnoがEINVALとなります。アイテムによっては-1が有効値の場合がありますから(例えばlimitsでは、-1が無制限を意味します)、呼び出す前にerrnoをクリアし、その後値を確認するほうが賢明です。
POSIXでは、_SC_PAGESIZE(および、同義語である_SC_PAGE_SIZE)がバイト数で定義されるページサイズです。したがって、以下のとおり、ページサイズを簡単に入手できます。
long page_size = sysconf (_SC_PAGESIZE);
getpagesize(). Linuxには、getpagesize()関数もあります。
#include <unistd.h>
int getpagesize (void);
以下のgetpagesize()のコールでも、同様に、ページサイズはバイト数で戻されます。sysconf()よりもっと簡単です。
int page_size = getpagesize ();
この関数はすべてのUnixシステムにサポートされているわけではありません。POSIX 標準1003.1-2001改訂版からは省略されています。ここでは、情報の完全を期す意味で、一応紹介しておきました。
PAGE_SIZE
ページサイズは、マクロPAGE_SIZEにも静的に格納されています。マクロPAGE_SIZEは
int page_size = PAGE_SIZE;
ただし、前の2つの方法と異なり、3番目の方法は実行時ではなくコンパイル時のシステムのページサイズを取得します。アーキテクチャによっては、ページサイズの異なる複数のマシンをサポートします。マシンのタイプによっては、複数のページサイズをサポートするものさえあります!アーキテクチャが共通している場合、1つのバイナリをあらゆるタイプのマシンで実行できなくてはなりません。つまり、一度構築すれば、それをどこでも実行できる必要があります。ページサイズをハード・コーディングすると、この可能性が失われてしまいます。したがって、ページサイズは実行時に特定すべきです。通常、addrとoffsetはゼロですから、さほど難しいことではありません。
さらに、将来のカーネル・バージョンは、このマクロをユーザーにエクスポートしないと予想されます。Unixコードでは頻繁に登場するのでこの章で取り上げましたが、皆さんのプログラムでは使わないようにしましょう。sysconf()を利用するのがベストです。
Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.








