forked from obhi-d/acl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpool_allocator.cpp
123 lines (108 loc) · 3.62 KB
/
pool_allocator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "acl/allocators/pool_allocator.hpp"
#include "acl/allocators/std_allocator_wrapper.hpp"
#include "catch2/catch_all.hpp"
#include <random>
// NOLINTBEGIN
TEST_CASE("Validate pool_allocator", "[pool_allocator]")
{
using namespace acl;
using allocator_t = pool_allocator<acl::config<acl::cfg::compute_stats>>;
struct trivial_object
{
std::uint8_t value[16];
};
struct record
{
trivial_object* data;
std::uint32_t count;
};
constexpr std::uint32_t k_atom_count = 1000;
acl::vector<record> records;
std::minstd_rand gen;
std::bernoulli_distribution dice(0.6);
std::uniform_int_distribution<std::uint32_t> generator(1, k_atom_count / 2);
allocator_t allocator(sizeof(trivial_object), k_atom_count);
auto validate = [&]()
{
return allocator.validate(records);
};
for (std::uint32_t allocs = 0; allocs < 10000; ++allocs)
{
if (dice(gen) || records.size() == 0)
{
record r;
r.count = dice(gen) ? 1 : generator(gen);
r.data = reinterpret_cast<trivial_object*>(allocator.allocate(r.count * sizeof(trivial_object)));
records.push_back(r);
CHECK(validate());
}
else
{
std::uniform_int_distribution<std::uint32_t> choose(0, static_cast<std::uint32_t>(records.size() - 1));
std::uint32_t chosen = choose(gen);
allocator.deallocate(records[chosen].data, records[chosen].count * sizeof(trivial_object));
records.erase(records.begin() + chosen);
CHECK(validate());
}
}
}
TEST_CASE("Validate pool_allocator with alignment", "[pool_allocator]")
{
using namespace acl;
using allocator_t = pool_allocator<acl::config<acl::cfg::compute_stats>>;
struct trivial_object
{
std::uint8_t value[16];
};
struct record
{
trivial_object* data;
std::uint32_t count;
};
constexpr std::uint32_t k_atom_count = 1000;
acl::vector<record> records;
std::minstd_rand gen;
std::bernoulli_distribution dice(0.6);
std::uniform_int_distribution<std::uint32_t> generator(1, k_atom_count / 2);
allocator_t allocator(sizeof(trivial_object), k_atom_count);
auto validate = [&]()
{
return allocator.validate(records);
};
for (std::uint32_t allocs = 0; allocs < 10000; ++allocs)
{
if (dice(gen) || records.size() == 0)
{
record r;
r.count = dice(gen) ? 1 : generator(gen);
r.data = reinterpret_cast<trivial_object*>(
allocator.allocate(r.count * sizeof(trivial_object), acl::alignarg<trivial_object>));
records.push_back(r);
assert(validate());
CHECK(validate());
}
else
{
std::uniform_int_distribution<std::uint32_t> choose(0, static_cast<std::uint32_t>(records.size() - 1));
std::uint32_t chosen = choose(gen);
allocator.deallocate(records[chosen].data, records[chosen].count * sizeof(trivial_object),
acl::alignarg<trivial_object>);
records.erase(records.begin() + chosen);
assert(validate());
CHECK(validate());
}
}
}
TEST_CASE("Validate std_allocator", "[std_allocator]")
{
using namespace acl;
acl::pool_allocator<> pool_allocator(8, 1000);
{
using std_allocator = acl::allocator_ref<std::uint64_t, acl::pool_allocator<>>;
std::vector<std::uint64_t, std_allocator> vlist =
std::vector<std::uint64_t, std_allocator>(std_allocator(pool_allocator));
for (std::uint64_t i = 0; i < 1000; ++i)
vlist.push_back(i);
}
}
// NOLINTEND