diff options
Diffstat (limited to 'util/mmap.cpp')
-rw-r--r-- | util/mmap.cpp | 152 |
1 files changed, 101 insertions, 51 deletions
diff --git a/util/mmap.cpp b/util/mmap.cpp index f6bbc73..b9c1994 100644 --- a/util/mmap.cpp +++ b/util/mmap.cpp @@ -15,36 +15,67 @@ * limitations under the License. */ -#include "stdafx.h" +#include "pch.h" #include "mmap.h" #include "processinfo.h" +#include "concurrency/rwlock.h" namespace mongo { - set<MemoryMappedFile*> mmfiles; - mongo::mutex mmmutex; + /*static*/ void MemoryMappedFile::updateLength( const char *filename, long &length ) { + if ( !boost::filesystem::exists( filename ) ) + return; + // make sure we map full length if preexisting file. + boost::uintmax_t l = boost::filesystem::file_size( filename ); + assert( l <= 0x7fffffff ); + length = (long) l; + } - MemoryMappedFile::~MemoryMappedFile() { - close(); - scoped_lock lk( mmmutex ); - mmfiles.erase(this); + void* MemoryMappedFile::map(const char *filename) { + boost::uintmax_t l = boost::filesystem::file_size( filename ); + assert( l <= 0x7fffffff ); + long i = (long)l; + return map( filename , i ); } - void MemoryMappedFile::created(){ - scoped_lock lk( mmmutex ); - mmfiles.insert(this); + void printMemInfo( const char * where ){ + cout << "mem info: "; + if ( where ) + cout << where << " "; + ProcessInfo pi; + if ( ! pi.supported() ){ + cout << " not supported" << endl; + return; + } + + cout << "vsize: " << pi.getVirtualMemorySize() << " resident: " << pi.getResidentSize() << " mapped: " << ( MemoryMappedFile::totalMappedLength() / ( 1024 * 1024 ) ) << endl; + } + + /* --- MongoFile ------------------------------------------------- + this is the administrative stuff + */ + + static set<MongoFile*> mmfiles; + static RWLock mmmutex("rw:mmmutex"); + + void MongoFile::destroyed() { + rwlock lk( mmmutex , true ); + mmfiles.erase(this); } /*static*/ - int closingAllFiles = 0; - void MemoryMappedFile::closeAllFiles( stringstream &message ) { + void MongoFile::closeAllFiles( stringstream &message ) { + static int closingAllFiles = 0; if ( closingAllFiles ) { message << "warning closingAllFiles=" << closingAllFiles << endl; return; } ++closingAllFiles; + + rwlock lk( mmmutex , true ); + ProgressMeter pm( mmfiles.size() , 2 , 1 ); - for ( set<MemoryMappedFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ + for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ (*i)->close(); pm.hit(); } @@ -52,59 +83,78 @@ namespace mongo { --closingAllFiles; } - long long MemoryMappedFile::totalMappedLength(){ + /*static*/ long long MongoFile::totalMappedLength(){ unsigned long long total = 0; - scoped_lock lk( mmmutex ); - for ( set<MemoryMappedFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) + rwlock lk( mmmutex , false ); + for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) total += (*i)->length(); return total; } - int MemoryMappedFile::flushAll( bool sync ){ - int num = 0; - - scoped_lock lk( mmmutex ); - for ( set<MemoryMappedFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ - num++; - MemoryMappedFile * mmf = *i; - if ( ! mmf ) - continue; - mmf->flush( sync ); + /*static*/ int MongoFile::flushAll( bool sync ){ + if ( ! sync ){ + int num = 0; + rwlock lk( mmmutex , false ); + for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ + num++; + MongoFile * mmf = *i; + if ( ! mmf ) + continue; + + mmf->flush( sync ); + } + return num; + } + + // want to do it sync + set<MongoFile*> seen; + while ( true ){ + auto_ptr<Flushable> f; + { + rwlock lk( mmmutex , false ); + for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ + MongoFile * mmf = *i; + if ( ! mmf ) + continue; + if ( seen.count( mmf ) ) + continue; + f.reset( mmf->prepareFlush() ); + seen.insert( mmf ); + break; + } + } + if ( ! f.get() ) + break; + + f->flush(); } - return num; + return seen.size(); } - - void MemoryMappedFile::updateLength( const char *filename, long &length ) { - if ( !boost::filesystem::exists( filename ) ) - return; - // make sure we map full length if preexisting file. - boost::uintmax_t l = boost::filesystem::file_size( filename ); - assert( l <= 0x7fffffff ); - length = (long) l; + void MongoFile::created(){ + rwlock lk( mmmutex , true ); + mmfiles.insert(this); } - void* MemoryMappedFile::map(const char *filename) { - boost::uintmax_t l = boost::filesystem::file_size( filename ); - assert( l <= 0x7fffffff ); - long i = (long)l; - return map( filename , i ); - } +#ifdef _DEBUG - void printMemInfo( const char * where ){ - cout << "mem info: "; - if ( where ) - cout << where << " "; - ProcessInfo pi; - if ( ! pi.supported() ){ - cout << " not supported" << endl; - return; + void MongoFile::lockAll() { + rwlock lk( mmmutex , false ); + for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ + MongoFile * mmf = *i; + if (mmf) mmf->_lock(); } - - cout << "vsize: " << pi.getVirtualMemorySize() << " resident: " << pi.getResidentSize() << " mapped: " << ( MemoryMappedFile::totalMappedLength() / ( 1024 * 1024 ) ) << endl; } + void MongoFile::unlockAll() { + rwlock lk( mmmutex , false ); + for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ + MongoFile * mmf = *i; + if (mmf) mmf->_unlock(); + } + } +#endif } // namespace mongo |