summaryrefslogtreecommitdiff
path: root/util/mmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'util/mmap.cpp')
-rw-r--r--util/mmap.cpp152
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