1 #ifndef OSMIUM_UTIL_MEMORY_MAPPING_HPP
2 #define OSMIUM_UTIL_MEMORY_MAPPING_HPP
39 #include <system_error>
44 # include <sys/mman.h>
48 # include <sys/types.h>
136 HANDLE get_handle() const noexcept;
197 }
catch (std::system_error&) {
220 void resize(
size_t new_size);
226 operator bool() const noexcept {
244 int fd() const noexcept {
260 template <
typename T =
void>
263 return reinterpret_cast<T*
>(
m_addr);
265 throw std::runtime_error(
"invalid memory mapping");
293 void resize(
size_t) =
delete;
307 template <
typename T>
321 m_mapping(sizeof(T) * size) {
335 m_mapping(sizeof(T) * size, writable, fd, sizeof(T) * offset) {
382 m_mapping.
resize(
sizeof(T) * new_size);
389 operator bool() const noexcept {
399 assert(m_mapping.
size() %
sizeof(T) == 0);
400 return m_mapping.
size() /
sizeof(T);
408 int fd() const noexcept {
409 return m_mapping.
fd();
455 template <
typename T>
469 void resize(
size_t) =
delete;
483 #pragma GCC diagnostic push
484 #pragma GCC diagnostic ignored "-Wold-style-cast"
487 return m_addr != MAP_FAILED;
494 #pragma GCC diagnostic pop
497 #ifndef MAP_ANONYMOUS
498 # define MAP_ANONYMOUS MAP_ANON
503 return PROT_READ | PROT_WRITE;
516 m_size(initial_size(size)),
519 m_writable(writable),
520 m_addr(::mmap(nullptr, m_size, get_protection(), get_flags(), m_fd, m_offset)) {
521 assert(writable || fd != -1);
523 throw std::system_error(errno, std::system_category(),
"mmap failed");
528 m_size(other.m_size),
529 m_offset(other.m_offset),
531 m_writable(other.m_writable),
532 m_addr(other.m_addr) {
533 other.make_invalid();
538 m_size = other.m_size;
539 m_offset = other.m_offset;
541 m_writable = other.m_writable;
542 m_addr = other.m_addr;
543 other.make_invalid();
549 if (::munmap(m_addr, m_size) != 0) {
550 throw std::system_error(errno, std::system_category(),
"munmap failed");
557 assert(new_size > 0 &&
"can not resize to zero size");
560 m_addr = ::mremap(m_addr, m_size, new_size, MREMAP_MAYMOVE);
562 throw std::system_error(errno, std::system_category(),
"mremap failed");
566 assert(
false &&
"can't resize anonymous mappings on non-linux systems");
572 m_addr = ::mmap(
nullptr, new_size, get_protection(), get_flags(), m_fd, m_offset);
574 throw std::system_error(errno, std::system_category(),
"mmap (remap) failed");
594 inline DWORD dword_hi(uint64_t x) {
595 return static_cast<DWORD
>(x >> 32);
598 inline DWORD dword_lo(uint64_t x) {
599 return static_cast<DWORD
>(x & 0xffffffff);
608 return PAGE_READWRITE;
610 return PAGE_READONLY;
615 return FILE_MAP_WRITE | FILE_MAP_COPY;
618 return FILE_MAP_WRITE;
620 return FILE_MAP_READ;
623 inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept {
625 return INVALID_HANDLE_VALUE;
627 return reinterpret_cast<HANDLE
>(_get_osfhandle(m_fd));
630 inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept {
631 return CreateFileMapping(get_handle(),
nullptr, get_protection(), osmium::util::dword_hi(static_cast<uint64_t>(m_size) + m_offset), osmium::util::dword_lo(static_cast<uint64_t>(m_size) + m_offset),
nullptr);
634 inline void* osmium::util::MemoryMapping::map_view_of_file() const noexcept {
635 return MapViewOfFile(m_handle, get_flags(), osmium::util::dword_hi(m_offset), osmium::util::dword_lo(m_offset), m_size);
639 return m_addr !=
nullptr;
647 m_size(initial_size(size)),
650 m_writable(writable),
651 m_handle(create_file_mapping()),
655 throw std::system_error(GetLastError(), std::system_category(),
"CreateFileMapping failed");
658 m_addr = map_view_of_file();
660 throw std::system_error(GetLastError(), std::system_category(),
"MapViewOfFile failed");
665 m_size(other.m_size),
666 m_offset(other.m_offset),
668 m_writable(other.m_writable),
669 m_handle(
std::move(other.m_handle)),
670 m_addr(other.m_addr) {
671 other.make_invalid();
672 other.m_handle =
nullptr;
677 m_size = other.m_size;
678 m_offset = other.m_offset;
680 m_writable = other.m_writable;
681 m_handle = std::move(other.m_handle);
682 m_addr = other.m_addr;
683 other.make_invalid();
684 other.m_handle =
nullptr;
690 if (! UnmapViewOfFile(m_addr)) {
691 throw std::system_error(GetLastError(), std::system_category(),
"UnmapViewOfFile failed");
697 if (! CloseHandle(m_handle)) {
698 throw std::system_error(GetLastError(), std::system_category(),
"CloseHandle failed");
710 m_handle = create_file_mapping();
712 throw std::system_error(GetLastError(), std::system_category(),
"CreateFileMapping failed");
715 m_addr = map_view_of_file();
717 throw std::system_error(GetLastError(), std::system_category(),
"MapViewOfFile failed");
723 #endif // OSMIUM_UTIL_MEMORY_MAPPING_HPP
~MemoryMapping() noexcept
Definition: memory_mapping.hpp:194
const T * end() const
Definition: memory_mapping.hpp:449
bool is_valid() const noexcept
Definition: memory_mapping.hpp:486
flag_type get_protection() const noexcept
Definition: memory_mapping.hpp:501
MemoryMapping m_mapping
Definition: memory_mapping.hpp:310
size_t file_size(int fd)
Definition: file.hpp:66
flag_type get_flags() const noexcept
Definition: memory_mapping.hpp:508
int fd() const noexcept
Definition: memory_mapping.hpp:244
TypedMemoryMapping(size_t size, bool writable, int fd, off_t offset=0)
Definition: memory_mapping.hpp:334
static size_t initial_size(size_t size)
Definition: memory_mapping.hpp:128
void unmap()
Definition: memory_mapping.hpp:547
Definition: memory_mapping.hpp:89
Definition: reader_iterator.hpp:39
void resize(size_t new_size)
Definition: memory_mapping.hpp:381
int flag_type
Definition: memory_mapping.hpp:117
int resize_fd(int fd)
Definition: memory_mapping.hpp:141
T * end()
Definition: memory_mapping.hpp:433
~TypedMemoryMapping()=default
size_t get_pagesize()
Definition: file.hpp:102
void * m_addr
The address where the memory is mapped.
Definition: memory_mapping.hpp:108
const T * cbegin() const
Definition: memory_mapping.hpp:437
off_t m_offset
Offset into the file.
Definition: memory_mapping.hpp:95
#define MAP_ANONYMOUS
Definition: memory_mapping.hpp:498
int m_fd
File handle we got the mapping from.
Definition: memory_mapping.hpp:98
size_t size() const noexcept
Definition: memory_mapping.hpp:235
bool m_writable
Is the memory writable?
Definition: memory_mapping.hpp:101
Namespace for everything in the Osmium library.
Definition: assembler.hpp:55
AnonymousMemoryMapping(size_t size)
Definition: memory_mapping.hpp:284
Definition: memory_mapping.hpp:456
size_t size() const noexcept
Definition: memory_mapping.hpp:398
T * begin()
Definition: memory_mapping.hpp:424
Definition: memory_mapping.hpp:280
void make_invalid() noexcept
Definition: memory_mapping.hpp:490
MemoryMapping(size_t size, bool writable=true, int fd=-1, off_t offset=0)
Definition: memory_mapping.hpp:515
AnonymousTypedMemoryMapping(size_t size)
Definition: memory_mapping.hpp:460
int fd() const noexcept
Definition: memory_mapping.hpp:408
void resize(size_t new_size)
Definition: memory_mapping.hpp:556
MemoryMapping & operator=(const MemoryMapping &)=delete
You can not copy a MemoryMapping.
Definition: memory_mapping.hpp:308
TypedMemoryMapping & operator=(const TypedMemoryMapping &)=delete
You can not copy a MemoryMapping.
void unmap()
Definition: memory_mapping.hpp:367
bool writable() const noexcept
Definition: memory_mapping.hpp:251
void resize_file(int fd, size_t new_size)
Definition: file.hpp:93
const T * begin() const
Definition: memory_mapping.hpp:445
size_t m_size
The size of the mapping.
Definition: memory_mapping.hpp:92
const T * cend() const
Definition: memory_mapping.hpp:441
TypedMemoryMapping(size_t size)
Definition: memory_mapping.hpp:320
T * get_addr() const
Definition: memory_mapping.hpp:261
bool writable() const noexcept
Definition: memory_mapping.hpp:415