29 #include <memoryapi.h> 50 static constexpr DWORD DWORD_MAX = std::numeric_limits<DWORD>::max();
54 MappedFile::MappedFile(
const MemoryRegion ®ion) : region_(region) {}
57 if (region_.size != 0) {
59 VLOG(2) <<
"munmap'ed " << region_.size <<
" bytes at " << region_.mmap;
61 if (UnmapViewOfFile(region_.mmap) != 0) {
62 LOG(ERROR) <<
"Failed to unmap region: " << GetLastError();
64 CloseHandle(region_.file_mapping);
66 if (munmap(region_.mmap, region_.size) != 0) {
67 LOG(ERROR) <<
"Failed to unmap region: " << strerror(errno);
72 operator delete(region_.data, region_.size,
73 std::align_val_t{region_.offset});
83 const auto spos = istrm.tellg();
84 VLOG(2) <<
"memorymap: " << (memorymap ?
"true" :
"false") <<
" source: \"" 86 <<
" size: " << size <<
" offset: " << spos;
87 if (memorymap && spos >= 0 && spos % kArchAlignment == 0) {
88 const size_t pos =
static_cast<size_t>(spos);
90 const int fd = _open(source.c_str(), _O_RDONLY);
92 const int fd = open(source.c_str(), O_RDONLY);
95 std::unique_ptr<MappedFile> mmf(MapFromFileDescriptor(fd, pos, size));
96 if (close(fd) == 0 && mmf !=
nullptr) {
97 istrm.seekg(pos + size, std::ios::beg);
99 VLOG(2) <<
"mmap'ed region of " << size <<
" at offset " << pos
100 <<
" from " << source <<
" to addr " << mmf->region_.mmap;
101 return mmf.release();
104 LOG(WARNING) <<
"Mapping of file failed: " << strerror(errno);
111 LOG(WARNING) <<
"File mapping at offset " << spos <<
" of file " << source
112 <<
" could not be honored, reading instead";
115 std::unique_ptr<MappedFile> mf(Allocate(size));
116 auto *buffer =
static_cast<char *
>(mf->mutable_data());
118 const auto next_size = std::min(size, kMaxReadChunk);
119 const auto current_pos = istrm.tellg();
120 if (!istrm.read(buffer, next_size)) {
121 LOG(ERROR) <<
"Failed to read " << next_size <<
" bytes at offset " 122 << current_pos <<
"from \"" << source <<
"\"";
127 VLOG(2) <<
"Read " << next_size <<
" bytes. " << size <<
" remaining";
137 GetSystemInfo(&sysInfo);
138 const DWORD pagesize = sysInfo.dwAllocationGranularity;
140 const int pagesize = sysconf(_SC_PAGESIZE);
143 const size_t offset = pos % pagesize;
144 const size_t offset_pos = pos - offset;
145 const size_t upsize = size + offset;
149 LOG(ERROR) <<
"Invalid file descriptor fd=" << fd;
152 HANDLE file =
reinterpret_cast<HANDLE
>(_get_osfhandle(fd));
153 if (file == INVALID_HANDLE_VALUE) {
154 LOG(ERROR) <<
"Invalid file descriptor fd=" << fd;
157 const DWORD max_size_hi =
158 sizeof(size_t) >
sizeof(DWORD) ? upsize >> (CHAR_BIT *
sizeof(DWORD)) : 0;
159 const DWORD max_size_lo = upsize & DWORD_MAX;
160 HANDLE file_mapping = CreateFileMappingA(file,
nullptr, PAGE_READONLY,
161 max_size_hi, max_size_lo,
nullptr);
162 if (file_mapping == INVALID_HANDLE_VALUE) {
163 LOG(ERROR) <<
"Can't create mapping for fd=" << fd <<
" size=" << upsize
164 <<
": " << GetLastError();
168 const DWORD offset_pos_hi =
169 sizeof(size_t) >
sizeof(DWORD) ? offset_pos >> (CHAR_BIT *
sizeof(DWORD))
171 const DWORD offset_pos_lo = offset_pos & DWORD_MAX;
172 void *map = MapViewOfFile(file_mapping, FILE_MAP_READ,
173 offset_pos_hi, offset_pos_lo, upsize);
175 LOG(ERROR) <<
"mmap failed for fd=" << fd <<
" size=" << upsize
176 <<
" offset=" << offset_pos <<
": " << GetLastError();
177 CloseHandle(file_mapping);
181 void *map = mmap(
nullptr, upsize, PROT_READ, MAP_SHARED, fd, offset_pos);
182 if (map == MAP_FAILED) {
183 LOG(ERROR) <<
"mmap failed for fd=" << fd <<
" size=" << upsize
184 <<
" offset=" << offset_pos;
190 region.
size = upsize;
191 region.
data =
static_cast<void *
>(
static_cast<char *
>(map) + offset);
194 region.file_mapping = file_mapping;
201 region.
data =
nullptr;
205 region.
data =
static_cast<char *
>(
operator new(
206 size, std::align_val_t{align}
209 region.
mmap =
nullptr;
static MappedFile * Map(std::istream &istrm, bool memorymap, const std::string &source, size_t size)
static MappedFile * Allocate(size_t size, size_t align=kArchAlignment)
static MappedFile * Borrow(void *data)
static MappedFile * MapFromFileDescriptor(int fd, size_t pos, size_t size)