20template <std::
size_t MAX_BLOCK_SIZE_BYTES, std::
size_t ALIGN_BYTES>
21class PoolResourceFuzzer
26 size_t m_total_allocated{};
29 std::span<std::byte> span;
33 Entry(std::span<std::byte> s,
size_t a,
uint64_t se) : span(
s), alignment(
a), seed(
se) {}
36 std::vector<Entry> m_entries;
45 void Allocate(
size_t size,
size_t alignment)
49 assert((alignment & (alignment - 1)) == 0);
50 assert((size & (alignment - 1)) == 0);
52 auto span = std::span(
static_cast<std::byte*
>(m_test_resource.
Allocate(size, alignment)), size);
53 m_total_allocated += size;
55 auto ptr_val =
reinterpret_cast<std::uintptr_t
>(span.data());
65 if (m_total_allocated > 16
_MiB)
return;
66 size_t alignment_bits = m_provider.ConsumeIntegralInRange<
size_t>(0, 7);
70 Allocate(size, alignment);
80 std::vector<std::byte>
expect(entry.span.size());
85 void Deallocate(
const Entry& entry)
87 auto ptr_val =
reinterpret_cast<std::uintptr_t
>(entry.span.data());
90 m_total_allocated -= entry.span.size();
91 m_test_resource.
Deallocate(entry.span.data(), entry.span.size(), entry.alignment);
96 if (m_entries.empty()) {
100 size_t idx = m_provider.ConsumeIntegralInRange<
size_t>(0, m_entries.size() - 1);
101 Deallocate(m_entries[idx]);
102 if (idx != m_entries.size() - 1) {
103 m_entries[idx] = std::move(m_entries.back());
105 m_entries.pop_back();
110 while (!m_entries.empty()) {
123 [&] { Deallocate(); });
A memory resource similar to std::pmr::unsynchronized_pool_resource, but optimized for node-based con...
void Deallocate(void *p, std::size_t bytes, std::size_t alignment) noexcept
Returns a block to the freelists, or deletes the block when it did not come from the chunks.
void * Allocate(std::size_t bytes, std::size_t alignment)
Allocates a block of bytes.
static void CheckAllDataAccountedFor(const PoolResource< MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES > &resource)
Once all blocks are given back to the resource, tests that the freelists are consistent:
void fillrand(std::span< std::byte > span) noexcept
Fill a span with random bytes.
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
FuzzedDataProvider provider
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.