Mon, 15 Jul 2013 16:59:52 +0200
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 }