From 2f26ceafb49615c781551df1fd9f33a550a32b2a Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Tue, 20 Jun 2023 16:48:17 +0200 Subject: [PATCH] Switch dwarfs::mmap implementation to boost::iostreams::mapped_file --- CMakeLists.txt | 2 +- include/dwarfs/mmap.h | 10 ++--- src/dwarfs/mmap.cpp | 101 ++++++++++++++++-------------------------- 3 files changed, 44 insertions(+), 69 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33b3b70d..c5ed57a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,7 +160,7 @@ else() find_package(fmt 10.0 REQUIRED CONFIG PATHS "${CMAKE_CURRENT_BINARY_DIR}/fmtlib-install" NO_DEFAULT_PATH) endif() -list(APPEND DWARFS_BOOST_MODULES chrono date_time filesystem program_options system) +list(APPEND DWARFS_BOOST_MODULES chrono date_time filesystem iostreams program_options system) if(WITH_PYTHON) # TODO: would be nicer to be able to support a range of python versions diff --git a/include/dwarfs/mmap.h b/include/dwarfs/mmap.h index f5a7e429..9487d861 100644 --- a/include/dwarfs/mmap.h +++ b/include/dwarfs/mmap.h @@ -24,6 +24,8 @@ #include #include +#include + #include "dwarfs/mmif.h" namespace dwarfs { @@ -33,8 +35,6 @@ class mmap : public mmif { explicit mmap(const std::string& path); mmap(const std::string& path, size_t size); - ~mmap() noexcept override; - void const* addr() const override; size_t size() const override; @@ -43,9 +43,9 @@ class mmap : public mmif { std::error_code release_until(off_t offset) override; private: - int fd_; - size_t size_; - void* addr_; + boost::iostreams::mapped_file mutable mf_; +#ifndef _WIN32 off_t const page_size_; +#endif }; } // namespace dwarfs diff --git a/src/dwarfs/mmap.cpp b/src/dwarfs/mmap.cpp index b1763ce0..bbb3f2a3 100644 --- a/src/dwarfs/mmap.cpp +++ b/src/dwarfs/mmap.cpp @@ -19,109 +19,84 @@ * along with dwarfs. If not, see . */ +#include #include -#include +#ifndef _WIN32 #include -#include -#include - -#include +#endif #include "dwarfs/error.h" #include "dwarfs/mmap.h" namespace dwarfs { -namespace { - -int safe_open(const std::string& path) { - int fd = ::open(path.c_str(), O_RDONLY); - - if (fd == -1) { - DWARFS_THROW(system_error, fmt::format("open('{}')", path)); - } - - return fd; -} - -size_t safe_size(int fd) { - struct stat st; - if (::fstat(fd, &st) == -1) { - DWARFS_THROW(system_error, "fstat"); - } - return st.st_size; -} - -void* safe_mmap(int fd, size_t size) { - if (size == 0) { - DWARFS_THROW(runtime_error, "empty file"); - } - - void* addr = ::mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - - if (addr == MAP_FAILED) { - DWARFS_THROW(system_error, "mmap"); - } - - return addr; -} - -} // namespace - -std::error_code mmap::lock(off_t offset, size_t size) { +std::error_code +mmap::lock(off_t offset [[maybe_unused]], size_t size [[maybe_unused]]) { std::error_code ec; - auto addr = reinterpret_cast(addr_) + offset; - if (::mlock(addr, size) != 0) { + +#ifndef _WIN32 + if (::mlock(mf_.const_data() + offset, size) != 0) { ec.assign(errno, std::generic_category()); } +#endif + return ec; } -std::error_code mmap::release(off_t offset, size_t size) { +std::error_code +mmap::release(off_t offset [[maybe_unused]], size_t size [[maybe_unused]]) { std::error_code ec; + +#ifndef _WIN32 auto misalign = offset % page_size_; offset -= misalign; size += misalign; size -= size % page_size_; - auto addr = reinterpret_cast(addr_) + offset; - if (::madvise(addr, size, MADV_DONTNEED) != 0) { + if (::madvise(mf_.data() + offset, size, MADV_DONTNEED) != 0) { ec.assign(errno, std::generic_category()); } +#endif + return ec; } -std::error_code mmap::release_until(off_t offset) { +std::error_code mmap::release_until(off_t offset [[maybe_unused]]) { std::error_code ec; +#ifndef _WIN32 offset -= offset % page_size_; - if (::madvise(addr_, offset, MADV_DONTNEED) != 0) { + if (::madvise(mf_.data(), offset, MADV_DONTNEED) != 0) { ec.assign(errno, std::generic_category()); } +#endif + return ec; } -void const* mmap::addr() const { return addr_; } +void const* mmap::addr() const { return mf_.const_data(); } -size_t mmap::size() const { return size_; } +size_t mmap::size() const { return mf_.size(); } mmap::mmap(const std::string& path) - : fd_(safe_open(path)) - , size_(safe_size(fd_)) - , addr_(safe_mmap(fd_, size_)) - , page_size_(::sysconf(_SC_PAGESIZE)) {} + : mf_(path, boost::iostreams::mapped_file::readonly) +#ifndef _WIN32 + , page_size_(::sysconf(_SC_PAGESIZE)) +#endif +{ + assert(mf_.is_open()); +} mmap::mmap(const std::string& path, size_t size) - : fd_(safe_open(path)) - , size_(size) - , addr_(safe_mmap(fd_, size_)) - , page_size_(::sysconf(_SC_PAGESIZE)) {} - -mmap::~mmap() noexcept { - ::munmap(addr_, size_); - ::close(fd_); + : mf_(path, boost::iostreams::mapped_file::readonly, size) +#ifndef _WIN32 + , page_size_(::sysconf(_SC_PAGESIZE)) +#endif +{ + assert(mf_.is_open()); } + } // namespace dwarfs