1 #ifndef OSMIUM_UTIL_MEMORY_MAPPING_HPP
2 #define OSMIUM_UTIL_MEMORY_MAPPING_HPP
43 #include <system_error>
46 # include <sys/mman.h>
47 # include <sys/statvfs.h>
52 # include <sys/types.h>
57 inline namespace util {
149 HANDLE get_handle() const noexcept;
150 HANDLE create_file_mapping() const noexcept;
151 void* map_view_of_file() const noexcept;
160 struct statvfs stat{};
161 const int result = ::fstatvfs(
fd, &stat);
165 return stat.f_bsize * stat.f_bavail;
179 if (available > 0 && current_file_size + available <=
m_size) {
180 throw std::system_error{ENOSPC, std::system_category(),
"Could not resize file: Not enough space on filesystem"};
242 }
catch (
const std::system_error&) {
266 void resize(std::size_t new_size);
272 explicit operator bool() const noexcept {
281 std::size_t
size() const noexcept {
290 int fd() const noexcept {
306 template <
typename T =
void>
308 return reinterpret_cast<T*
>(
m_addr);
336 void resize(std::size_t) =
delete;
350 template <
typename T>
390 sizeof(T) * offset) {
444 explicit operator bool() const noexcept {
453 std::size_t
size() const noexcept {
463 int fd() const noexcept {
506 const T*
cend() const noexcept {
524 const T*
end() const noexcept {
530 template <
typename T>
544 void resize(std::size_t) =
delete;
558 #pragma GCC diagnostic push
559 #pragma GCC diagnostic ignored "-Wold-style-cast"
562 return m_addr != MAP_FAILED;
569 #pragma GCC diagnostic pop
572 #ifndef MAP_ANONYMOUS
573 # define MAP_ANONYMOUS MAP_ANON
577 if (m_mapping_mode == mapping_mode::readonly) {
580 return PROT_READ | PROT_WRITE;
587 if (m_mapping_mode == mapping_mode::write_shared) {
594 m_size(check_size(size)),
597 m_mapping_mode(mode),
598 m_addr(::mmap(nullptr, m_size, get_protection(), get_flags(), m_fd, m_offset)) {
601 throw std::system_error{errno, std::system_category(),
"mmap failed"};
606 m_size(other.m_size),
607 m_offset(other.m_offset),
609 m_mapping_mode(other.m_mapping_mode),
610 m_addr(other.m_addr) {
611 other.make_invalid();
617 }
catch (
const std::system_error&) {
621 m_size = other.m_size;
622 m_offset = other.m_offset;
624 m_mapping_mode = other.m_mapping_mode;
625 m_addr = other.m_addr;
626 other.make_invalid();
632 if (::munmap(m_addr, m_size) != 0) {
633 throw std::system_error{errno, std::system_category(),
"munmap failed"};
640 assert(new_size > 0 &&
"can not resize to zero size");
643 m_addr = ::mremap(m_addr, m_size, new_size, MREMAP_MAYMOVE);
645 throw std::system_error{errno, std::system_category(),
"mremap failed"};
649 assert(
false &&
"can't resize anonymous mappings on non-linux systems");
655 m_addr = ::mmap(
nullptr, new_size, get_protection(), get_flags(), m_fd, m_offset);
657 throw std::system_error{errno, std::system_category(),
"mmap (remap) failed"};
675 inline namespace util {
677 inline DWORD dword_hi(uint64_t x) {
678 return static_cast<DWORD
>(x >> 32);
681 inline DWORD dword_lo(uint64_t x) {
682 return static_cast<DWORD
>(x & 0xffffffff);
690 switch (m_mapping_mode) {
691 case mapping_mode::readonly:
692 return PAGE_READONLY;
693 case mapping_mode::write_private:
694 return PAGE_WRITECOPY;
698 return PAGE_READWRITE;
702 switch (m_mapping_mode) {
703 case mapping_mode::readonly:
704 return FILE_MAP_READ;
705 case mapping_mode::write_private:
706 return FILE_MAP_COPY;
710 return FILE_MAP_WRITE;
713 inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept {
715 return INVALID_HANDLE_VALUE;
717 return reinterpret_cast<HANDLE
>(_get_osfhandle(m_fd));
720 inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept {
722 _setmode(m_fd, _O_BINARY);
724 return CreateFileMapping(get_handle(),
727 osmium::dword_hi(
static_cast<uint64_t
>(m_size) + m_offset),
728 osmium::dword_lo(
static_cast<uint64_t
>(m_size) + m_offset),
732 inline void* osmium::util::MemoryMapping::map_view_of_file() const noexcept {
733 return MapViewOfFile(m_handle,
735 osmium::dword_hi(m_offset),
736 osmium::dword_lo(m_offset),
741 return m_addr !=
nullptr;
751 inline int last_error() noexcept {
752 return static_cast<int>(GetLastError());
756 m_size(check_size(size)),
759 m_mapping_mode(mode),
760 m_handle(create_file_mapping()),
764 throw std::system_error{last_error(), std::system_category(),
"CreateFileMapping failed"};
767 m_addr = map_view_of_file();
769 throw std::system_error{last_error(), std::system_category(),
"MapViewOfFile failed"};
774 m_size(other.m_size),
775 m_offset(other.m_offset),
777 m_mapping_mode(other.m_mapping_mode),
778 m_handle(std::move(other.m_handle)),
779 m_addr(other.m_addr) {
780 other.make_invalid();
781 other.m_handle =
nullptr;
787 }
catch (
const std::system_error&) {
791 m_size = other.m_size;
792 m_offset = other.m_offset;
794 m_mapping_mode = other.m_mapping_mode;
795 m_handle = std::move(other.m_handle);
796 m_addr = other.m_addr;
797 other.make_invalid();
798 other.m_handle =
nullptr;
804 if (!UnmapViewOfFile(m_addr)) {
805 throw std::system_error{last_error(), std::system_category(),
"UnmapViewOfFile failed"};
811 if (!CloseHandle(m_handle)) {
812 throw std::system_error{last_error(), std::system_category(),
"CloseHandle failed"};
824 m_handle = create_file_mapping();
826 throw std::system_error{last_error(), std::system_category(),
"CreateFileMapping failed"};
829 m_addr = map_view_of_file();
831 throw std::system_error{last_error(), std::system_category(),
"MapViewOfFile failed"};
Definition: memory_mapping.hpp:323
AnonymousMemoryMapping(std::size_t size)
Definition: memory_mapping.hpp:327
Definition: memory_mapping.hpp:531
AnonymousTypedMemoryMapping(std::size_t size)
Definition: memory_mapping.hpp:535
Definition: memory_mapping.hpp:96
int resize_fd(int fd) const
Definition: memory_mapping.hpp:169
void unmap()
Definition: memory_mapping.hpp:630
bool is_valid() const noexcept
Definition: memory_mapping.hpp:561
mapping_mode
Definition: memory_mapping.hpp:100
std::size_t size() const noexcept
Definition: memory_mapping.hpp:281
OSMIUM_DEPRECATED MemoryMapping(std::size_t size, bool writable=true, int fd=-1, off_t offset=0)
Definition: memory_mapping.hpp:214
MemoryMapping(const MemoryMapping &)=delete
You can not copy construct a MemoryMapping.
flag_type get_protection() const noexcept
Definition: memory_mapping.hpp:576
off_t m_offset
Offset into the file.
Definition: memory_mapping.hpp:112
~MemoryMapping() noexcept
Definition: memory_mapping.hpp:239
MemoryMapping & operator=(const MemoryMapping &)=delete
You can not copy a MemoryMapping.
T * get_addr() const noexcept
Definition: memory_mapping.hpp:307
std::size_t m_size
The size of the mapping.
Definition: memory_mapping.hpp:109
static std::size_t available_space(int fd)
Definition: memory_mapping.hpp:156
int m_fd
File handle we got the mapping from.
Definition: memory_mapping.hpp:115
int flag_type
Definition: memory_mapping.hpp:134
void resize(std::size_t new_size)
Definition: memory_mapping.hpp:639
bool writable() const noexcept
Definition: memory_mapping.hpp:297
flag_type get_flags() const noexcept
Definition: memory_mapping.hpp:583
mapping_mode m_mapping_mode
Mapping mode.
Definition: memory_mapping.hpp:118
static std::size_t check_size(std::size_t size)
Definition: memory_mapping.hpp:141
void make_invalid() noexcept
Definition: memory_mapping.hpp:565
void * m_addr
The address where the memory is mapped.
Definition: memory_mapping.hpp:125
int fd() const noexcept
Definition: memory_mapping.hpp:290
MemoryMapping(std::size_t size, mapping_mode mode, int fd=-1, off_t offset=0)
Definition: memory_mapping.hpp:593
Definition: memory_mapping.hpp:351
~TypedMemoryMapping() noexcept=default
int fd() const noexcept
Definition: memory_mapping.hpp:463
void resize(std::size_t new_size)
Definition: memory_mapping.hpp:436
const T * end() const noexcept
Definition: memory_mapping.hpp:524
const T * cbegin() const noexcept
Definition: memory_mapping.hpp:497
TypedMemoryMapping & operator=(const TypedMemoryMapping &)=delete
You can not copy a TypedMemoryMapping.
const T * cend() const noexcept
Definition: memory_mapping.hpp:506
void unmap()
Definition: memory_mapping.hpp:422
TypedMemoryMapping(std::size_t size)
Definition: memory_mapping.hpp:363
const T * begin() const noexcept
Definition: memory_mapping.hpp:515
bool writable() const noexcept
Definition: memory_mapping.hpp:470
T * end() noexcept
Definition: memory_mapping.hpp:488
T * begin() noexcept
Definition: memory_mapping.hpp:479
TypedMemoryMapping(const TypedMemoryMapping &)=delete
You can not copy construct a TypedMemoryMapping.
std::size_t size() const noexcept
Definition: memory_mapping.hpp:453
TypedMemoryMapping & operator=(TypedMemoryMapping &&other) noexcept=default
TypedMemoryMapping(std::size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset=0)
Definition: memory_mapping.hpp:377
MemoryMapping m_mapping
Definition: memory_mapping.hpp:353
TypedMemoryMapping(TypedMemoryMapping &&other) noexcept=default
OSMIUM_DEPRECATED TypedMemoryMapping(std::size_t size, bool writable, int fd, off_t offset=0)
Definition: memory_mapping.hpp:386
#define OSMIUM_DEPRECATED
Definition: compatibility.hpp:51
#define MAP_ANONYMOUS
Definition: memory_mapping.hpp:573
void resize_file(int fd, std::size_t new_size)
Definition: file.hpp:177
std::size_t file_size(int fd)
Definition: file.hpp:109
std::size_t get_pagesize() noexcept
Definition: file.hpp:193
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
Definition: location.hpp:555