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 |
--- a/test/main.c Mon Jul 15 15:43:18 2013 +0200 +++ b/test/main.c Mon Jul 15 16:59:52 2013 +0200 @@ -153,6 +153,7 @@ ucx_test_register(suite, test_ucx_mempool_malloc); ucx_test_register(suite, test_ucx_mempool_malloc_with_chcap); ucx_test_register(suite, test_ucx_mempool_calloc); + ucx_test_register(suite, test_ucx_mempool_free); ucx_test_register(suite, test_ucx_mempool_set_destr); ucx_test_register(suite, test_ucx_mempool_reg_destr); ucx_test_register(suite, test_ucx_mempool_realloc);
--- a/test/mpool_tests.c Mon Jul 15 15:43:18 2013 +0200 +++ b/test/mpool_tests.c Mon Jul 15 16:59:52 2013 +0200 @@ -37,7 +37,7 @@ UCX_TEST_ASSERT(pool->ndata == 0, "uninitialized counter"); UCX_TEST_ASSERT(pool->data != NULL, "no memory addressed"); UCX_TEST_END - ucx_mempool_free(pool); + ucx_mempool_destroy(pool); } UCX_TEST_IMPLEMENT(test_ucx_mempool_malloc) { @@ -56,7 +56,7 @@ UCX_TEST_ASSERT(*test == 5, "wrong pointer"); UCX_TEST_END - ucx_mempool_free(pool); + ucx_mempool_destroy(pool); } UCX_TEST_IMPLEMENT(test_ucx_mempool_malloc_with_chcap) { @@ -76,7 +76,7 @@ UCX_TEST_ASSERT(*test == 5, "wrong pointer"); UCX_TEST_END - ucx_mempool_free(pool); + ucx_mempool_destroy(pool); } UCX_TEST_IMPLEMENT(test_ucx_mempool_calloc) { @@ -90,7 +90,37 @@ UCX_TEST_ASSERT(test[0] == 0 && test[1] == 0, "failed"); UCX_TEST_END - ucx_mempool_free(pool); + ucx_mempool_destroy(pool); +} + +UCX_TEST_IMPLEMENT(test_ucx_mempool_free) { + UcxMempool *pool = ucx_mempool_new(16); + void *mem1; + void *mem2; + + UCX_TEST_BEGIN + + mem1 = ucx_mempool_malloc(pool, 16); + ucx_mempool_free(pool, mem1); + + UCX_TEST_ASSERT(pool->ndata == 0, "mempool not empty"); + + ucx_mempool_malloc(pool, 16); + ucx_mempool_malloc(pool, 16); + mem1 = ucx_mempool_malloc(pool, 16); + ucx_mempool_malloc(pool, 16); + mem2 = ucx_mempool_malloc(pool, 16); + + ucx_mempool_free(pool, mem1); + + UCX_TEST_ASSERT(pool->ndata == 4, "wrong mempool size"); + + ucx_mempool_free(pool, mem2); + + UCX_TEST_ASSERT(pool->ndata == 3, "wrong mempool size"); + + UCX_TEST_END + ucx_mempool_destroy(pool); } void test_setdestr(void* elem) { @@ -118,7 +148,7 @@ UCX_TEST_ASSERT( test[0] == 5 && test[1] == (intptr_t) cb, "setdestr destroyed data") - ucx_mempool_free(pool); + ucx_mempool_destroy(pool); UCX_TEST_ASSERT(*cb == 42, "destructor not called"); @@ -146,7 +176,7 @@ UCX_TEST_ASSERT(*pooladdr == test_setdestr, "failed"); - ucx_mempool_free(pool); + ucx_mempool_destroy(pool); UCX_TEST_ASSERT(*cb == 42, "destructor not called"); UCX_TEST_END @@ -183,7 +213,7 @@ UCX_TEST_ASSERT( test[0] == 5 && test[1] == (intptr_t) cb, "realloc destroyed data") - ucx_mempool_free(pool); + ucx_mempool_destroy(pool); UCX_TEST_ASSERT(*cb == 42, "destructor not called");
--- a/test/mpool_tests.h Mon Jul 15 15:43:18 2013 +0200 +++ b/test/mpool_tests.h Mon Jul 15 16:59:52 2013 +0200 @@ -40,6 +40,7 @@ UCX_TEST_DECLARE(test_ucx_mempool_malloc); UCX_TEST_DECLARE(test_ucx_mempool_malloc_with_chcap); UCX_TEST_DECLARE(test_ucx_mempool_calloc); +UCX_TEST_DECLARE(test_ucx_mempool_free); UCX_TEST_DECLARE(test_ucx_mempool_set_destr); UCX_TEST_DECLARE(test_ucx_mempool_reg_destr); UCX_TEST_DECLARE(test_ucx_mempool_realloc);
--- a/ucx/mempool.c Mon Jul 15 15:43:18 2013 +0200 +++ b/ucx/mempool.c Mon Jul 15 16:59:52 2013 +0200 @@ -112,7 +112,7 @@ return newm + sizeof(ucx_destructor); } } - fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n", + fprintf(stderr, "FATAL: 0x%08"PRIxPTR" not in mpool 0x%08" PRIxPTR"\n", (intptr_t)ptr, (intptr_t)pool); exit(1); } else { @@ -120,14 +120,37 @@ } } -void ucx_mempool_free(UcxMempool *pool) { +void ucx_mempool_free(UcxMempool *pool, void *ptr) { + ucx_memchunk *chunk = (ucx_memchunk*)((char*)ptr-sizeof(ucx_destructor)); + for(size_t i=0 ; i<pool->ndata ; i++) { + if(chunk == pool->data[i]) { + if(chunk->destructor != NULL) { + chunk->destructor(&chunk->c); + } + free(chunk); + size_t last_index = pool->ndata - 1; + if(i != last_index) { + pool->data[i] = pool->data[last_index]; + } + pool->ndata--; + return; + } + } + fprintf(stderr, "FATAL: 0x%08"PRIxPTR" not in mpool 0x%08" PRIxPTR"\n", + (intptr_t)ptr, (intptr_t)pool); + exit(1); +} + +void ucx_mempool_destroy(UcxMempool *pool) { ucx_memchunk *chunk; for(size_t i=0 ; i<pool->ndata ; i++) { chunk = (ucx_memchunk*) pool->data[i]; - if(chunk->destructor != NULL) { - chunk->destructor(&chunk->c); + if(chunk) { + if(chunk->destructor != NULL) { + chunk->destructor(&chunk->c); + } + free(chunk); } - free(chunk); } free(pool->data); free(pool); @@ -145,3 +168,17 @@ rd->ptr = ptr; ucx_mempool_set_destr(rd, ucx_mempool_shared_destr); } + +UcxAllocator* ucx_mempool_allocator(UcxMempool *pool) { + UcxAllocator *allocator = (UcxAllocator*)ucx_mempool_malloc( + pool, sizeof(UcxAllocator)); + if(!allocator) { + return NULL; + } + allocator->malloc = (ucx_allocator_malloc)ucx_mempool_malloc; + allocator->calloc = (ucx_allocator_calloc)ucx_mempool_calloc; + allocator->realloc = (ucx_allocator_realloc)ucx_mempool_realloc; + allocator->free = (ucx_allocator_free)ucx_mempool_free; + allocator->pool = pool; + return allocator; +}
--- a/ucx/mempool.h Mon Jul 15 15:43:18 2013 +0200 +++ b/ucx/mempool.h Mon Jul 15 16:59:52 2013 +0200 @@ -45,10 +45,6 @@ size_t size; } UcxMempool; -#define UCX_ALLOCATOR_MEMPOOL(pool) {pool, \ - (ucx_allocator_malloc) ucx_mempool_malloc, \ - (ucx_allocator_calloc) ucx_mempool_calloc, \ - (ucx_allocator_realloc) ucx_mempool_realloc} #define ucx_mempool_new_default() ucx_mempool_new(16) UcxMempool *ucx_mempool_new(size_t n); @@ -57,12 +53,14 @@ void *ucx_mempool_malloc(UcxMempool *pool, size_t n); void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize); void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n); +void ucx_mempool_free(UcxMempool *pool, void *ptr); -void ucx_mempool_free(UcxMempool *pool); +void ucx_mempool_destroy(UcxMempool *pool); void ucx_mempool_set_destr(void *ptr, ucx_destructor func); void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr); +UcxAllocator* ucx_mempool_allocator(UcxMempool *pool); #ifdef __cplusplus }