Program Listing for File umap_file.hpp¶
↰ Return to documentation for file (utility/umap_file.hpp
)
/* This file is part of UMAP. For copyright information see the COPYRIGHT
* file in the top level directory, or at
* https://github.com/LLNL/umap/blob/master/COPYRIGHT This program is free
* software; you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License (as published by the Free Software
* Foundation) version 2.1 dated February 1999. This program is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the terms and conditions of the GNU Lesser General Public License for
* more details. You should have received a copy of the GNU Lesser General
* Public License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _UMAP_FILE_HPP_
#define _UMAP_FILE_HPP_
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <iostream>
#include <string>
#include <sstream>
#include <sys/stat.h>
#include <fcntl.h>
#include "umap/umap.h"
namespace utility {
void* map_in_file(
std::string filename,
bool initonly,
bool noinit,
bool usemmap,
uint64_t numbytes)
{
int o_opts = O_RDWR | O_LARGEFILE | O_DIRECT;
void* region = NULL;
int fd;
if ( initonly || !noinit ) {
o_opts |= O_CREAT;
unlink(filename.c_str()); // Remove the file if it exists
}
if ( ( fd = open(filename.c_str(), o_opts, S_IRUSR | S_IWUSR) ) == -1 ) {
std::string estr = "Failed to open/create " + filename + ": ";
perror(estr.c_str());
return NULL;
}
if ( o_opts & O_CREAT ) {
// If we are initializing, attempt to pre-allocate disk space for the file.
try {
int x;
if ( ( x = posix_fallocate(fd, 0, numbytes) != 0 ) ) {
std::ostringstream ss;
ss << "Failed to pre-allocate " <<
numbytes << " bytes in " << filename << ": ";
perror(ss.str().c_str());
return NULL;
}
} catch(const std::exception& e) {
std::cerr << "posix_fallocate: " << e.what() << std::endl;
return NULL;
} catch(...) {
std::cerr << "posix_fallocate failed to allocate backing store\n";
return NULL;
}
}
struct stat sbuf;
if (fstat(fd, &sbuf) == -1) {
std::string estr = "Failed to get status (fstat) for " + filename + ": ";
perror(estr.c_str());
return NULL;
}
if ( (off_t)sbuf.st_size != (numbytes) ) {
std::cerr << filename << " size " << sbuf.st_size
<< " does not match specified data size of " << (numbytes) << std::endl;
return NULL;
}
const int prot = PROT_READ|PROT_WRITE;
if ( usemmap ) {
region = mmap(NULL, numbytes, prot, MAP_SHARED | MAP_NORESERVE, fd, 0);
if (region == MAP_FAILED) {
std::ostringstream ss;
ss << "mmap of " << numbytes << " bytes failed for " << filename << ": ";
perror(ss.str().c_str());
return NULL;
}
}
else {
int flags = UMAP_PRIVATE;
region = umap(NULL, numbytes, prot, flags, fd, 0);
if ( region == UMAP_FAILED ) {
std::ostringstream ss;
ss << "umap_mf of " << numbytes
<< " bytes failed for " << filename << ": ";
perror(ss.str().c_str());
return NULL;
}
}
return region;
}
void unmap_file(bool usemmap, uint64_t numbytes, void* region)
{
if ( usemmap ) {
if ( munmap(region, numbytes) < 0 ) {
std::ostringstream ss;
ss << "munmap failure: ";
perror(ss.str().c_str());
exit(-1);
}
}
else {
if (uunmap(region, numbytes) < 0) {
std::ostringstream ss;
ss << "uunmap of failure: ";
perror(ss.str().c_str());
exit(-1);
}
}
}
}
#endif