20 #ifndef RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
21 #define RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
23 #include <ripple/beast/type_name.h>
30 #include <boost/align.hpp>
31 #include <boost/container/static_vector.hpp>
32 #include <boost/predef.h>
40 template <
typename Type>
45 "SlabAllocator: the requested object must be larger than a pointer.");
47 static_assert(
alignof(Type) == 8 ||
alignof(Type) == 4);
77 while (data + item <=
p_ +
size_)
209 auto slab =
slabs_.load();
211 while (slab !=
nullptr)
213 if (
auto ret = slab->allocate())
229 if (!buf) [[unlikely]]
239 madvise(buf,
size, MADV_HUGEPAGE);
244 auto slabData =
reinterpret_cast<void*
>(
250 if (!boost::alignment::align(
253 boost::alignment::aligned_free(buf);
264 while (!
slabs_.compare_exchange_weak(
267 std::memory_order_release,
268 std::memory_order_relaxed))
288 for (
auto slab =
slabs_.load(); slab !=
nullptr; slab = slab->next_)
292 slab->deallocate(ptr);
302 template <
typename Type>
307 boost::container::static_vector<SlabAllocator<Type>, 64>
allocators_;
351 "SlabAllocatorSet<" + beast::type_name<Type>() +
352 ">: duplicate slab size");
355 for (
auto const& c : cfg)
357 auto& a =
allocators_.emplace_back(c.extra, c.alloc, c.align);
387 if (
auto const size =
sizeof(Type) + extra; size <=
maxSize_)
391 if (a.size() >= size)
411 if (a.deallocate(ptr))
421 #endif // RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
void deallocate(std::uint8_t *ptr) noexcept
Return an item to this allocator's freelist.
SlabAllocator & operator=(SlabAllocator const &other)=delete
std::uint8_t * allocate(std::size_t extra) noexcept
Returns a suitably aligned pointer, if one is available.
bool deallocate(std::uint8_t *ptr) noexcept
Returns the memory block to the allocator.
bool own(std::uint8_t const *p) const noexcept
Determines whether the given pointer belongs to this allocator.
constexpr SlabConfig(std::size_t extra_, std::size_t alloc_=0, std::size_t align_=alignof(Type))
SlabBlock & operator=(SlabBlock const &other)=delete
const std::size_t itemAlignment_
SlabAllocatorSet & operator=(SlabAllocatorSet const &other)=delete
SlabBlock(SlabBlock *next, std::uint8_t *data, std::size_t size, std::size_t item)
std::atomic< SlabBlock * > slabs_
constexpr auto megabytes(T value) noexcept
constexpr SlabAllocator(std::size_t extra, std::size_t alloc=0, std::size_t align=0)
Constructs a slab allocator able to allocate objects of a fixed size.
constexpr std::size_t size() const noexcept
Returns the size of the memory block this allocator returns.
bool deallocate(std::uint8_t *ptr) noexcept
Returns the memory block to the allocator.
std::uint8_t const *const p_
const std::size_t itemSize_
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::uint8_t * allocate() noexcept
Returns a suitably aligned pointer, if one is available.
boost::container::static_vector< SlabAllocator< Type >, 64 > allocators_
T adjacent_find(T... args)
const std::size_t slabSize_
A block of memory that is owned by a slab allocator.
A collection of slab allocators of various sizes for a given type.
std::uint8_t * allocate() noexcept
constexpr SlabAllocatorSet(std::vector< SlabConfig > cfg)