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 |