// Copyright 2010, 2013 Martin C. Frith #include "fileMap.hh" #include "stringify.hh" #include // strerror #include #include // File mapping requires non-standard-C++ library functions. I think // this code will not work on all platforms, e.g. windows. Hopefully, // it's easy to rewrite this code for those platforms. #include // open #include // close #include // mmap, munmap static void err( const std::string& s ) { throw std::runtime_error( s + ": " + std::strerror(errno) ); } // This function tries to force the file-mapping to actually get // loaded into memory, by reading it sequentially. Without this, // random access can be horribly slow (at least on two Linux 2.6 // systems). static void primeMemory( void* begin, size_t bytes ){ unsigned z = 0; size_t stepSize = 1024; const char* x = static_cast(begin); const char* y = x + (bytes / stepSize) * stepSize; while( x < y ){ z += *x; x += stepSize; } volatile unsigned dontOptimizeMeAway = z; dontOptimizeMeAway = dontOptimizeMeAway; // ??? prevents compiler warning } namespace cbrc{ void* openFileMap( const std::string& fileName, size_t bytes ){ if( bytes == 0 ) return 0; int f = open( fileName.c_str(), O_RDONLY ); if( f < 0 ) err( "can't open file " + fileName ); void* m = mmap( 0, bytes, PROT_READ, MAP_SHARED, f, 0 ); if( m == MAP_FAILED ) err( "can't map file " + fileName ); int e = close(f); if( e < 0 ) err( "can't close file " + fileName ); primeMemory( m, bytes ); return m; } void closeFileMap( void* begin, size_t bytes ){ if( bytes == 0 ) return; int e = munmap( begin, bytes ); if( e < 0 ) err( "failed to \"munmap\" " + stringify(bytes) + " bytes" ); } } // end namespace