0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-28 17:52:54 +01:00

ircd::allocator: Add incore(); replace as fs::fincore() impl.

This commit is contained in:
Jason Volk 2020-11-01 05:19:31 -08:00
parent b1cc013132
commit 536a496bee
4 changed files with 90 additions and 43 deletions

View file

@ -46,6 +46,8 @@ namespace ircd::allocator
template<class T> T set(const string_view &var, T val);
bool trim(const size_t &pad = 0) noexcept; // malloc_trim(3)
size_t incore(const const_buffer &);
std::unique_ptr<char, decltype(&std::free)>
aligned_alloc(const size_t &align, const size_t &size);
}
@ -60,6 +62,7 @@ namespace ircd::allocator::je
namespace ircd
{
using allocator::aligned_alloc;
using allocator::incore;
}
/// Profiling counters. The purpose of this device is to gauge whether unwanted

View file

@ -29,7 +29,7 @@ namespace ircd::fs
std::string read(const fd &, const read_opts & = read_opts_default);
// Test whether bytes in the specified range are cached and should not block
bool fincore(const fd &, const size_t &, const read_opts & = read_opts_default);
bool incore(const fd &, const size_t &, const read_opts & = read_opts_default);
// Prefetch data for subsequent read(); offset given in opts (WILLNEED).
size_t prefetch(const fd &, const size_t &, const read_opts & = read_opts_default);

View file

@ -9,6 +9,7 @@
// full license for this software is available in the LICENSE file.
#include <RB_INC_SYS_RESOURCE_H
#include <RB_INC_SYS_MMAN_H
// Uncomment or -D this #define to enable our own crude but simple ability to
// profile dynamic memory usage. Global `new` and `delete` will be captured
@ -72,6 +73,83 @@ ircd::allocator::aligned_alloc(const size_t &alignment_,
};
}
size_t
ircd::allocator::incore(const const_buffer &buf)
{
const auto base
{
buffer::align(begin(buf), info::page_size)
};
const auto top
{
buffer::align_up(end(buf), info::page_size)
};
assert(base <= data(buf));
const auto below
{
std::distance(base, begin(buf))
};
assert(top >= data(buf) + size(buf));
const auto span
{
std::distance(base, top)
};
const auto above
{
std::distance(end(buf), top)
};
assert(span >= 0);
assert(above >= 0);
assert(below >= 0);
assert(above < ssize_t(info::page_size));
assert(below < ssize_t(info::page_size));
assert(below + ssize_t(size(buf)) + above == span);
auto remain(span), ret(0L);
thread_local uint8_t vec alignas(64) [4096];
for(auto i(0); i < span / ssizeof(vec) && remain > 0; ++i)
{
const auto len
{
std::min(ssizeof(vec) * ssize_t(info::page_size), remain)
};
assert(len > 0);
assert(len <= span);
const ssize_t vec_size
(
std::ceil(len / double(info::page_size))
);
assert(vec_size > 0);
assert(vec_size <= ssizeof(vec));
syscall(::mincore, mutable_cast(base), len, vec);
for(auto j(0); j < vec_size; ++j)
ret += (vec[j] & 0x01) * info::page_size;
remain -= len;
assert(remain >= 0);
if(!remain && (vec[vec_size - 1] & 0x01)) // last iteration
ret -= above;
assert(ret >= 0);
if(i == 0 && (vec[0] & 0x01)) // first iteration
ret -= below;
assert(ret >= 0);
}
assert(remain == 0);
assert(ret <= ssize_t(size(buf)));
assert(ret >= 0);
return ret;
}
//
// control panel
//

View file

@ -806,11 +806,6 @@ ircd::fs::flush(const fd &fd,
// fs/read.h
//
namespace ircd::fs
{
static bool fincore(void *const &map, const size_t &map_size, uint8_t *const &vec, const size_t &vec_size);
}
ircd::fs::read_opts
const ircd::fs::read_opts_default
{};
@ -828,13 +823,10 @@ ircd::fs::prefetch(const fd &fd,
}
bool
ircd::fs::fincore(const fd &fd,
const size_t &count,
const read_opts &opts)
ircd::fs::incore(const fd &fd,
const size_t &count,
const read_opts &opts)
{
using word_t = unsigned long long;
thread_local std::array<word_t, 64> tls_vec;
fs::map::opts map_opts;
map_opts.offset = buffer::align(opts.offset, info::page_size);
map_opts.blocking = false;
@ -848,44 +840,18 @@ ircd::fs::fincore(const fd &fd,
(map_size + info::page_size - 1) / info::page_size
};
const size_t &vec_size
{
std::max(map_pages / sizeof(word_t), 1UL)
};
const size_t &dynamic_vec_size
{
vec_size > tls_vec.size()?
vec_size:
0UL
};
std::vector<word_t> dynamic_vec(dynamic_vec_size);
auto *const vec
{
dynamic_vec_size?
dynamic_vec.data():
tls_vec.data()
};
assert(map_opts.offset % 4096 == 0);
const fs::map map
{
fd, map_opts, map_size
};
assert(vec_size > 0 && vec_size <= map_size);
return fincore(data(map), map_size, reinterpret_cast<uint8_t *>(vec), vec_size);
}
const size_t res
{
allocator::incore(map)
};
bool
ircd::fs::fincore(void *const &map,
const size_t &map_size,
uint8_t *const &vec,
const size_t &vec_size)
{
syscall(::mincore, map, map_size, vec);
return std::find(vec, vec + vec_size, 0UL) == vec + vec_size;
return res == map_size;
}
std::string