# HG changeset patch # User Olaf Wintermann # Date 1325361959 -3600 # Node ID 98ac89e3aa37b7e0d01cf175dcc9bcb8e05902d7 # Parent fe50a85e69e76916ca65d401beedd237f47df85f Added mempool diff -r fe50a85e69e7 -r 98ac89e3aa37 gcc.mk --- a/gcc.mk Sat Dec 31 19:10:29 2011 +0100 +++ b/gcc.mk Sat Dec 31 21:05:59 2011 +0100 @@ -31,7 +31,7 @@ AR = ar RM = rm -CFLAGS = -std=gnu99 +CFLAGS = -std=gnu99 -g LDFLAGS = ARFLAGS = -r RMFLAGS = -f diff -r fe50a85e69e7 -r 98ac89e3aa37 osx.mk --- a/osx.mk Sat Dec 31 19:10:29 2011 +0100 +++ b/osx.mk Sat Dec 31 21:05:59 2011 +0100 @@ -31,7 +31,7 @@ AR = ar RM = rm -CFLAGS = -std=gnu99 +CFLAGS = -std=gnu99 -g LDFLAGS = ARFLAGS = -r RMFLAGS = -f diff -r fe50a85e69e7 -r 98ac89e3aa37 suncc.mk --- a/suncc.mk Sat Dec 31 19:10:29 2011 +0100 +++ b/suncc.mk Sat Dec 31 21:05:59 2011 +0100 @@ -31,7 +31,7 @@ AR = ar RM = rm -CFLAGS = +CFLAGS = -g LDFLAGS = ARFLAGS = -r RMFLAGS = -f diff -r fe50a85e69e7 -r 98ac89e3aa37 test/Makefile --- a/test/Makefile Sat Dec 31 19:10:29 2011 +0100 +++ b/test/Makefile Sat Dec 31 21:05:59 2011 +0100 @@ -28,7 +28,7 @@ include ../$(CONF).mk -SRC = main.c list_tests.c +SRC = main.c list_tests.c mpool_tests.c OBJ = $(SRC:%.c=../build/%.$(OBJ_EXT)) diff -r fe50a85e69e7 -r 98ac89e3aa37 test/list_tests.h --- a/test/list_tests.h Sat Dec 31 19:10:29 2011 +0100 +++ b/test/list_tests.h Sat Dec 31 21:05:59 2011 +0100 @@ -13,7 +13,7 @@ #endif int dlist_tests(); -int list_tests();; +int list_tests(); #ifdef __cplusplus diff -r fe50a85e69e7 -r 98ac89e3aa37 test/main.c --- a/test/main.c Sat Dec 31 19:10:29 2011 +0100 +++ b/test/main.c Sat Dec 31 21:05:59 2011 +0100 @@ -30,17 +30,24 @@ #include #include "list_tests.h" +#include "mpool_tests.h" int main(int argc, char **argv) { - printf("UCX Tests\n---------\n\n"); + printf("UCX Tests\n---------\n"); - printf("UcxDlist Tests\n"); + printf("\nUcxDlist Tests\n"); if(dlist_tests()) { + fprintf(stderr, "dlist_tests failed\n"); + } + + printf("\nUcxList Tests\n"); + if(list_tests()) { fprintf(stderr, "list_tests failed\n"); } - printf("UcxList Tests\n"); - if(list_tests()) { - fprintf(stderr, "list_tests failed\n"); + + printf("\nUcxMemPool Tests\n"); + if(mpool_tests()) { + fprintf(stderr, "mpool_tests failed\n"); } return EXIT_SUCCESS; diff -r fe50a85e69e7 -r 98ac89e3aa37 test/mpool_tests.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/mpool_tests.c Sat Dec 31 21:05:59 2011 +0100 @@ -0,0 +1,79 @@ +/* + * + */ + +#include +#include +#include + +#include "mpool_tests.h" + +int cmp_value = 2; + +void int_destructor(int *ptr) { + if(*ptr != cmp_value) { + fprintf(stderr, "ucx_mempool_free failed: wrong order\n"); + return; + } + cmp_value += 2; +} + +void hello_destructor(char *str) { + if(strcmp(str, "Hello World!") != 0) { + fprintf(stderr, "ucx_mempool_reg_destr failed\n"); + } +} + +int mpool_tests() { + printf(" Test ucx_mempool_new\n"); + UcxMempool *pool = ucx_mempool_new(16); + + printf(" Test ucx_mempool_malloc\n"); + int *ptr1 = (int*)ucx_mempool_malloc(pool, sizeof(int)); + for(int i=0;i<256;i++) { + ucx_mempool_malloc(pool, i); + } + int *ptr2 = (int*)ucx_mempool_malloc(pool, sizeof(int)); + int *ptr3 = (int*)ucx_mempool_malloc(pool, sizeof(int)); + for(int i=0;i<256;i++) { + ucx_mempool_malloc(pool, i); + } + int *ptr4 = (int*)ucx_mempool_malloc(pool, sizeof(int)); + + *ptr1 = 2; + *ptr2 = 4; + *ptr3 = 6; + *ptr4 = 8; + + printf(" Test ucx_mempool_set_destr\n"); + ucx_mempool_set_destr(ptr1, (ucx_destructor)int_destructor); + ucx_mempool_set_destr(ptr2, (ucx_destructor)int_destructor); + ucx_mempool_set_destr(ptr3, (ucx_destructor)int_destructor); + ucx_mempool_set_destr(ptr4, (ucx_destructor)int_destructor); + + printf(" Test ucx_mempool_calloc\n"); + char *str = ucx_mempool_calloc(pool, 1, 3); + if(str[0] != 0 || str[1] != 0 || str[2] != 0) { + fprintf(stderr, "ucx_mempool_calloc failed\n"); + } + str[0] = 'O'; + str[1] = 'K'; + + printf(" Test ucx_mempool_realloc\n"); + str = ucx_mempool_realloc(pool, str, 4); + str[2] = '!'; + str[3] = 0; + if(strcmp(str, "OK!") != 0) { + fprintf(stderr, "Test ucx_mempool_realloc failed!\n"); + } + + printf(" Test ucx_mempool_reg_destr\n"); + char *hello = "Hello World!"; + ucx_mempool_reg_destr(pool, hello, (ucx_destructor)hello_destructor); + + printf(" Test ucx_mempool_free\n"); + ucx_mempool_free(pool); + + + return 0; +} diff -r fe50a85e69e7 -r 98ac89e3aa37 test/mpool_tests.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/mpool_tests.h Sat Dec 31 21:05:59 2011 +0100 @@ -0,0 +1,23 @@ +/* + * + */ + +#ifndef MPOOL_TESTS_H +#define MPOOL_TESTS_H + +#include "ucx/mpool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int mpool_tests(); + + + +#ifdef __cplusplus +} +#endif + +#endif /* MPOOL_TESTS_H */ + diff -r fe50a85e69e7 -r 98ac89e3aa37 ucx/Makefile --- a/ucx/Makefile Sat Dec 31 19:10:29 2011 +0100 +++ b/ucx/Makefile Sat Dec 31 21:05:59 2011 +0100 @@ -29,7 +29,7 @@ include ../$(CONF).mk # list of source files -SRC = list.c dlist.c map.c +SRC = list.c dlist.c map.c mpool.c OBJ = $(SRC:%.c=../build/%.$(OBJ_EXT)) diff -r fe50a85e69e7 -r 98ac89e3aa37 ucx/dlist.c --- a/ucx/dlist.c Sat Dec 31 19:10:29 2011 +0100 +++ b/ucx/dlist.c Sat Dec 31 21:05:59 2011 +0100 @@ -99,4 +99,4 @@ e = e->prev; } return e; -} \ No newline at end of file +} diff -r fe50a85e69e7 -r 98ac89e3aa37 ucx/mpool.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/mpool.c Sat Dec 31 21:05:59 2011 +0100 @@ -0,0 +1,101 @@ +/* + * + */ + +#include +#include +#include + +#include "mpool.h" + +typedef struct { + ucx_destructor destructor; + char c; +} ucx_memchunk; + +typedef struct { + ucx_destructor destructor; + void *ptr; +} ucx_regdestr; + +void ucx_mempool_shared_destr(void* ptr) { + ucx_regdestr *rd = (ucx_regdestr*)ptr; + rd->destructor(rd->ptr); +} + +UcxMempool *ucx_mempool_new(size_t n) { + UcxMempool *pool = (UcxMempool*)malloc(sizeof(UcxMempool*)); + pool->data = malloc(n * sizeof(void*)); + pool->ndata = 0; + pool->size = n; + return pool; +} + +void ucx_mempool_chcap(UcxMempool *pool, size_t newcap) { + void **data = realloc(pool->data, newcap*sizeof(void*)); + pool->data = data; + pool->size = newcap; +} + +void *ucx_mempool_malloc(UcxMempool *pool, size_t n) { + ucx_memchunk *mem = (ucx_memchunk*)malloc(sizeof(ucx_destructor) + n); + if(mem == NULL) { + return NULL; + } + + if (pool->ndata >= pool->size) { + ucx_mempool_chcap(pool, pool->size + 16); + } + + mem->destructor = NULL; + pool->data[pool->ndata] = mem; + pool->ndata++; + + return &mem->c; +} + +void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize) { + void *ptr = ucx_mempool_malloc(pool, nelem*elsize); + if(ptr == NULL) { + return NULL; + } + memset(ptr, 0, nelem * elsize); + return ptr; +} + +void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n) { + void *mem = ((char*)ptr) - sizeof(ucx_destructor); + for(int i=0;indata;i++) { + if(pool->data[i] == mem) { + mem == realloc(mem, n); + pool->data[i] = mem; + return mem; + } + } +} + +void ucx_mempool_free(UcxMempool *pool) { + ucx_memchunk *chunk; + for(int i=0;indata;i++) { + chunk = (ucx_memchunk*) pool->data[i]; + if(chunk->destructor != NULL) { + chunk->destructor(&chunk->c); + } + free(chunk); + } + free(pool->data); + free(pool); +} + +void ucx_mempool_set_destr(void *ptr, ucx_destructor func) { + *(ucx_destructor*)((char*)ptr-sizeof(ucx_destructor)) = func; +} + +void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr) { + ucx_regdestr *rd = (ucx_regdestr*)ucx_mempool_malloc( + pool, + sizeof(ucx_regdestr)); + rd->destructor = destr; + rd->ptr; + ucx_mempool_set_destr(rd, ucx_mempool_shared_destr); +} diff -r fe50a85e69e7 -r 98ac89e3aa37 ucx/mpool.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/mpool.h Sat Dec 31 21:05:59 2011 +0100 @@ -0,0 +1,39 @@ +/* + * + */ + +#ifndef MPOOL_H +#define MPOOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void(*ucx_destructor)(void*); + +typedef struct { + void **data; + size_t ndata; + size_t size; +} UcxMempool; + +#define ucx_mempool_new_default() ucx_mempool_new(16) +UcxMempool *ucx_mempool_new(size_t n); +void ucx_mempool_chcap(UcxMempool *pool, size_t newcap); + +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 ucx_mempool_set_destr(void *ptr, ucx_destructor func); +void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr); + + +#ifdef __cplusplus +} +#endif + +#endif /* MPOOL_H */ +