mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-11 21:35:27 -04:00
refactor(mmap): clean up madvise code and expose advise interface
This commit is contained in:
parent
54e2f68957
commit
c1da30db6b
@ -44,6 +44,9 @@ class mmap : public mmif {
|
||||
std::error_code release(file_off_t offset, size_t size) override;
|
||||
std::error_code release_until(file_off_t offset) override;
|
||||
|
||||
std::error_code advise(advice adv) override;
|
||||
std::error_code advise(advice adv, file_off_t offset, size_t size) override;
|
||||
|
||||
std::filesystem::path const& path() const override;
|
||||
|
||||
private:
|
||||
|
@ -32,6 +32,14 @@
|
||||
|
||||
namespace dwarfs {
|
||||
|
||||
enum class advice {
|
||||
normal,
|
||||
random,
|
||||
sequential,
|
||||
willneed,
|
||||
dontneed,
|
||||
};
|
||||
|
||||
class mmif : public boost::noncopyable {
|
||||
public:
|
||||
virtual ~mmif() = default;
|
||||
@ -59,6 +67,11 @@ class mmif : public boost::noncopyable {
|
||||
virtual std::error_code release(file_off_t offset, size_t size) = 0;
|
||||
virtual std::error_code release_until(file_off_t offset) = 0;
|
||||
|
||||
virtual std::error_code advise(advice adv) = 0;
|
||||
virtual std::error_code
|
||||
advise(advice adv, file_off_t offset, size_t size) = 0;
|
||||
|
||||
virtual std::filesystem::path const& path() const = 0;
|
||||
};
|
||||
|
||||
} // namespace dwarfs
|
||||
|
@ -48,6 +48,27 @@ uint64_t get_page_size() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
int posix_advice(advice adv) {
|
||||
switch (adv) {
|
||||
case advice::normal:
|
||||
return MADV_NORMAL;
|
||||
case advice::random:
|
||||
return MADV_RANDOM;
|
||||
case advice::sequential:
|
||||
return MADV_SEQUENTIAL;
|
||||
case advice::willneed:
|
||||
return MADV_WILLNEED;
|
||||
case advice::dontneed:
|
||||
return MADV_DONTNEED;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
|
||||
return MADV_NORMAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
boost::filesystem::path boost_from_std_path(std::filesystem::path const& p) {
|
||||
#ifdef _WIN32
|
||||
return boost::filesystem::path(p.wstring());
|
||||
@ -77,27 +98,28 @@ mmap::lock(file_off_t offset [[maybe_unused]], size_t size [[maybe_unused]]) {
|
||||
return ec;
|
||||
}
|
||||
|
||||
std::error_code mmap::release(file_off_t offset [[maybe_unused]],
|
||||
size_t size [[maybe_unused]]) {
|
||||
std::error_code
|
||||
mmap::advise(advice adv [[maybe_unused]], file_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 data = const_cast<char*>(mf_.const_data() + offset);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
//// TODO: this doesn't currently work
|
||||
// if (::VirtualFree(data, size, MEM_DECOMMIT) == 0) {
|
||||
// ec.assign(::GetLastError(), std::system_category());
|
||||
// }
|
||||
#else
|
||||
if (::madvise(data, size, MADV_DONTNEED) != 0) {
|
||||
auto misalign = offset % page_size_;
|
||||
|
||||
offset -= misalign;
|
||||
size += misalign;
|
||||
size -= size % page_size_;
|
||||
|
||||
auto data = const_cast<char*>(mf_.const_data() + offset);
|
||||
|
||||
int native_adv = posix_advice(adv);
|
||||
|
||||
if (::madvise(data, size, native_adv) != 0) {
|
||||
ec.assign(errno, std::generic_category());
|
||||
}
|
||||
#endif
|
||||
@ -105,27 +127,14 @@ std::error_code mmap::release(file_off_t offset [[maybe_unused]],
|
||||
return ec;
|
||||
}
|
||||
|
||||
std::error_code mmap::release_until(file_off_t offset [[maybe_unused]]) {
|
||||
std::error_code ec;
|
||||
std::error_code mmap::advise(advice adv) { return advise(adv, 0, size()); }
|
||||
|
||||
#ifndef _WIN32
|
||||
offset -= offset % page_size_;
|
||||
std::error_code mmap::release(file_off_t offset, size_t size) {
|
||||
return advise(advice::dontneed, offset, size);
|
||||
}
|
||||
|
||||
auto data = const_cast<char*>(mf_.const_data());
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
//// TODO: this doesn't currently work
|
||||
// if (::VirtualFree(data, offset, MEM_DECOMMIT) == 0) {
|
||||
// ec.assign(::GetLastError(), std::system_category());
|
||||
// }
|
||||
#else
|
||||
if (::madvise(data, offset, MADV_DONTNEED) != 0) {
|
||||
ec.assign(errno, std::generic_category());
|
||||
}
|
||||
#endif
|
||||
|
||||
return ec;
|
||||
std::error_code mmap::release_until(file_off_t offset) {
|
||||
return release(0, offset);
|
||||
}
|
||||
|
||||
void const* mmap::addr() const { return mf_.const_data(); }
|
||||
|
@ -57,6 +57,11 @@ class mmap_mock : public mmif {
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code advise(advice) override { return std::error_code(); }
|
||||
std::error_code advise(advice, file_off_t, size_t) override {
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string const data_;
|
||||
std::filesystem::path const path_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user