diff options
author | dwight <dwight@10gen.com> | 2011-02-21 10:48:28 -0500 |
---|---|---|
committer | dwight <dwight@10gen.com> | 2011-02-21 10:48:28 -0500 |
commit | af363697167c103374d7534b1af4b92f6eb3270c (patch) | |
tree | 4f6089113657c4a08d34608bc0fcb97a333549b9 | |
parent | 7e13092c2f41ce844c3671cd39cf96afd8e62a90 (diff) | |
download | mongo-af363697167c103374d7534b1af4b92f6eb3270c.tar.gz |
SERVER-2500 windows - eliminate mapaligned
-rw-r--r-- | db/mongommf.cpp | 48 | ||||
-rw-r--r-- | db/mongommf.h | 2 | ||||
-rw-r--r-- | util/mmap.h | 4 | ||||
-rw-r--r-- | util/mmap_win.cpp | 4 |
4 files changed, 52 insertions, 6 deletions
diff --git a/db/mongommf.cpp b/db/mongommf.cpp index 20b45247670..46724c0ff1f 100644 --- a/db/mongommf.cpp +++ b/db/mongommf.cpp @@ -37,6 +37,48 @@ namespace mongo { __declspec(noinline) void makeChunkWritable(size_t chunkno) {
scoped_lock lk(mapViewMutex); + if( writable.get(chunkno) ) // double check lock
+ return;
+
+ // remap all maps in this chunk. common case is a single map, but could have more than one with smallfiles or .ns files
+ size_t chunkStart = chunkno * MemoryMappedFile::ChunkSize;
+ size_t chunkNext = chunkStart + MemoryMappedFile::ChunkSize;
+
+ scoped_lock lk2(privateViews._mutex());
+ map<void*,MongoMMF*>::iterator i = privateViews.finditer_inlock((void*) (chunkNext-1));
+ while( 1 ) {
+ const pair<void*,MongoMMF*> x = *(--i); + MongoMMF *mmf = x.second; + if( mmf == 0 ) + break; + + size_t viewStart = (size_t) x.first; + size_t viewEnd = viewStart + mmf->length(); + if( viewEnd <= chunkStart ) + break; + + size_t protectStart = max(viewStart, chunkStart); + dassert(protectStart<chunkNext); + + size_t protectEnd = min(viewEnd, chunkNext); + size_t protectSize = protectEnd - protectStart;
+ dassert(protectSize>0&&protectSize<=MemoryMappedFile::ChunkSize);
+
+ DWORD old;
+ bool ok = VirtualProtect((void*)protectStart, protectSize, PAGE_WRITECOPY, &old);
+ if( !ok ) {
+ DWORD e = GetLastError();
+ log() << "VirtualProtect failed " << chunkno << hex << protectStart << ' ' << protectSize << ' ' << errnoWithDescription(e) << endl;
+ assert(false);
+ }
+ }
+
+ writable.set(chunkno);
+ }
+
+ __declspec(noinline) void makeChunkWritableOld(size_t chunkno) {
+ scoped_lock lk(mapViewMutex); +
if( writable.get(chunkno) )
return;
@@ -118,12 +160,14 @@ namespace mongo { void* MemoryMappedFile::createPrivateMap() { assert( maphandle ); scoped_lock lk(mapViewMutex); - void *p = mapaligned(maphandle, len); + //void *p = mapaligned(maphandle, len); + void *p = MapViewOfFile(maphandle, FILE_MAP_READ, 0, 0, 0); if ( p == 0 ) { DWORD e = GetLastError(); log() << "createPrivateMap failed " << filename() << " " << errnoWithDescription(e) << endl; } else { + clearWritableBits(p); views.push_back(p); } return p; @@ -135,7 +179,7 @@ namespace mongo { scoped_lock lk(mapViewMutex); - unmapped(oldPrivateAddr); + clearWritableBits(oldPrivateAddr); if( !UnmapViewOfFile(oldPrivateAddr) ) { DWORD e = GetLastError(); diff --git a/db/mongommf.h b/db/mongommf.h index f7716735cd9..7061903512f 100644 --- a/db/mongommf.h +++ b/db/mongommf.h @@ -128,6 +128,8 @@ namespace mongo { mutex& _mutex() { return _m; } MongoMMF* find_inlock(void *p, /*out*/ size_t& ofs); + map<void*,MongoMMF*>::iterator PointerToMMF::finditer_inlock(void *p) { return _views.upper_bound(p); } + private: mutex _m; map<void*, MongoMMF*> _views; diff --git a/util/mmap.h b/util/mmap.h index 28e7be7c5fe..2ef417690c4 100644 --- a/util/mmap.h +++ b/util/mmap.h @@ -190,12 +190,12 @@ namespace mongo { #ifdef _WIN32 boost::shared_ptr<mutex> _flushMutex; - void unmapped(void *privateView); + void clearWritableBits(void *privateView); public: static const unsigned ChunkSize = 64 * 1024 * 1024; static const unsigned NChunks = 1024 * 1024; #else - void unmapped(void *privateView) { } + void clearWritableBits(void *privateView) { } #endif protected: diff --git a/util/mmap_win.cpp b/util/mmap_win.cpp index 76837edd5c4..0b0b834becd 100644 --- a/util/mmap_win.cpp +++ b/util/mmap_win.cpp @@ -28,7 +28,7 @@ namespace mongo { ourbitset writable; /** notification on unmapping so we can clear writable bits */ - void MemoryMappedFile::unmapped(void *p) { + void MemoryMappedFile::clearWritableBits(void *p) { for( unsigned i = ((size_t)p)/ChunkSize; i <= (((size_t)p)+len)/ChunkSize; i++ ) { writable.clear(i); assert( !writable.get(i) ); @@ -45,7 +45,7 @@ namespace mongo { void MemoryMappedFile::close() { for( vector<void*>::iterator i = views.begin(); i != views.end(); i++ ) { - unmapped(*i); + clearWritableBits(*i); UnmapViewOfFile(*i); } views.clear(); |