2011-07-04 13 views
6

以下は、hugepagesを使用してubuntuでファイルをmmapingするためのコードですが、この呼び出しは "invalid argument"というエラーで失敗しています。しかし、mmapのファイル記述子パラメータなしで MAP_ANONフラグを渡すと、動作します。私はこの背後にある理由を理解できません。Ubuntu 10.04、MAP_SHAREDでMAP_HUGETLBを使用したときにエラーが発生しました

第2に、このフラグ自体が変更がファイルに書き戻されないことを意味する場合、MAP_PRIVATEでファイルのmmapingが許可される理由を理解できません。これはいつもMAP_ANONを使って達成することができますか?それとも何か不足していますか?

誰かが私を助けることができますか?

int32_t main(int32_t argc, char** argv) { 
int32_t map_length = 16*1024*1024; // 16 MB , huge page size is 2 MB 
int32_t protection = PROT_READ | PROT_WRITE; 
int32_t flags = MAP_SHARED | MAP_HUGETLB; 
int32_t file__ = open("test",O_RDWR|O_CREAT | O_LARGEFILE,s_IRWXU | S_IRGRP | S_IROTH); 
if(file__ < 0) { 
    std::cerr << "Unable to open file\n"; 
    return -1; 
} 

if (ftruncate(file__, map_length) < 0) { 
    std::cerr 
    << "main :: unable to truncate the file\n" 
    << "main :: " << strerror(errno) << "\n" 
    << "main :: error number is " << errno << "\n"; 
    return -1; 
} 
void *addr= mmap(NULL, map_length, protection, flags, file__, 0); 
if (addr == MAP_FAILED) { 
    perror("mmap"); 
    return -1; 
} 
const char* msg = "Hello World\n"; 
int32_t len = strlen(msg); 
memcpy(addr,msg,len); 
munmap(addr, map_length); 
close(file__); 
return 0; 
} 
+0

'int32_t main'はエラーです。 C++標準では、 'main'の戻り値の型と' argc'の型はどちらも 'int'でなければなりません。 –

+0

larsmans、それはプログラムの出力に影響しますか?私のアーキテクチャでは、intはint32_tと同じですので、まったく問題ではありません。しかし、標準的な観点からは、それは正しくない、私は同意する。 (以前、私はこのコメントを書いて何らかの誤りを犯しました) – Faraz

+0

Faraz:いいえ、彼はちょうどニックピッキングしていました。 – BjoernD

答えて

4

mmap()を使用すると、匿名メモリとファイルの2種類のマッピングが得られます。

匿名メモリは、(マニュアルページに記載されているように)ファイルシステムのどのファイルにもバックアップされていません。その代わりに、mmap()へのMAP_ANON呼び出しから返されるメモリは、単純なシステムメモリです。このインタフェースの主なユーザは、malloc/freeのバッキングストレージを取得するために使用するCライブラリです。したがって、MAP_ANONを使用すると、ファイルをマップしたくないということが明示的に示されます。

ファイルのメモリファイルのブレンドの種類(またはその一部)をアプリケーションのアドレス空間に組み込みます。この場合、メモリコンテンツは実際にはファイルのコンテンツによってバックアップされます。 MAP_PRIVATEフラグは、最初にファイルのメモリを割り当ててからこのメモリにコンテンツをコピーするものと考えてください。実際には、これはカーネルがやっていることではありませんが、ちょうどふりをしましょう。

HUGE_TLBは、カーネルが匿名メモリを提供する機能です(mmap()のマニュアルページで参照されているDocumentation/vm/hugetlb-page.txtを参照)。これは、ファイルに対してHUGETLBを使用しているときにmmap()呼び出しが失敗する理由です。 *編集:完全には正しくありません。巨大なページをサポートするRAMファイルシステム(hugetlbfs)があります。ただし、huge_tlbのマッピングは、ドキュメントを理解しているので、任意のファイルでは機能しません。*

HUGE_TLBおよび対応するメモリ内ファイルシステム(hugetlbfs)の使用方法の詳細については、次の記事LWN上:

+0

mmapがエラー "無効な引数"で失敗していると書いています。strerno(22)を実行したときに取得する文字列です。 – Faraz

+1

このクエリを書く前にすべてのドキュメントを調べました。私は "MAP_HUGETLBはMAP_ANONでしか動作しません"と似たようなものを読んでうれしく思います。第2に、hugetlbfsをマウントした後、我々は膨大なページを持つファイルバックアップmmapを(このfs上で)行うことができます。実際にMAP_HUGETLBがファイルバックアップmmapでサポートされていない場合、そのファイルシステムでmmpファイルをバックアップするためにhugepagesをどのように使用できますか?行方不明のものがなければならない、そうですか? – Faraz

+0

私の答えを編集しました。 – BjoernD

0

MAPPRIVATEをフラグに追加すると、この問題が解決されます。

+0

mmapページには、MAP_SHAREDまたはMAP_PRIVATEのいずれか一方のみを指定でき、両方を指定することはできません。 http://man7.org/linux/man-pages/man2/mmap.2.html –

関連する問題