|     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  |