added mempool allocator

Mon, 15 Jul 2013 16:59:52 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 15 Jul 2013 16:59:52 +0200
changeset 113
8693d7874773
parent 112
6384016df2a3
child 114
5a0859739b76

added mempool allocator

test/main.c file | annotate | diff | comparison | revisions
test/mpool_tests.c file | annotate | diff | comparison | revisions
test/mpool_tests.h file | annotate | diff | comparison | revisions
ucx/mempool.c file | annotate | diff | comparison | revisions
ucx/mempool.h file | annotate | diff | comparison | revisions
     1.1 --- a/test/main.c	Mon Jul 15 15:43:18 2013 +0200
     1.2 +++ b/test/main.c	Mon Jul 15 16:59:52 2013 +0200
     1.3 @@ -153,6 +153,7 @@
     1.4          ucx_test_register(suite, test_ucx_mempool_malloc);
     1.5          ucx_test_register(suite, test_ucx_mempool_malloc_with_chcap);
     1.6          ucx_test_register(suite, test_ucx_mempool_calloc);
     1.7 +        ucx_test_register(suite, test_ucx_mempool_free);
     1.8          ucx_test_register(suite, test_ucx_mempool_set_destr);
     1.9          ucx_test_register(suite, test_ucx_mempool_reg_destr);
    1.10          ucx_test_register(suite, test_ucx_mempool_realloc);
     2.1 --- a/test/mpool_tests.c	Mon Jul 15 15:43:18 2013 +0200
     2.2 +++ b/test/mpool_tests.c	Mon Jul 15 16:59:52 2013 +0200
     2.3 @@ -37,7 +37,7 @@
     2.4      UCX_TEST_ASSERT(pool->ndata == 0, "uninitialized counter");
     2.5      UCX_TEST_ASSERT(pool->data != NULL, "no memory addressed");
     2.6      UCX_TEST_END
     2.7 -    ucx_mempool_free(pool);
     2.8 +    ucx_mempool_destroy(pool);
     2.9  }
    2.10  
    2.11  UCX_TEST_IMPLEMENT(test_ucx_mempool_malloc) {
    2.12 @@ -56,7 +56,7 @@
    2.13      UCX_TEST_ASSERT(*test == 5, "wrong pointer");
    2.14      
    2.15      UCX_TEST_END
    2.16 -    ucx_mempool_free(pool);
    2.17 +    ucx_mempool_destroy(pool);
    2.18  }
    2.19  
    2.20  UCX_TEST_IMPLEMENT(test_ucx_mempool_malloc_with_chcap) {
    2.21 @@ -76,7 +76,7 @@
    2.22      UCX_TEST_ASSERT(*test == 5, "wrong pointer");
    2.23      
    2.24      UCX_TEST_END
    2.25 -    ucx_mempool_free(pool);
    2.26 +    ucx_mempool_destroy(pool);
    2.27  }
    2.28  
    2.29  UCX_TEST_IMPLEMENT(test_ucx_mempool_calloc) {
    2.30 @@ -90,7 +90,37 @@
    2.31      UCX_TEST_ASSERT(test[0] == 0 && test[1] == 0, "failed");
    2.32      
    2.33      UCX_TEST_END
    2.34 -    ucx_mempool_free(pool);
    2.35 +    ucx_mempool_destroy(pool);
    2.36 +}
    2.37 +
    2.38 +UCX_TEST_IMPLEMENT(test_ucx_mempool_free) {
    2.39 +    UcxMempool *pool = ucx_mempool_new(16);
    2.40 +    void *mem1;
    2.41 +    void *mem2;
    2.42 +    
    2.43 +    UCX_TEST_BEGIN
    2.44 +    
    2.45 +    mem1 = ucx_mempool_malloc(pool, 16);
    2.46 +    ucx_mempool_free(pool, mem1);
    2.47 +    
    2.48 +    UCX_TEST_ASSERT(pool->ndata == 0, "mempool not empty");
    2.49 +    
    2.50 +    ucx_mempool_malloc(pool, 16);
    2.51 +    ucx_mempool_malloc(pool, 16);
    2.52 +    mem1 = ucx_mempool_malloc(pool, 16);
    2.53 +    ucx_mempool_malloc(pool, 16);
    2.54 +    mem2 = ucx_mempool_malloc(pool, 16);
    2.55 +    
    2.56 +    ucx_mempool_free(pool, mem1);
    2.57 +    
    2.58 +    UCX_TEST_ASSERT(pool->ndata == 4, "wrong mempool size");
    2.59 +    
    2.60 +    ucx_mempool_free(pool, mem2);
    2.61 +    
    2.62 +    UCX_TEST_ASSERT(pool->ndata == 3, "wrong mempool size");
    2.63 +    
    2.64 +    UCX_TEST_END
    2.65 +    ucx_mempool_destroy(pool);
    2.66  }
    2.67  
    2.68  void test_setdestr(void* elem) {
    2.69 @@ -118,7 +148,7 @@
    2.70      UCX_TEST_ASSERT(
    2.71              test[0] == 5 && test[1] == (intptr_t) cb, "setdestr destroyed data")
    2.72      
    2.73 -    ucx_mempool_free(pool);
    2.74 +    ucx_mempool_destroy(pool);
    2.75      
    2.76      UCX_TEST_ASSERT(*cb == 42, "destructor not called");
    2.77      
    2.78 @@ -146,7 +176,7 @@
    2.79      
    2.80      UCX_TEST_ASSERT(*pooladdr == test_setdestr, "failed");
    2.81      
    2.82 -    ucx_mempool_free(pool);
    2.83 +    ucx_mempool_destroy(pool);
    2.84      UCX_TEST_ASSERT(*cb == 42, "destructor not called");
    2.85      UCX_TEST_END
    2.86  
    2.87 @@ -183,7 +213,7 @@
    2.88      UCX_TEST_ASSERT(
    2.89              test[0] == 5 && test[1] == (intptr_t) cb, "realloc destroyed data")
    2.90      
    2.91 -    ucx_mempool_free(pool);
    2.92 +    ucx_mempool_destroy(pool);
    2.93      
    2.94      UCX_TEST_ASSERT(*cb == 42, "destructor not called");
    2.95      
     3.1 --- a/test/mpool_tests.h	Mon Jul 15 15:43:18 2013 +0200
     3.2 +++ b/test/mpool_tests.h	Mon Jul 15 16:59:52 2013 +0200
     3.3 @@ -40,6 +40,7 @@
     3.4  UCX_TEST_DECLARE(test_ucx_mempool_malloc);
     3.5  UCX_TEST_DECLARE(test_ucx_mempool_malloc_with_chcap);
     3.6  UCX_TEST_DECLARE(test_ucx_mempool_calloc);
     3.7 +UCX_TEST_DECLARE(test_ucx_mempool_free);
     3.8  UCX_TEST_DECLARE(test_ucx_mempool_set_destr);
     3.9  UCX_TEST_DECLARE(test_ucx_mempool_reg_destr);
    3.10  UCX_TEST_DECLARE(test_ucx_mempool_realloc);
     4.1 --- a/ucx/mempool.c	Mon Jul 15 15:43:18 2013 +0200
     4.2 +++ b/ucx/mempool.c	Mon Jul 15 16:59:52 2013 +0200
     4.3 @@ -112,7 +112,7 @@
     4.4                  return newm + sizeof(ucx_destructor);
     4.5              }
     4.6          }
     4.7 -        fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
     4.8 +        fprintf(stderr, "FATAL: 0x%08"PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
     4.9            (intptr_t)ptr, (intptr_t)pool);
    4.10          exit(1);
    4.11      } else {
    4.12 @@ -120,14 +120,37 @@
    4.13      }
    4.14  }
    4.15  
    4.16 -void ucx_mempool_free(UcxMempool *pool) {
    4.17 +void ucx_mempool_free(UcxMempool *pool, void *ptr) {
    4.18 +    ucx_memchunk *chunk = (ucx_memchunk*)((char*)ptr-sizeof(ucx_destructor));
    4.19 +    for(size_t i=0 ; i<pool->ndata ; i++) {
    4.20 +        if(chunk == pool->data[i]) {
    4.21 +            if(chunk->destructor != NULL) {
    4.22 +                chunk->destructor(&chunk->c);
    4.23 +            }
    4.24 +            free(chunk);
    4.25 +            size_t last_index = pool->ndata - 1;
    4.26 +            if(i != last_index) {
    4.27 +                pool->data[i] = pool->data[last_index];
    4.28 +            }
    4.29 +            pool->ndata--;
    4.30 +            return;
    4.31 +        }
    4.32 +    }
    4.33 +    fprintf(stderr, "FATAL: 0x%08"PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
    4.34 +            (intptr_t)ptr, (intptr_t)pool);
    4.35 +    exit(1);
    4.36 +}
    4.37 +
    4.38 +void ucx_mempool_destroy(UcxMempool *pool) {
    4.39      ucx_memchunk *chunk;
    4.40      for(size_t i=0 ; i<pool->ndata ; i++) {
    4.41          chunk = (ucx_memchunk*) pool->data[i];
    4.42 -        if(chunk->destructor != NULL) {
    4.43 -            chunk->destructor(&chunk->c);
    4.44 +        if(chunk) {
    4.45 +            if(chunk->destructor != NULL) {
    4.46 +                chunk->destructor(&chunk->c);
    4.47 +            }
    4.48 +            free(chunk);
    4.49          }
    4.50 -        free(chunk);
    4.51      }
    4.52      free(pool->data);
    4.53      free(pool);
    4.54 @@ -145,3 +168,17 @@
    4.55      rd->ptr = ptr;
    4.56      ucx_mempool_set_destr(rd, ucx_mempool_shared_destr);
    4.57  }
    4.58 +
    4.59 +UcxAllocator* ucx_mempool_allocator(UcxMempool *pool) {
    4.60 +    UcxAllocator *allocator = (UcxAllocator*)ucx_mempool_malloc(
    4.61 +            pool, sizeof(UcxAllocator));
    4.62 +    if(!allocator) {
    4.63 +        return NULL;
    4.64 +    }
    4.65 +    allocator->malloc = (ucx_allocator_malloc)ucx_mempool_malloc;
    4.66 +    allocator->calloc = (ucx_allocator_calloc)ucx_mempool_calloc;
    4.67 +    allocator->realloc = (ucx_allocator_realloc)ucx_mempool_realloc;
    4.68 +    allocator->free = (ucx_allocator_free)ucx_mempool_free;
    4.69 +    allocator->pool = pool;
    4.70 +    return allocator;
    4.71 +}
     5.1 --- a/ucx/mempool.h	Mon Jul 15 15:43:18 2013 +0200
     5.2 +++ b/ucx/mempool.h	Mon Jul 15 16:59:52 2013 +0200
     5.3 @@ -45,10 +45,6 @@
     5.4      size_t size;
     5.5  } UcxMempool;
     5.6  
     5.7 -#define UCX_ALLOCATOR_MEMPOOL(pool) {pool, \
     5.8 -    (ucx_allocator_malloc) ucx_mempool_malloc, \
     5.9 -    (ucx_allocator_calloc) ucx_mempool_calloc, \
    5.10 -    (ucx_allocator_realloc) ucx_mempool_realloc}
    5.11  
    5.12  #define ucx_mempool_new_default() ucx_mempool_new(16)
    5.13  UcxMempool *ucx_mempool_new(size_t n);
    5.14 @@ -57,12 +53,14 @@
    5.15  void *ucx_mempool_malloc(UcxMempool *pool, size_t n);
    5.16  void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize);
    5.17  void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n);
    5.18 +void ucx_mempool_free(UcxMempool *pool, void *ptr);
    5.19  
    5.20 -void ucx_mempool_free(UcxMempool *pool);
    5.21 +void ucx_mempool_destroy(UcxMempool *pool);
    5.22  
    5.23  void ucx_mempool_set_destr(void *ptr, ucx_destructor func);
    5.24  void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr);
    5.25  
    5.26 +UcxAllocator* ucx_mempool_allocator(UcxMempool *pool);
    5.27  
    5.28  #ifdef	__cplusplus
    5.29  }

mercurial