| 32 #include "cx/mempool.h" |
32 #include "cx/mempool.h" |
| 33 |
33 |
| 34 CX_TEST(test_mempool_create) { |
34 CX_TEST(test_mempool_create) { |
| 35 CxMempool *pool = cxMempoolCreateSimple(16); |
35 CxMempool *pool = cxMempoolCreateSimple(16); |
| 36 CX_TEST_DO { |
36 CX_TEST_DO { |
| 37 CX_TEST_ASSERT(pool->auto_destr == NULL); |
37 CX_TEST_ASSERT(pool->destr == NULL); |
| |
38 CX_TEST_ASSERT(pool->destr2 == NULL); |
| |
39 CX_TEST_ASSERT(pool->destr2_data == NULL); |
| 38 CX_TEST_ASSERT(pool->allocator != NULL); |
40 CX_TEST_ASSERT(pool->allocator != NULL); |
| 39 CX_TEST_ASSERT(pool->allocator->cl != NULL); |
41 CX_TEST_ASSERT(pool->allocator->cl != NULL); |
| 40 CX_TEST_ASSERT(pool->allocator->data == pool); |
42 CX_TEST_ASSERT(pool->allocator->data == pool); |
| 41 CX_TEST_ASSERT(pool->allocator->cl->malloc != NULL); |
43 CX_TEST_ASSERT(pool->allocator->cl->malloc != NULL); |
| 42 CX_TEST_ASSERT(pool->allocator->cl->calloc != NULL); |
44 CX_TEST_ASSERT(pool->allocator->cl->calloc != NULL); |
| 84 static void test_mempool_destructor(cx_attr_unused void *mem) { |
86 static void test_mempool_destructor(cx_attr_unused void *mem) { |
| 85 test_mempool_destructor_called++; |
87 test_mempool_destructor_called++; |
| 86 } |
88 } |
| 87 |
89 |
| 88 CX_TEST(test_mempool_realloc) { |
90 CX_TEST(test_mempool_realloc) { |
| 89 CxMempool *pool = cxMempoolCreate(4, test_mempool_destructor); |
91 CxMempool *pool = cxMempoolCreateSimple(4); |
| 90 CX_TEST_DO { |
92 cxMempoolGlobalDestructor(pool, test_mempool_destructor); |
| 91 CX_TEST_ASSERT(pool->auto_destr == test_mempool_destructor); |
93 CX_TEST_DO { |
| |
94 CX_TEST_ASSERT(pool->destr == test_mempool_destructor); |
| 92 int *data = cxMalloc(pool->allocator, sizeof(int)); |
95 int *data = cxMalloc(pool->allocator, sizeof(int)); |
| 93 *data = 13; |
96 *data = 13; |
| 94 |
97 |
| 95 int *rdata = data; |
98 int *rdata = data; |
| 96 unsigned n = 1; |
99 unsigned n = 1; |
| 166 |
169 |
| 167 CX_TEST(test_mempool_transfer) { |
170 CX_TEST(test_mempool_transfer) { |
| 168 CxMempool *src = cxMempoolCreateSimple(4); |
171 CxMempool *src = cxMempoolCreateSimple(4); |
| 169 CxMempool *dest = cxMempoolCreateSimple(4); |
172 CxMempool *dest = cxMempoolCreateSimple(4); |
| 170 CX_TEST_DO { |
173 CX_TEST_DO { |
| |
174 // allocate the first object |
| |
175 int *c = cxMalloc(src->allocator, sizeof(int)); |
| |
176 // allocate the second object |
| |
177 c = cxMalloc(src->allocator, sizeof(int)); |
| 171 // check that the destructor functions are also transferred |
178 // check that the destructor functions are also transferred |
| 172 src->auto_destr = test_mempool_destructor; |
179 cxMempoolSetDestructor(c, test_mempool_destructor); |
| 173 |
|
| 174 // allocate first object |
|
| 175 int *c = cxMalloc(src->allocator, sizeof(int)); |
|
| 176 // allocate second object |
|
| 177 c = cxMalloc(src->allocator, sizeof(int)); |
|
| 178 // register foreign object |
180 // register foreign object |
| 179 c = malloc(sizeof(int)); |
181 c = malloc(sizeof(int)); |
| 180 cxMempoolRegister(src, c, test_mempool_destructor); |
182 cxMempoolRegister(src, c, test_mempool_destructor); |
| 181 |
183 |
| 182 // check source pool |
184 // check source pool |
| 183 CX_TEST_ASSERT(src->size == 3); |
185 CX_TEST_ASSERT(src->size == 2); |
| |
186 CX_TEST_ASSERT(src->registered_size == 1); |
| 184 const CxAllocator *old_allocator = src->allocator; |
187 const CxAllocator *old_allocator = src->allocator; |
| 185 CX_TEST_ASSERT(old_allocator->data == src); |
188 CX_TEST_ASSERT(old_allocator->data == src); |
| 186 |
189 |
| 187 // perform transfer |
190 // perform transfer |
| 188 int result = cxMempoolTransfer(src, dest); |
191 int result = cxMempoolTransfer(src, dest); |
| 189 CX_TEST_ASSERT(result == 0); |
192 CX_TEST_ASSERT(result == 0); |
| 190 |
193 |
| 191 // check transfer |
194 // check transfer |
| 192 CX_TEST_ASSERT(src->size == 0); |
195 CX_TEST_ASSERT(src->size == 0); |
| 193 CX_TEST_ASSERT(dest->size == 4); // 3 objects + the old allocator |
196 CX_TEST_ASSERT(dest->size == 2); |
| |
197 CX_TEST_ASSERT(src->registered_size == 0); |
| |
198 CX_TEST_ASSERT(dest->registered_size == 2); // 1 object + old allocator |
| 194 CX_TEST_ASSERT(src->allocator != old_allocator); |
199 CX_TEST_ASSERT(src->allocator != old_allocator); |
| 195 CX_TEST_ASSERT(old_allocator->data == dest); |
200 CX_TEST_ASSERT(old_allocator->data == dest); |
| 196 |
201 |
| 197 // verify that destroying old pool does nothing |
202 // verify that destroying old pool does nothing |
| 198 test_mempool_destructor_called = 0; |
203 test_mempool_destructor_called = 0; |
| 202 // cover illegal arguments |
207 // cover illegal arguments |
| 203 result = cxMempoolTransfer(dest, dest); |
208 result = cxMempoolTransfer(dest, dest); |
| 204 CX_TEST_ASSERT(result != 0); |
209 CX_TEST_ASSERT(result != 0); |
| 205 |
210 |
| 206 // verify that destroying new pool calls the destructors |
211 // verify that destroying new pool calls the destructors |
| 207 // but only three times (the old allocator has a different destructor) |
212 // but only two times (the old allocator has a different destructor) |
| 208 cxMempoolFree(dest); |
213 cxMempoolFree(dest); |
| 209 CX_TEST_ASSERT(test_mempool_destructor_called == 3); |
214 CX_TEST_ASSERT(test_mempool_destructor_called == 2); |
| 210 |
215 |
| 211 // free the foreign object |
216 // free the foreign object |
| 212 free(c); |
217 free(c); |
| 213 } |
218 } |
| 214 } |
219 } |
| 219 CX_TEST_DO { |
224 CX_TEST_DO { |
| 220 int *b = cxMalloc(src->allocator, sizeof(int)); |
225 int *b = cxMalloc(src->allocator, sizeof(int)); |
| 221 b = cxMalloc(src->allocator, sizeof(int)); |
226 b = cxMalloc(src->allocator, sizeof(int)); |
| 222 int *c = malloc(sizeof(int)); |
227 int *c = malloc(sizeof(int)); |
| 223 cxMempoolRegister(src, c, free); |
228 cxMempoolRegister(src, c, free); |
| 224 |
229 CX_TEST_ASSERT(src->size == 2); |
| 225 CX_TEST_ASSERT(src->size == 3); |
230 CX_TEST_ASSERT(src->registered_size == 1); |
| |
231 |
| 226 int result = cxMempoolTransferObject(src, dest, b); |
232 int result = cxMempoolTransferObject(src, dest, b); |
| 227 CX_TEST_ASSERT(result == 0); |
233 CX_TEST_ASSERT(result == 0); |
| 228 CX_TEST_ASSERT(src->size == 2); |
234 CX_TEST_ASSERT(src->size == 1); |
| 229 CX_TEST_ASSERT(dest->size == 1); |
235 CX_TEST_ASSERT(dest->size == 1); |
| 230 result = cxMempoolTransferObject(src, dest, b); |
236 result = cxMempoolTransferObject(src, dest, b); |
| 231 CX_TEST_ASSERT(result != 0); |
237 CX_TEST_ASSERT(result != 0); |
| 232 CX_TEST_ASSERT(src->size == 2); |
238 CX_TEST_ASSERT(src->size == 1); |
| 233 CX_TEST_ASSERT(dest->size == 1); |
239 CX_TEST_ASSERT(dest->size == 1); |
| |
240 |
| 234 // cannot transfer foreign memory this way |
241 // cannot transfer foreign memory this way |
| 235 result = cxMempoolTransferObject(src, dest, c); |
242 result = cxMempoolTransferObject(src, dest, c); |
| 236 CX_TEST_ASSERT(result != 0); |
243 CX_TEST_ASSERT(result != 0); |
| 237 CX_TEST_ASSERT(src->size == 2); |
244 CX_TEST_ASSERT(src->size == 1); |
| 238 CX_TEST_ASSERT(dest->size == 1); |
245 CX_TEST_ASSERT(dest->size == 1); |
| |
246 |
| 239 result = cxMempoolTransferObject(dest, dest, b); |
247 result = cxMempoolTransferObject(dest, dest, b); |
| 240 CX_TEST_ASSERT(result != 0); |
248 CX_TEST_ASSERT(result != 0); |
| 241 CX_TEST_ASSERT(src->size == 2); |
249 CX_TEST_ASSERT(src->size == 1); |
| 242 CX_TEST_ASSERT(dest->size == 1); |
250 CX_TEST_ASSERT(dest->size == 1); |
| 243 |
251 } |
| 244 cxMempoolFree(src); |
252 cxMempoolFree(src); |
| 245 cxMempoolFree(dest); |
253 cxMempoolFree(dest); |
| 246 // let valgrind check that everything worked |
254 // let valgrind check that everything worked |
| 247 } |
|
| 248 } |
255 } |
| 249 |
256 |
| 250 CxTestSuite *cx_test_suite_mempool(void) { |
257 CxTestSuite *cx_test_suite_mempool(void) { |
| 251 CxTestSuite *suite = cx_test_suite_new("mempool"); |
258 CxTestSuite *suite = cx_test_suite_new("mempool"); |
| 252 |
259 |