5
5
6
6
#include " pool.hpp"
7
7
8
+ #include < array>
8
9
#include < cstring>
9
10
#include < functional>
10
11
#include < random>
12
+ #include < string>
13
+ #include < thread>
11
14
12
15
#ifndef UMF_TEST_MEMORY_POOL_OPS_HPP
13
16
#define UMF_TEST_MEMORY_POOL_OPS_HPP
@@ -30,6 +33,7 @@ struct umfPoolTest : umf_test::test,
30
33
}
31
34
32
35
umf::pool_unique_handle_t pool;
36
+ static constexpr int NTHREADS = 5 ;
33
37
};
34
38
35
39
struct umfMultiPoolTest : umfPoolTest {
@@ -57,33 +61,196 @@ TEST_P(umfPoolTest, allocFree) {
57
61
umfPoolFree (pool.get (), ptr);
58
62
}
59
63
60
- TEST_P (umfPoolTest, pow2AlignedAlloc) {
61
- #ifdef _WIN32
62
- // TODO: implement support for windows
63
- GTEST_SKIP ();
64
- #endif
64
+ TEST_P (umfPoolTest, reallocFree) {
65
+ if (!umf_test::isReallocSupported (pool.get ())) {
66
+ GTEST_SKIP ();
67
+ }
68
+ static constexpr size_t allocSize = 64 ;
69
+ static constexpr size_t multiplier = 3 ;
70
+ auto *ptr = umfPoolMalloc (pool.get (), allocSize);
71
+ ASSERT_NE (ptr, nullptr );
72
+ auto *new_ptr = umfPoolRealloc (pool.get (), ptr, allocSize * multiplier);
73
+ ASSERT_NE (new_ptr, nullptr );
74
+ std::memset (new_ptr, 0 , allocSize * multiplier);
75
+ umfPoolFree (pool.get (), new_ptr);
76
+ }
65
77
78
+ TEST_P (umfPoolTest, callocFree) {
79
+ if (!umf_test::isCallocSupported (pool.get ())) {
80
+ GTEST_SKIP ();
81
+ }
82
+ static constexpr size_t num = 10 ;
83
+ static constexpr size_t size = sizeof (int );
84
+ auto *ptr = umfPoolCalloc (pool.get (), num, size);
85
+ ASSERT_NE (ptr, nullptr );
86
+ for (size_t i = 0 ; i < num; ++i) {
87
+ ASSERT_EQ (((int *)ptr)[i], 0 );
88
+ }
89
+ umfPoolFree (pool.get (), ptr);
90
+ }
91
+
92
+ void pow2AlignedAllocHelper (umf_memory_pool_handle_t pool) {
66
93
static constexpr size_t maxAlignment = (1u << 22 );
67
94
static constexpr size_t numAllocs = 4 ;
68
-
69
95
for (size_t alignment = 1 ; alignment <= maxAlignment; alignment <<= 1 ) {
70
96
std::cout << alignment << std::endl;
71
97
std::vector<void *> allocs;
72
98
73
99
for (size_t alloc = 0 ; alloc < numAllocs; alloc++) {
74
- auto *ptr = umfPoolAlignedMalloc (pool. get () , alignment, alignment);
100
+ auto *ptr = umfPoolAlignedMalloc (pool, alignment, alignment);
75
101
ASSERT_NE (ptr, nullptr );
76
102
ASSERT_TRUE (reinterpret_cast <uintptr_t >(ptr) % alignment == 0 );
77
103
std::memset (ptr, 0 , alignment);
78
104
allocs.push_back (ptr);
79
105
}
80
106
81
107
for (auto &ptr : allocs) {
82
- umfPoolFree (pool. get () , ptr);
108
+ umfPoolFree (pool, ptr);
83
109
}
84
110
}
85
111
}
86
112
113
+ TEST_P (umfPoolTest, pow2AlignedAlloc) {
114
+ #ifdef _WIN32
115
+ // TODO: implement support for windows
116
+ GTEST_SKIP ();
117
+ #endif
118
+ pow2AlignedAllocHelper (pool.get ());
119
+ }
120
+
121
+ TEST_P (umfPoolTest, freeNullptr) {
122
+ void *ptr = nullptr ;
123
+ auto ret = umfPoolFree (pool.get (), ptr);
124
+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
125
+ }
126
+
127
+ TEST_P (umfPoolTest, multiThreadedMallocFree) {
128
+ static constexpr size_t allocSize = 64 ;
129
+ auto poolMalloc = [](size_t allocSize, umf_memory_pool_handle_t pool) {
130
+ std::vector<void *> allocations;
131
+ for (size_t i = 0 ; i <= 10 ; ++i) {
132
+ allocations.emplace_back (umfPoolMalloc (pool, allocSize));
133
+ ASSERT_NE (allocations.back (), nullptr );
134
+ }
135
+
136
+ for (auto allocation : allocations) {
137
+ umfPoolFree (pool, allocation);
138
+ }
139
+ };
140
+
141
+ std::vector<std::thread> threads;
142
+ for (int i = 0 ; i < NTHREADS; i++) {
143
+ threads.emplace_back (poolMalloc, allocSize, pool.get ());
144
+ ;
145
+ }
146
+
147
+ for (auto &thread : threads) {
148
+ thread.join ();
149
+ }
150
+ }
151
+
152
+ TEST_P (umfPoolTest, multiThreadedpow2AlignedAlloc) {
153
+ #ifdef _WIN32
154
+ // TODO: implement support for windows
155
+ GTEST_SKIP ();
156
+ #endif
157
+
158
+ auto poolpow2AlignedAlloc = [](umf_memory_pool_handle_t pool) {
159
+ pow2AlignedAllocHelper (pool);
160
+ };
161
+
162
+ std::vector<std::thread> threads;
163
+ for (int i = 0 ; i < NTHREADS; i++) {
164
+ threads.emplace_back (poolpow2AlignedAlloc, pool.get ());
165
+ }
166
+
167
+ for (auto &thread : threads) {
168
+ thread.join ();
169
+ }
170
+ }
171
+
172
+ TEST_P (umfPoolTest, multiThreadedReallocFree) {
173
+ if (!umf_test::isReallocSupported (pool.get ())) {
174
+ GTEST_SKIP ();
175
+ }
176
+ static constexpr size_t allocSize = 64 ;
177
+ static constexpr size_t multiplier = 3 ;
178
+ auto poolRealloc = [](size_t allocSize, size_t multiplier,
179
+ umf_memory_pool_handle_t pool) {
180
+ std::vector<void *> allocations;
181
+ for (size_t i = 0 ; i <= 10 ; ++i) {
182
+ allocations.emplace_back (umfPoolMalloc (pool, allocSize));
183
+ ASSERT_NE (allocations.back (), nullptr );
184
+ }
185
+
186
+ for (auto allocation : allocations) {
187
+ auto *ptr =
188
+ umfPoolRealloc (pool, allocation, allocSize * multiplier);
189
+ umfPoolFree (pool, ptr);
190
+ }
191
+ };
192
+
193
+ std::vector<std::thread> threads;
194
+ for (int i = 0 ; i < NTHREADS; i++) {
195
+ threads.emplace_back (poolRealloc, allocSize, multiplier, pool.get ());
196
+ }
197
+
198
+ for (auto &thread : threads) {
199
+ thread.join ();
200
+ }
201
+ }
202
+
203
+ TEST_P (umfPoolTest, multiThreadedCallocFree) {
204
+ if (!umf_test::isCallocSupported (pool.get ())) {
205
+ GTEST_SKIP ();
206
+ }
207
+ static constexpr size_t num = 10 ;
208
+ auto poolCalloc = [](size_t num, size_t size,
209
+ umf_memory_pool_handle_t pool) {
210
+ std::vector<void *> allocations;
211
+ for (size_t i = 0 ; i <= 10 ; ++i) {
212
+ allocations.emplace_back (umfPoolCalloc (pool, num, size));
213
+ ASSERT_NE (allocations.back (), nullptr );
214
+ }
215
+
216
+ for (auto allocation : allocations) {
217
+ umfPoolFree (pool, allocation);
218
+ }
219
+ };
220
+
221
+ std::vector<std::thread> threads;
222
+ for (int i = 0 ; i < NTHREADS; i++) {
223
+ threads.emplace_back (poolCalloc, num, sizeof (int ), pool.get ());
224
+ }
225
+
226
+ for (auto &thread : threads) {
227
+ thread.join ();
228
+ }
229
+ }
230
+
231
+ TEST_P (umfPoolTest, multiThreadedMallocFreeRandomSizes) {
232
+ auto poolMalloc = [](size_t allocSize, umf_memory_pool_handle_t pool) {
233
+ std::vector<void *> allocations;
234
+ for (size_t i = 0 ; i <= 10 ; ++i) {
235
+ allocations.emplace_back (umfPoolMalloc (pool, allocSize));
236
+ ASSERT_NE (allocations.back (), nullptr );
237
+ }
238
+
239
+ for (auto allocation : allocations) {
240
+ umfPoolFree (pool, allocation);
241
+ }
242
+ };
243
+
244
+ std::vector<std::thread> threads;
245
+ for (int i = 0 ; i < NTHREADS; i++) {
246
+ threads.emplace_back (poolMalloc, rand () % 64 + 1 , pool.get ());
247
+ }
248
+
249
+ for (auto &thread : threads) {
250
+ thread.join ();
251
+ }
252
+ }
253
+
87
254
// TODO: add similar tests for realloc/aligned_alloc, etc.
88
255
// TODO: add multithreaded tests
89
256
TEST_P (umfMultiPoolTest, memoryTracking) {
0 commit comments