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>
145 HANDLE get_handle() const noexcept;
211 }
catch (std::system_error&) {
234 void resize(
size_t new_size);
240 operator bool() const noexcept {
258 int fd() const noexcept {
274 template <
typename T =
void>
277 return reinterpret_cast<T*
>(
m_addr);
279 throw std::runtime_error(
"invalid memory mapping");
307 void resize(
size_t) =
delete;
321 template <
typename T>
335 m_mapping(sizeof(T) * size,
MemoryMapping::mapping_mode::write_private) {
349 m_mapping(sizeof(T) * size, mode, fd, sizeof(T) * offset) {
354 m_mapping(sizeof(T) * size, writable ?
MemoryMapping::mapping_mode::write_shared :
MemoryMapping::mapping_mode::readonly, fd, sizeof(T) * offset) {
401 m_mapping.
resize(
sizeof(T) * new_size);
408 operator bool() const noexcept {
418 assert(m_mapping.
size() %
sizeof(T) == 0);
419 return m_mapping.
size() /
sizeof(T);
427 int fd() const noexcept {
428 return m_mapping.
fd();
474 template <
typename T>
488 void resize(
size_t) =
delete;
502 #pragma GCC diagnostic push
503 #pragma GCC diagnostic ignored "-Wold-style-cast"
506 return m_addr != MAP_FAILED;
513 #pragma GCC diagnostic pop
516 #ifndef MAP_ANONYMOUS
517 # define MAP_ANONYMOUS MAP_ANON
521 if (m_mapping_mode == mapping_mode::readonly) {
524 return PROT_READ | PROT_WRITE;
531 if (m_mapping_mode == mapping_mode::write_shared) {
538 m_size(initial_size(size)),
541 m_mapping_mode(mode),
542 m_addr(::mmap(nullptr, m_size, get_protection(), get_flags(), m_fd, m_offset)) {
545 throw std::system_error(errno, std::system_category(),
"mmap failed");
550 m_size(other.m_size),
551 m_offset(other.m_offset),
553 m_mapping_mode(other.m_mapping_mode),
554 m_addr(other.m_addr) {
555 other.make_invalid();
560 m_size = other.m_size;
561 m_offset = other.m_offset;
563 m_mapping_mode = other.m_mapping_mode;
564 m_addr = other.m_addr;
565 other.make_invalid();
571 if (::munmap(m_addr, m_size) != 0) {
572 throw std::system_error(errno, std::system_category(),
"munmap failed");
579 assert(new_size > 0 &&
"can not resize to zero size");
582 m_addr = ::mremap(m_addr, m_size, new_size, MREMAP_MAYMOVE);
584 throw std::system_error(errno, std::system_category(),
"mremap failed");
588 assert(
false &&
"can't resize anonymous mappings on non-linux systems");
594 m_addr = ::mmap(
nullptr, new_size, get_protection(), get_flags(), m_fd, m_offset);
596 throw std::system_error(errno, std::system_category(),
"mmap (remap) failed");
616 inline DWORD dword_hi(uint64_t x) {
617 return static_cast<DWORD
>(x >> 32);
620 inline DWORD dword_lo(uint64_t x) {
621 return static_cast<DWORD
>(x & 0xffffffff);
629 switch (m_mapping_mode) {
630 case mapping_mode::readonly:
631 return PAGE_READONLY;
632 case mapping_mode::write_private:
633 return PAGE_WRITECOPY;
634 case mapping_mode::write_shared:
635 return PAGE_READWRITE;
640 switch (m_mapping_mode) {
641 case mapping_mode::readonly:
642 return FILE_MAP_READ;
643 case mapping_mode::write_private:
644 return FILE_MAP_COPY;
645 case mapping_mode::write_shared:
646 return FILE_MAP_WRITE;
650 inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept {
652 return INVALID_HANDLE_VALUE;
654 return reinterpret_cast<HANDLE
>(_get_osfhandle(m_fd));
657 inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept {
658 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);
661 inline void* osmium::util::MemoryMapping::map_view_of_file() const noexcept {
662 return MapViewOfFile(m_handle, get_flags(), osmium::util::dword_hi(m_offset), osmium::util::dword_lo(m_offset), m_size);
666 return m_addr !=
nullptr;
674 m_size(initial_size(size)),
677 m_mapping_mode(mode),
678 m_handle(create_file_mapping()),
682 throw std::system_error(GetLastError(), std::system_category(),
"CreateFileMapping failed");
685 m_addr = map_view_of_file();
687 throw std::system_error(GetLastError(), std::system_category(),
"MapViewOfFile failed");
692 m_size(other.m_size),
693 m_offset(other.m_offset),
695 m_mapping_mode(other.m_mapping_mode),
696 m_handle(
std::move(other.m_handle)),
697 m_addr(other.m_addr) {
698 other.make_invalid();
699 other.m_handle =
nullptr;
704 m_size = other.m_size;
705 m_offset = other.m_offset;
707 m_mapping_mode = other.m_mapping_mode;
708 m_handle = std::move(other.m_handle);
709 m_addr = other.m_addr;
710 other.make_invalid();
711 other.m_handle =
nullptr;
717 if (! UnmapViewOfFile(m_addr)) {
718 throw std::system_error(GetLastError(), std::system_category(),
"UnmapViewOfFile failed");
724 if (! CloseHandle(m_handle)) {
725 throw std::system_error(GetLastError(), std::system_category(),
"CloseHandle failed");
737 m_handle = create_file_mapping();
739 throw std::system_error(GetLastError(), std::system_category(),
"CreateFileMapping failed");
742 m_addr = map_view_of_file();
744 throw std::system_error(GetLastError(), std::system_category(),
"MapViewOfFile failed");
750 #endif // OSMIUM_UTIL_MEMORY_MAPPING_HPP
~MemoryMapping() noexcept
Definition: memory_mapping.hpp:208
const T * end() const
Definition: memory_mapping.hpp:468
bool is_valid() const noexcept
Definition: memory_mapping.hpp:505
flag_type get_protection() const noexcept
Definition: memory_mapping.hpp:520
MemoryMapping m_mapping
Definition: memory_mapping.hpp:324
MemoryMapping(size_t size, mapping_mode mode, int fd=-1, off_t offset=0)
Definition: memory_mapping.hpp:537
size_t file_size(int fd)
Definition: file.hpp:67
flag_type get_flags() const noexcept
Definition: memory_mapping.hpp:527
int fd() const noexcept
Definition: memory_mapping.hpp:258
TypedMemoryMapping(size_t size, bool writable, int fd, off_t offset=0)
DEPRECATED: For backwards compatibility.
Definition: memory_mapping.hpp:353
static size_t initial_size(size_t size)
Definition: memory_mapping.hpp:137
void unmap()
Definition: memory_mapping.hpp:569
Definition: memory_mapping.hpp:89
Definition: reader_iterator.hpp:39
mapping_mode
Definition: memory_mapping.hpp:92
void resize(size_t new_size)
Definition: memory_mapping.hpp:400
int flag_type
Definition: memory_mapping.hpp:126
int resize_fd(int fd)
Definition: memory_mapping.hpp:150
T * end()
Definition: memory_mapping.hpp:452
~TypedMemoryMapping()=default
size_t get_pagesize()
Definition: file.hpp:103
void * m_addr
The address where the memory is mapped.
Definition: memory_mapping.hpp:117
const T * cbegin() const
Definition: memory_mapping.hpp:456
off_t m_offset
Offset into the file.
Definition: memory_mapping.hpp:104
#define MAP_ANONYMOUS
Definition: memory_mapping.hpp:517
int m_fd
File handle we got the mapping from.
Definition: memory_mapping.hpp:107
size_t size() const noexcept
Definition: memory_mapping.hpp:249
mapping_mode m_mapping_mode
Mapping mode.
Definition: memory_mapping.hpp:110
Namespace for everything in the Osmium library.
Definition: assembler.hpp:55
AnonymousMemoryMapping(size_t size)
Definition: memory_mapping.hpp:298
Definition: memory_mapping.hpp:475
TypedMemoryMapping(size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset=0)
Definition: memory_mapping.hpp:348
size_t size() const noexcept
Definition: memory_mapping.hpp:417
T * begin()
Definition: memory_mapping.hpp:443
Definition: memory_mapping.hpp:294
void make_invalid() noexcept
Definition: memory_mapping.hpp:509
MemoryMapping(size_t size, bool writable=true, int fd=-1, off_t offset=0)
DEPRECATED: For backwards compatibility.
Definition: memory_mapping.hpp:183
AnonymousTypedMemoryMapping(size_t size)
Definition: memory_mapping.hpp:479
int fd() const noexcept
Definition: memory_mapping.hpp:427
void resize(size_t new_size)
Definition: memory_mapping.hpp:578
MemoryMapping & operator=(const MemoryMapping &)=delete
You can not copy a MemoryMapping.
Definition: memory_mapping.hpp:322
TypedMemoryMapping & operator=(const TypedMemoryMapping &)=delete
You can not copy a MemoryMapping.
void unmap()
Definition: memory_mapping.hpp:386
bool writable() const noexcept
Definition: memory_mapping.hpp:265
void resize_file(int fd, size_t new_size)
Definition: file.hpp:94
const T * begin() const
Definition: memory_mapping.hpp:464
size_t m_size
The size of the mapping.
Definition: memory_mapping.hpp:101
const T * cend() const
Definition: memory_mapping.hpp:460
TypedMemoryMapping(size_t size)
Definition: memory_mapping.hpp:334
T * get_addr() const
Definition: memory_mapping.hpp:275
bool writable() const noexcept
Definition: memory_mapping.hpp:434