From 2acd11a39ec554ef390bb840175a11e108732379 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 26 Sep 2008 15:27:46 +0000 Subject: [PATCH] Add a new type of memory pool and factorize test code. SVN revision: 36267 --- legacy/eina/configure.in | 3 +- legacy/eina/src/lib/eina_mempool.c | 5 + legacy/eina/src/modules/mp/Makefile.am | 2 +- .../src/modules/mp/fixed_bitmap/Makefile.am | 24 ++ .../mp/fixed_bitmap/eina_fixed_bitmap.c | 234 ++++++++++++++++++ legacy/eina/src/tests/eina_test_mempool.c | 138 ++++------- 6 files changed, 319 insertions(+), 87 deletions(-) create mode 100644 legacy/eina/src/modules/mp/fixed_bitmap/Makefile.am create mode 100644 legacy/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c diff --git a/legacy/eina/configure.in b/legacy/eina/configure.in index 5ca73c6b51..16b851bc1e 100644 --- a/legacy/eina/configure.in +++ b/legacy/eina/configure.in @@ -126,7 +126,7 @@ EINA_CHECK_STATIC([chained-pool], [chained pool]) EINA_CHECK_STATIC([ememoa-fixed], [ememoa fixed]) EINA_CHECK_STATIC([ememoa-unknown], [ememoa unknown]) EINA_CHECK_STATIC([pass-through], [pass through]) - +EINA_CHECK_STATIC([fixed-bitmap], [fixed bitmap]) ### Checks for libraries @@ -333,6 +333,7 @@ src/modules/mp/chained_pool/Makefile src/modules/mp/ememoa_fixed/Makefile src/modules/mp/ememoa_unknown/Makefile src/modules/mp/pass_through/Makefile +src/modules/mp/fixed_bitmap/Makefile src/tests/Makefile ]) diff --git a/legacy/eina/src/lib/eina_mempool.c b/legacy/eina/src/lib/eina_mempool.c index 10f74abf8f..c404d37002 100644 --- a/legacy/eina/src/lib/eina_mempool.c +++ b/legacy/eina/src/lib/eina_mempool.c @@ -83,6 +83,11 @@ Eina_Bool ememoa_fixed_init(void); void ememoa_fixed_shutdown(void); #endif +#ifdef EINA_STATIC_BUILD_FIXED_BITMAP +Eina_Bool fixed_bitmap_init(void); +void fixed_bitmap_shutdown(void); +#endif + /*============================================================================* * Global * *============================================================================*/ diff --git a/legacy/eina/src/modules/mp/Makefile.am b/legacy/eina/src/modules/mp/Makefile.am index 8dc920adf7..641127ce84 100644 --- a/legacy/eina/src/modules/mp/Makefile.am +++ b/legacy/eina/src/modules/mp/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = chained_pool ememoa_fixed pass_through ememoa_unknown +SUBDIRS = chained_pool ememoa_fixed pass_through ememoa_unknown fixed_bitmap MAINTAINERCLEANFILES = \ Makefile.in \ No newline at end of file diff --git a/legacy/eina/src/modules/mp/fixed_bitmap/Makefile.am b/legacy/eina/src/modules/mp/fixed_bitmap/Makefile.am new file mode 100644 index 0000000000..36ce28d079 --- /dev/null +++ b/legacy/eina/src/modules/mp/fixed_bitmap/Makefile.am @@ -0,0 +1,24 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I. \ +-I$(top_srcdir)/src/include \ +@COVERAGE_CFLAGS@ + +if !EINA_STATIC_BUILD_FIXED_BITMAP + +controllerdir = $(libdir)/eina/mp/ +controller_LTLIBRARIES = eina_fixed_bitmap.la + +eina_fixed_bitmap_la_SOURCES = \ +eina_fixed_bitmap.c + +eina_fixed_bitmap_la_LIBADD = $(top_builddir)/src/lib/libeina.la @COVERAGE_LIBS@ +eina_fixed_bitmap_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version +eina_fixed_bitmap_la_LIBTOOLFLAGS = --tag=disable-static +eina_fixed_bitmap_la_DEPENDENCIES = $(top_builddir)/src/lib/libeina.la + +endif + +clean-local: + rm -rf *.gcno diff --git a/legacy/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c b/legacy/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c new file mode 100644 index 0000000000..54ed39df37 --- /dev/null +++ b/legacy/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c @@ -0,0 +1,234 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +/* EINA - EFL data type library + * Copyright (C) 2008 Cedric BAIL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "eina_inlist.h" +#include "eina_rbtree.h" +#include "eina_error.h" + +#include "eina_mempool.h" + +#include "eina_private.h" + +typedef struct _Eina_Fixed_Bitmap Eina_Fixed_Bitmap; +typedef struct _Eina_Fixed_Bitmap_Pool Eina_Fixed_Bitmap_Pool; + +struct _Eina_Fixed_Bitmap +{ + Eina_Rbtree *lookup; + Eina_Inlist *head; + + int item_size; +}; + +struct _Eina_Fixed_Bitmap_Pool +{ + EINA_RBTREE; + EINA_INLIST; + + uint32_t bitmask; +}; + +static inline int +_eina_rbtree_inlist_delta(void) +{ + Eina_Fixed_Bitmap_Pool tmp; + void *a = &tmp.__rbtree; + void *b = &tmp.__in_list; + + return a - b; +} + +static Eina_Rbtree_Direction +_eina_fixed_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, __UNUSED__ void *data) +{ + if (left - right < 0) + return EINA_RBTREE_LEFT; + return EINA_RBTREE_RIGHT; +} + +static int +_eina_fixed_cmp_key(const Eina_Rbtree *node, const void *key, __UNUSED__ int length, Eina_Fixed_Bitmap *mp) +{ + const void *a = node; + const void *b = key; + int delta; + int limit; + + limit = sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32; + delta = a - b; + + if (delta > 0) + return 1; + if (delta + limit < 0) + return -1; + return 0; +} + +static void +_eina_fixed_bitmap_pool_free(Eina_Fixed_Bitmap_Pool *pool, __UNUSED__ void *data) +{ + free(pool); +} + +static void * +eina_fixed_bitmap_malloc(void *data, __UNUSED__ unsigned int size) +{ + Eina_Fixed_Bitmap *mp = data; + Eina_Fixed_Bitmap_Pool *pool; + void *ptr; + int index; + + if (mp->head) + { + pool = (Eina_Fixed_Bitmap_Pool*) ((unsigned char*) mp->head + _eina_rbtree_inlist_delta()); + + if (pool->bitmask == 0) pool = NULL; + } + + if (!pool) + { + eina_error_set(0); + pool = malloc(sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32); + if (!pool) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + + pool->bitmask = 0xFFFFFFFF; + + mp->head = eina_inlist_prepend(mp->head, EINA_INLIST_GET(pool)); + mp->lookup = eina_rbtree_inline_insert(mp->lookup, EINA_RBTREE_GET(pool), EINA_RBTREE_CMP_NODE_CB(_eina_fixed_cmp), NULL); + } + + index = ffs(pool->bitmask) - 1; + pool->bitmask &= ~(1 << index); + ptr = (unsigned char*) (pool + 1) + index * mp->item_size; + + if (pool->bitmask == 0) + { + mp->head = eina_inlist_remove(mp->head, EINA_INLIST_GET(pool)); + mp->head = eina_inlist_append(mp->head, EINA_INLIST_GET(pool)); + } + + return ptr; +} + +#include +static void +eina_fixed_bitmap_free(void *data, void *ptr) +{ + Eina_Fixed_Bitmap *mp = data; + Eina_Fixed_Bitmap_Pool *pool; + void *a; + Eina_Bool push_front = EINA_FALSE; + int delta; + + pool = (Eina_Fixed_Bitmap_Pool*) eina_rbtree_inline_lookup(mp->lookup, + ptr, 0, + EINA_RBTREE_CMP_KEY_CB(_eina_fixed_cmp_key), mp); + if (!pool) return ; + if (pool->bitmask != 0xFFFFFFFF) push_front = EINA_TRUE; + + a = pool; + delta = (ptr - a - sizeof (Eina_Fixed_Bitmap_Pool)) / mp->item_size; + + assert(delta >= 0 && delta < 32); + + pool->bitmask |= (1 << (delta & 0x1F)); + + if (pool->bitmask == 0xFFFFFFFF) + { + mp->head = eina_inlist_remove(mp->head, EINA_INLIST_GET(pool)); + mp->lookup = eina_rbtree_inline_remove(mp->lookup, EINA_RBTREE_GET(pool), EINA_RBTREE_CMP_NODE_CB(_eina_fixed_cmp), NULL); + free(pool); + } + else if (push_front) + { + mp->head = eina_inlist_remove(mp->head, EINA_INLIST_GET(pool)); + mp->head = eina_inlist_prepend(mp->head, EINA_INLIST_GET(pool)); + } +} + +static void * +eina_fixed_bitmap_realloc(__UNUSED__ void *data, __UNUSED__ void *element, __UNUSED__ unsigned int size) +{ + return NULL; +} + +static void* +eina_fixed_bitmap_init(__UNUSED__ const char *context, __UNUSED__ const char *option, va_list args) +{ + Eina_Fixed_Bitmap *mp; + + mp = malloc(sizeof (Eina_Fixed_Bitmap)); + if (!mp) return NULL; + + mp->item_size = va_arg(args, int); + mp->lookup = NULL; + mp->head = NULL; + + return mp; +} + +static void +eina_fixed_bitmap_shutdown(void *data) +{ + Eina_Fixed_Bitmap *mp = data; + + eina_rbtree_delete(mp->lookup, EINA_RBTREE_FREE_CB(_eina_fixed_bitmap_pool_free), NULL); + free(mp); +} + +static Eina_Mempool_Backend mp_backend = { + .name ="fixed_bitmap", + .init = &eina_fixed_bitmap_init, + .shutdown = &eina_fixed_bitmap_shutdown, + .realloc = &eina_fixed_bitmap_realloc, + .alloc = &eina_fixed_bitmap_malloc, + .free = &eina_fixed_bitmap_free +}; + +Eina_Bool fixed_bitmap_init(void) +{ + return eina_mempool_register(&mp_backend); +} + +void fixed_bitmap_shutdown(void) +{ + eina_mempool_unregister(&mp_backend); +} + +#ifndef EINA_STATIC_BUILD_FIXED_BITMAP + +EINA_MODULE_INIT(fixed_bitmap_init); +EINA_MODULE_SHUTDOWN(fixed_bitmap_shutdown); + +#endif /* ! EINA_STATIC_BUILD_FIXED_BITMAP */ + diff --git a/legacy/eina/src/tests/eina_test_mempool.c b/legacy/eina/src/tests/eina_test_mempool.c index 27aa32153e..cf1208249f 100644 --- a/legacy/eina/src/tests/eina_test_mempool.c +++ b/legacy/eina/src/tests/eina_test_mempool.c @@ -25,7 +25,8 @@ static Eina_List *_modules; -static void _mempool_init(void) +static void +_mempool_init(void) { eina_mempool_init(); /* force modules to be loaded in case they are not installed */ @@ -33,13 +34,49 @@ static void _mempool_init(void) eina_module_list_load(_modules); } -static void _mempool_shutdown(void) +static void +_mempool_shutdown(void) { eina_module_list_delete(_modules); /* TODO delete the list */ eina_mempool_shutdown(); } +static void +_eina_mempool_test(Eina_Mempool *mp, Eina_Bool with_realloc, Eina_Bool with_gc) +{ + int *tbl[512]; + int i; + + fail_if(!mp); + + for (i = 0; i < 512; ++i) + { + tbl[i] = eina_mempool_alloc(mp, sizeof (int)); + fail_if(!tbl[i]); + *tbl[i] = i; + } + + for (i = 0; i < 512; ++i) + fail_if(*tbl[i] != i); + + for (i = 0; i < 256; ++i) + eina_mempool_free(mp, tbl[i]); + + if (with_realloc) + fail_if(eina_mempool_realloc(mp, tbl[500], 25) == NULL); + else + fail_if(eina_mempool_realloc(mp, tbl[500], 25) != NULL); + + if (with_gc) + { + eina_mempool_gc(mp); + eina_mempool_statistics(mp); + } + + eina_mempool_delete(mp); +} + START_TEST(eina_mempool_init_shutdown) { Eina_Mempool *mp; @@ -56,30 +93,11 @@ END_TEST START_TEST(eina_mempool_chained_mempool) { Eina_Mempool *mp; - int *tbl[512]; - int i; _mempool_init(); mp = eina_mempool_new("chained_mempool", "test", NULL, sizeof (int), 256); - fail_if(!mp); - - for (i = 0; i < 512; ++i) - { - tbl[i] = eina_mempool_alloc(mp, sizeof (int)); - fail_if(!tbl[i]); - *tbl[i] = i; - } - - for (i = 0; i < 512; ++i) - fail_if(*tbl[i] != i); - - for (i = 0; i < 256; ++i) - eina_mempool_free(mp, tbl[i]); - - fail_if(eina_mempool_realloc(mp, tbl[500], 25) != NULL); - - eina_mempool_delete(mp); + _eina_mempool_test(mp, EINA_FALSE, EINA_FALSE); _mempool_shutdown(); } @@ -88,30 +106,24 @@ END_TEST START_TEST(eina_mempool_pass_through) { Eina_Mempool *mp; - int *tbl[512]; - int i; _mempool_init(); mp = eina_mempool_new("pass_through", "test", NULL, sizeof (int), 8, 0); - fail_if(!mp); + _eina_mempool_test(mp, EINA_TRUE, EINA_FALSE); - for (i = 0; i < 512; ++i) - { - tbl[i] = eina_mempool_alloc(mp, sizeof (int)); - fail_if(!tbl[i]); - *tbl[i] = i; - } + _mempool_shutdown(); +} +END_TEST - for (i = 0; i < 512; ++i) - fail_if(*tbl[i] != i); +START_TEST(eina_mempool_fixed_bitmap) +{ + Eina_Mempool *mp; - for (i = 0; i < 256; ++i) - eina_mempool_free(mp, tbl[i]); + _mempool_init(); - fail_if(eina_mempool_realloc(mp, tbl[500], 25) == NULL); - - eina_mempool_delete(mp); + mp = eina_mempool_new("fixed_bitmap", "test", NULL, sizeof (int)); + _eina_mempool_test(mp, EINA_FALSE, EINA_FALSE); _mempool_shutdown(); } @@ -121,33 +133,11 @@ END_TEST START_TEST(eina_mempool_ememoa_fixed) { Eina_Mempool *mp; - int *tbl[512]; - int i; _mempool_init(); mp = eina_mempool_new("ememoa_fixed", "test", NULL, sizeof (int), 8, 0); - fail_if(!mp); - - for (i = 0; i < 512; ++i) - { - tbl[i] = eina_mempool_alloc(mp, sizeof (int)); - fail_if(!tbl[i]); - *tbl[i] = i; - } - - for (i = 0; i < 512; ++i) - fail_if(*tbl[i] != i); - - for (i = 0; i < 256; ++i) - eina_mempool_free(mp, tbl[i]); - - fail_if(eina_mempool_realloc(mp, tbl[500], 25) != NULL); - - eina_mempool_gc(mp); - eina_mempool_statistics(mp); - - eina_mempool_delete(mp); + _eina_mempool_test(mp, EINA_FALSE, EINA_TRUE); _mempool_shutdown(); } @@ -156,34 +146,11 @@ END_TEST START_TEST(eina_mempool_ememoa_unknown) { Eina_Mempool *mp; - int *tbl[512]; - int i; _mempool_init(); mp = eina_mempool_new("ememoa_unknown", "test", NULL, 0, 2, sizeof (int), 8, sizeof (int) * 2, 8); - fail_if(!mp); - - for (i = 0; i < 512; ++i) - { - tbl[i] = eina_mempool_alloc(mp, sizeof (int)); - fail_if(!tbl[i]); - *tbl[i] = i; - } - - for (i = 0; i < 512; ++i) - fail_if(*tbl[i] != i); - - for (i = 0; i < 256; ++i) - eina_mempool_free(mp, tbl[i]); - - for (i = 256; i < 512; ++i) - tbl[i] = eina_mempool_realloc(mp, tbl[i], 2 * sizeof (int)); - - eina_mempool_gc(mp); - eina_mempool_statistics(mp); - - eina_mempool_delete(mp); + _eina_mempool_test(mp, EINA_TRUE, EINA_TRUE); _mempool_shutdown(); } @@ -196,6 +163,7 @@ eina_test_mempool(TCase *tc) tcase_add_test(tc, eina_mempool_init_shutdown); tcase_add_test(tc, eina_mempool_chained_mempool); tcase_add_test(tc, eina_mempool_pass_through); + tcase_add_test(tc, eina_mempool_fixed_bitmap); #ifdef EINA_EMEMOA_SUPPORT tcase_add_test(tc, eina_mempool_ememoa_fixed); tcase_add_test(tc, eina_mempool_ememoa_unknown);