0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-2500 windows - eliminate mapaligned

This commit is contained in:
dwight 2011-02-21 10:48:28 -05:00
parent 7e13092c2f
commit af36369716
4 changed files with 52 additions and 6 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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:

View File

@ -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();