diff --git a/configure.ac b/configure.ac index 8be2d6dac..e7d76f8f3 100644 --- a/configure.ac +++ b/configure.ac @@ -1189,6 +1189,7 @@ AC_CHECK_FUNCS([ \ mlock2 \ mmap \ mprotect \ + mremap \ msync \ posix_fadvise \ posix_madvise \ diff --git a/include/ircd/fs/map.h b/include/ircd/fs/map.h index 876d6968a..54d8b4cc6 100644 --- a/include/ircd/fs/map.h +++ b/include/ircd/fs/map.h @@ -46,6 +46,7 @@ struct ircd::fs::map struct ircd::fs::map::opts :fd::opts { + uint alignment {0}; bool execute {false}; bool shared {false}; bool reserve {false}; diff --git a/ircd/fs.cc b/ircd/fs.cc index 72d1f9fab..82cab3d3f 100644 --- a/ircd/fs.cc +++ b/ircd/fs.cc @@ -2047,25 +2047,51 @@ ircd::fs::map::default_opts; ircd::fs::map::map(const fd &fd, const opts &opts, const size_t &size) +#if defined(HAVE_MMAP) { const auto map_size { size?: fs::size(fd) }; - #ifdef HAVE_MMAP - void *const &ptr + void *ptr { - ::mmap(nullptr, map_size, prot(opts), flags(opts), int(fd), opts.offset) + ::mmap + ( + nullptr, + map_size, + prot(opts), + flags(opts), + int(fd), + opts.offset + ) }; - #else - #error "Missing ::mmap(2) on this platform." - #endif if(unlikely(ptr == MAP_FAILED)) throw_system_error(errno); - static_cast(*this) = mutable_buffer + #if defined(HAVE_MREMAP) + if(opts.alignment && !aligned(ptr, opts.alignment)) + { + assert(opts.alignment > 1); + assert(opts.alignment > info::page_size); + ptr = ::mremap + ( + ptr, + map_size, + map_size, + MREMAP_FIXED | MREMAP_MAYMOVE, + align_up(ptr, opts.alignment) + pad_to(map_size, opts.alignment) + ); + + if(unlikely(ptr == MAP_FAILED)) + throw_system_error(errno); + } + #endif + + assert(aligned(ptr, opts.alignment)); + assert(padded(map_size, opts.alignment)); + static_cast(*this) = { reinterpret_cast(ptr), map_size @@ -2084,6 +2110,9 @@ ircd::fs::map::map(const fd &fd, if(advise) fs::advise(*this, advise, map_size); } +#else + #error "Missing mmap(2) on this platform." +#endif ircd::fs::map::~map() noexcept try