20 #ifndef RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
21 #define RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
23 #include <ripple/beast/type_name.h>
25 #include <boost/align.hpp>
26 #include <boost/container/static_vector.hpp>
27 #include <boost/predef.h>
42 template <
typename Type>
47 "SlabAllocator: the requested object must be larger than a pointer.");
49 static_assert(
alignof(Type) == 8 ||
alignof(Type) == 4);
79 while (data + item <=
p_ +
size_)
220 auto slab =
slabs_.load();
222 while (slab !=
nullptr)
224 if (
auto ret = slab->allocate())
240 if (!buf) [[unlikely]]
250 madvise(buf,
size, MADV_HUGEPAGE);
255 auto slabData =
reinterpret_cast<void*
>(
261 if (!boost::alignment::align(
264 boost::alignment::aligned_free(buf);
275 while (!
slabs_.compare_exchange_weak(
278 std::memory_order_release,
279 std::memory_order_relaxed))
299 for (
auto slab =
slabs_.load(); slab !=
nullptr; slab = slab->next_)
303 slab->deallocate(ptr);
313 template <
typename Type>
318 boost::container::static_vector<SlabAllocator<Type>, 64>
allocators_;
362 "SlabAllocatorSet<" + beast::type_name<Type>() +
363 ">: duplicate slab size");
366 for (
auto const& c : cfg)
368 auto& a =
allocators_.emplace_back(c.extra, c.alloc, c.align);
398 if (
auto const size =
sizeof(Type) + extra; size <=
maxSize_)
402 if (a.size() >= size)
422 if (a.deallocate(ptr))
432 #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)