1 #ifndef OSMIUM_UTIL_MEMORY_MAPPING_HPP
2 #define OSMIUM_UTIL_MEMORY_MAPPING_HPP
40 #include <system_error>
46 # include <sys/mman.h>
51 # include <sys/types.h>
133 using flag_type = int;
142 throw std::runtime_error(
"Zero-sized mapping is not allowed.");
148 HANDLE get_handle() const noexcept;
219 }
catch (
const std::system_error&) {
243 void resize(
size_t new_size);
249 explicit operator bool() const noexcept {
267 int fd() const noexcept {
283 template <
typename T =
void>
286 return reinterpret_cast<T*
>(
m_addr);
288 throw std::runtime_error(
"invalid memory mapping");
316 void resize(
size_t) =
delete;
330 template <
typename T>
344 m_mapping(sizeof(T) * size,
MemoryMapping::mapping_mode::write_private) {
358 m_mapping(sizeof(T) * size, mode, fd, sizeof(T) * offset) {
367 m_mapping(sizeof(T) * size, writable ?
MemoryMapping::mapping_mode::write_shared :
MemoryMapping::mapping_mode::readonly, fd, sizeof(T) * offset) {
414 m_mapping.
resize(
sizeof(T) * new_size);
421 explicit operator bool() const noexcept {
431 assert(m_mapping.
size() %
sizeof(T) == 0);
432 return m_mapping.
size() /
sizeof(T);
440 int fd() const noexcept {
441 return m_mapping.
fd();
487 template <
typename T>
501 void resize(
size_t) =
delete;
515 #pragma GCC diagnostic push
516 #pragma GCC diagnostic ignored "-Wold-style-cast"
519 return m_addr != MAP_FAILED;
526 #pragma GCC diagnostic pop
529 #ifndef MAP_ANONYMOUS
530 # define MAP_ANONYMOUS MAP_ANON
534 if (m_mapping_mode == mapping_mode::readonly) {
537 return PROT_READ | PROT_WRITE;
544 if (m_mapping_mode == mapping_mode::write_shared) {
551 m_size(check_size(size)),
554 m_mapping_mode(mode),
555 m_addr(::mmap(nullptr, m_size, get_protection(), get_flags(), m_fd, m_offset)) {
558 throw std::system_error(errno, std::system_category(),
"mmap failed");
563 m_size(other.m_size),
564 m_offset(other.m_offset),
566 m_mapping_mode(other.m_mapping_mode),
567 m_addr(other.m_addr) {
568 other.make_invalid();
573 m_size = other.m_size;
574 m_offset = other.m_offset;
576 m_mapping_mode = other.m_mapping_mode;
577 m_addr = other.m_addr;
578 other.make_invalid();
584 if (::munmap(m_addr, m_size) != 0) {
585 throw std::system_error(errno, std::system_category(),
"munmap failed");
592 assert(new_size > 0 &&
"can not resize to zero size");
595 m_addr = ::mremap(m_addr, m_size, new_size, MREMAP_MAYMOVE);
597 throw std::system_error(errno, std::system_category(),
"mremap failed");
601 assert(
false &&
"can't resize anonymous mappings on non-linux systems");
607 m_addr = ::mmap(
nullptr, new_size, get_protection(), get_flags(), m_fd, m_offset);
609 throw std::system_error(errno, std::system_category(),
"mmap (remap) failed");
629 inline DWORD dword_hi(uint64_t x) {
630 return static_cast<DWORD
>(x >> 32);
633 inline DWORD dword_lo(uint64_t x) {
634 return static_cast<DWORD
>(x & 0xffffffff);
642 switch (m_mapping_mode) {
643 case mapping_mode::readonly:
644 return PAGE_READONLY;
645 case mapping_mode::write_private:
646 return PAGE_WRITECOPY;
647 case mapping_mode::write_shared:
648 return PAGE_READWRITE;
653 switch (m_mapping_mode) {
654 case mapping_mode::readonly:
655 return FILE_MAP_READ;
656 case mapping_mode::write_private:
657 return FILE_MAP_COPY;
658 case mapping_mode::write_shared:
659 return FILE_MAP_WRITE;
663 inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept {
665 return INVALID_HANDLE_VALUE;
667 return reinterpret_cast<HANDLE
>(_get_osfhandle(m_fd));
670 inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept {
672 _setmode(m_fd, _O_BINARY);
674 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);
677 inline void* osmium::util::MemoryMapping::map_view_of_file() const noexcept {
678 return MapViewOfFile(m_handle, get_flags(), osmium::util::dword_hi(m_offset), osmium::util::dword_lo(m_offset), m_size);
682 return m_addr !=
nullptr;
690 m_size(check_size(size)),
693 m_mapping_mode(mode),
694 m_handle(create_file_mapping()),
698 throw std::system_error(GetLastError(), std::system_category(),
"CreateFileMapping failed");
701 m_addr = map_view_of_file();
703 throw std::system_error(GetLastError(), std::system_category(),
"MapViewOfFile failed");
708 m_size(other.m_size),
709 m_offset(other.m_offset),
711 m_mapping_mode(other.m_mapping_mode),
712 m_handle(
std::move(other.m_handle)),
713 m_addr(other.m_addr) {
714 other.make_invalid();
715 other.m_handle =
nullptr;
720 m_size = other.m_size;
721 m_offset = other.m_offset;
723 m_mapping_mode = other.m_mapping_mode;
724 m_handle = std::move(other.m_handle);
725 m_addr = other.m_addr;
726 other.make_invalid();
727 other.m_handle =
nullptr;
733 if (! UnmapViewOfFile(m_addr)) {
734 throw std::system_error(GetLastError(), std::system_category(),
"UnmapViewOfFile failed");
740 if (! CloseHandle(m_handle)) {
741 throw std::system_error(GetLastError(), std::system_category(),
"CloseHandle failed");
753 m_handle = create_file_mapping();
755 throw std::system_error(GetLastError(), std::system_category(),
"CreateFileMapping failed");
758 m_addr = map_view_of_file();
760 throw std::system_error(GetLastError(), std::system_category(),
"MapViewOfFile failed");
766 #endif // OSMIUM_UTIL_MEMORY_MAPPING_HPP
~MemoryMapping() noexcept
Definition: memory_mapping.hpp:216
const T * end() const
Definition: memory_mapping.hpp:481
bool is_valid() const noexcept
Definition: memory_mapping.hpp:518
#define OSMIUM_DEPRECATED
Definition: compatibility.hpp:50
flag_type get_protection() const noexcept
Definition: memory_mapping.hpp:533
MemoryMapping m_mapping
Definition: memory_mapping.hpp:333
int flag_type
Definition: memory_mapping.hpp:133
MemoryMapping(size_t size, mapping_mode mode, int fd=-1, off_t offset=0)
Definition: memory_mapping.hpp:550
~TypedMemoryMapping() noexcept=default
size_t file_size(int fd)
Definition: file.hpp:67
flag_type get_flags() const noexcept
Definition: memory_mapping.hpp:540
int fd() const noexcept
Definition: memory_mapping.hpp:267
void unmap()
Definition: memory_mapping.hpp:582
Definition: memory_mapping.hpp:95
Definition: reader_iterator.hpp:39
mapping_mode
Definition: memory_mapping.hpp:99
void resize(size_t new_size)
Definition: memory_mapping.hpp:413
static size_t check_size(size_t size)
Definition: memory_mapping.hpp:140
int resize_fd(int fd)
Definition: memory_mapping.hpp:153
T * end()
Definition: memory_mapping.hpp:465
void * m_addr
The address where the memory is mapped.
Definition: memory_mapping.hpp:124
const T * cbegin() const
Definition: memory_mapping.hpp:469
off_t m_offset
Offset into the file.
Definition: memory_mapping.hpp:111
#define MAP_ANONYMOUS
Definition: memory_mapping.hpp:530
int m_fd
File handle we got the mapping from.
Definition: memory_mapping.hpp:114
size_t size() const noexcept
Definition: memory_mapping.hpp:258
mapping_mode m_mapping_mode
Mapping mode.
Definition: memory_mapping.hpp:117
Namespace for everything in the Osmium library.
Definition: assembler.hpp:73
AnonymousMemoryMapping(size_t size)
Definition: memory_mapping.hpp:307
Definition: memory_mapping.hpp:488
OSMIUM_DEPRECATED TypedMemoryMapping(size_t size, bool writable, int fd, off_t offset=0)
Definition: memory_mapping.hpp:366
TypedMemoryMapping(size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset=0)
Definition: memory_mapping.hpp:357
size_t size() const noexcept
Definition: memory_mapping.hpp:430
T * begin()
Definition: memory_mapping.hpp:456
Definition: memory_mapping.hpp:303
void make_invalid() noexcept
Definition: memory_mapping.hpp:522
AnonymousTypedMemoryMapping(size_t size)
Definition: memory_mapping.hpp:492
int fd() const noexcept
Definition: memory_mapping.hpp:440
void resize(size_t new_size)
Definition: memory_mapping.hpp:591
MemoryMapping & operator=(const MemoryMapping &)=delete
You can not copy a MemoryMapping.
Definition: memory_mapping.hpp:331
TypedMemoryMapping & operator=(const TypedMemoryMapping &)=delete
You can not copy a MemoryMapping.
void unmap()
Definition: memory_mapping.hpp:399
bool writable() const noexcept
Definition: memory_mapping.hpp:274
void resize_file(int fd, size_t new_size)
Definition: file.hpp:132
const T * begin() const
Definition: memory_mapping.hpp:477
size_t m_size
The size of the mapping.
Definition: memory_mapping.hpp:108
const T * cend() const
Definition: memory_mapping.hpp:473
TypedMemoryMapping(size_t size)
Definition: memory_mapping.hpp:343
OSMIUM_DEPRECATED MemoryMapping(size_t size, bool writable=true, int fd=-1, off_t offset=0)
Definition: memory_mapping.hpp:191
T * get_addr() const
Definition: memory_mapping.hpp:284
bool writable() const noexcept
Definition: memory_mapping.hpp:447