diff options
author | Tad Marshall <tad@10gen.com> | 2012-03-28 16:24:30 -0400 |
---|---|---|
committer | Tad Marshall <tad@10gen.com> | 2012-03-28 16:43:13 -0400 |
commit | 46f203192c459ebdd3e3278de4f92e6d21f44e0d (patch) | |
tree | 75785d37c6720c980d1241ec1e9b85a6cf9880a2 /src | |
parent | 77e7786e7aae1d6446ad5f9357ced5973ed0a6b6 (diff) | |
download | mongo-46f203192c459ebdd3e3278de4f92e6d21f44e0d.tar.gz |
Move Windows mmap code from mongommf.cpp to mmap_win.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/mongommf.cpp | 104 | ||||
-rw-r--r-- | src/mongo/util/mmap_win.cpp | 102 |
2 files changed, 102 insertions, 104 deletions
diff --git a/src/mongo/db/mongommf.cpp b/src/mongo/db/mongommf.cpp index beff3cfa923..d44a02bf080 100644 --- a/src/mongo/db/mongommf.cpp +++ b/src/mongo/db/mongommf.cpp @@ -35,110 +35,6 @@ using namespace mongoutils; namespace mongo { -#if defined(_WIN32) - extern mutex mapViewMutex; - - __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 = (size_t) (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 (mcw) " << mmf->filename() << ' ' << chunkno << hex << protectStart << ' ' << protectSize << ' ' << errnoWithDescription(e) << endl; - verify(false); - } - } - - writable.set(chunkno); - } - - void* MemoryMappedFile::createPrivateMap() { - verify( maphandle ); - scoped_lock lk(mapViewMutex); - void *p = MapViewOfFile(maphandle, FILE_MAP_READ, 0, 0, 0); - if ( p == 0 ) { - DWORD e = GetLastError(); - log() << "createPrivateMap failed " << filename() << " " << - errnoWithDescription(e) << " filelen:" << len << - ((sizeof(void*) == 4 ) ? " (32 bit build)" : "") << - endl; - } - else { - clearWritableBits(p); - views.push_back(p); - memconcept::is(p, memconcept::concept::memorymappedfile, filename()); - } - return p; - } - - void* MemoryMappedFile::remapPrivateView(void *oldPrivateAddr) { - d.dbMutex.assertWriteLocked(); // short window where we are unmapped so must be exclusive - - // the mapViewMutex is to assure we get the same address on the remap - scoped_lock lk(mapViewMutex); - - clearWritableBits(oldPrivateAddr); -#if 1 - // https://jira.mongodb.org/browse/SERVER-2942 - DWORD old; - bool ok = VirtualProtect(oldPrivateAddr, (SIZE_T) len, PAGE_READONLY, &old); - if( !ok ) { - DWORD e = GetLastError(); - log() << "VirtualProtect failed in remapPrivateView " << filename() << hex << oldPrivateAddr << ' ' << len << ' ' << errnoWithDescription(e) << endl; - verify(false); - } - return oldPrivateAddr; -#else - if( !UnmapViewOfFile(oldPrivateAddr) ) { - DWORD e = GetLastError(); - log() << "UnMapViewOfFile failed " << filename() << ' ' << errnoWithDescription(e) << endl; - verify(false); - } - - // we want the new address to be the same as the old address in case things keep pointers around (as namespaceindex does). - void *p = MapViewOfFileEx(maphandle, FILE_MAP_READ, 0, 0, - /*dwNumberOfBytesToMap 0 means to eof*/0 /*len*/, - oldPrivateAddr); - - if ( p == 0 ) { - DWORD e = GetLastError(); - log() << "MapViewOfFileEx failed " << filename() << " " << errnoWithDescription(e) << endl; - verify(p); - } - verify(p == oldPrivateAddr); - return p; -#endif - } -#endif - void MongoMMF::remapThePrivateView() { verify( cmdLine.dur ); diff --git a/src/mongo/util/mmap_win.cpp b/src/mongo/util/mmap_win.cpp index 107653c5bda..2bf97930089 100644 --- a/src/mongo/util/mmap_win.cpp +++ b/src/mongo/util/mmap_win.cpp @@ -158,6 +158,108 @@ namespace mongo { return view; } + extern mutex mapViewMutex; + + __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 = (size_t) (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 (mcw) " << mmf->filename() << ' ' << chunkno << hex << protectStart << ' ' << protectSize << ' ' << errnoWithDescription(e) << endl; + verify(false); + } + } + + writable.set(chunkno); + } + + void* MemoryMappedFile::createPrivateMap() { + verify( maphandle ); + scoped_lock lk(mapViewMutex); + void *p = MapViewOfFile(maphandle, FILE_MAP_READ, 0, 0, 0); + if ( p == 0 ) { + DWORD e = GetLastError(); + log() << "createPrivateMap failed " << filename() << " " << + errnoWithDescription(e) << " filelen:" << len << + ((sizeof(void*) == 4 ) ? " (32 bit build)" : "") << + endl; + } + else { + clearWritableBits(p); + views.push_back(p); + memconcept::is(p, memconcept::concept::memorymappedfile, filename()); + } + return p; + } + + void* MemoryMappedFile::remapPrivateView(void *oldPrivateAddr) { + d.dbMutex.assertWriteLocked(); // short window where we are unmapped so must be exclusive + + // the mapViewMutex is to assure we get the same address on the remap + scoped_lock lk(mapViewMutex); + + clearWritableBits(oldPrivateAddr); +#if 1 + // https://jira.mongodb.org/browse/SERVER-2942 + DWORD old; + bool ok = VirtualProtect(oldPrivateAddr, (SIZE_T) len, PAGE_READONLY, &old); + if( !ok ) { + DWORD e = GetLastError(); + log() << "VirtualProtect failed in remapPrivateView " << filename() << hex << oldPrivateAddr << ' ' << len << ' ' << errnoWithDescription(e) << endl; + verify(false); + } + return oldPrivateAddr; +#else + if( !UnmapViewOfFile(oldPrivateAddr) ) { + DWORD e = GetLastError(); + log() << "UnMapViewOfFile failed " << filename() << ' ' << errnoWithDescription(e) << endl; + verify(false); + } + + // we want the new address to be the same as the old address in case things keep pointers around (as namespaceindex does). + void *p = MapViewOfFileEx(maphandle, FILE_MAP_READ, 0, 0, + /*dwNumberOfBytesToMap 0 means to eof*/0 /*len*/, + oldPrivateAddr); + + if ( p == 0 ) { + DWORD e = GetLastError(); + log() << "MapViewOfFileEx failed " << filename() << " " << errnoWithDescription(e) << endl; + verify(p); + } + verify(p == oldPrivateAddr); + return p; +#endif + } + class WindowsFlushable : public MemoryMappedFile::Flushable { public: WindowsFlushable( void * view , HANDLE fd , string filename , boost::shared_ptr<mutex> flushMutex ) |