mirror of
https://github.com/mhx/dwarfs.git
synced 2025-08-04 02:06:22 -04:00
refactor: simplify OS abstraction for mmap_block and fix move ops
This commit is contained in:
parent
6cf07409dc
commit
b0bc9b20c4
@ -44,60 +44,73 @@ namespace dwarfs::reader {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
class mmap_block {
|
class mmap_block {
|
||||||
public:
|
public:
|
||||||
mmap_block(size_t size)
|
mmap_block(size_t size)
|
||||||
: data_{::VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
|
: data_{allocate(size)}
|
||||||
PAGE_READWRITE)}
|
, size_{size} {}
|
||||||
, size_{size} {
|
|
||||||
if (!data_) {
|
mmap_block(mmap_block&& other) noexcept
|
||||||
|
: data_{other.data_}
|
||||||
|
, size_{other.size_} {
|
||||||
|
other.data_ = nullptr;
|
||||||
|
other.size_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mmap_block& operator=(mmap_block&& other) noexcept {
|
||||||
|
if (this != &other) {
|
||||||
|
mmap_block tmp{std::move(*this)};
|
||||||
|
data_ = other.data_;
|
||||||
|
size_ = other.size_;
|
||||||
|
other.data_ = nullptr;
|
||||||
|
other.size_ = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const { return size_; }
|
||||||
|
|
||||||
|
uint8_t* data() { return static_cast<uint8_t*>(data_); }
|
||||||
|
uint8_t const* data() const { return static_cast<uint8_t const*>(data_); }
|
||||||
|
|
||||||
|
~mmap_block() {
|
||||||
|
if (data_) {
|
||||||
|
deallocate(data_, size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void* allocate(size_t size) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
void* data =
|
||||||
|
::VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
if (!data) {
|
||||||
std::error_code ec(::GetLastError(), std::system_category());
|
std::error_code ec(::GetLastError(), std::system_category());
|
||||||
throw std::runtime_error("VirtualAlloc failed: " + ec.message());
|
throw std::runtime_error("VirtualAlloc failed: " + ec.message());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const { return size_; }
|
|
||||||
|
|
||||||
uint8_t* data() { return static_cast<uint8_t*>(data_); }
|
|
||||||
uint8_t const* data() const { return static_cast<uint8_t const*>(data_); }
|
|
||||||
|
|
||||||
~mmap_block() {
|
|
||||||
auto rv [[maybe_unused]] = ::VirtualFree(data_, 0, MEM_RELEASE);
|
|
||||||
assert(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void* data_;
|
|
||||||
size_t size_;
|
|
||||||
};
|
|
||||||
#else
|
#else
|
||||||
class mmap_block {
|
void* data = ::mmap(nullptr, size, PROT_READ | PROT_WRITE,
|
||||||
public:
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
mmap_block(size_t size)
|
if (data == MAP_FAILED) {
|
||||||
: data_{::mmap(nullptr, size, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)}
|
|
||||||
, size_{size} {
|
|
||||||
if (data_ == MAP_FAILED) {
|
|
||||||
throw std::runtime_error("mmap failed");
|
throw std::runtime_error("mmap failed");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const { return size_; }
|
static void deallocate(void* data, size_t size) {
|
||||||
|
#ifdef _WIN32
|
||||||
uint8_t* data() { return static_cast<uint8_t*>(data_); }
|
auto rv [[maybe_unused]] = ::VirtualFree(data, 0, MEM_RELEASE);
|
||||||
uint8_t const* data() const { return static_cast<uint8_t const*>(data_); }
|
assert(rv);
|
||||||
|
#else
|
||||||
~mmap_block() {
|
auto rv [[maybe_unused]] = ::munmap(data, size);
|
||||||
auto rv [[maybe_unused]] = ::munmap(data_, size_);
|
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void* data_;
|
void* data_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
class mmap_byte_buffer_impl : public mutable_byte_buffer_interface {
|
class mmap_byte_buffer_impl : public mutable_byte_buffer_interface {
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user