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
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
])
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 *
*============================================================================*/
-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
--- /dev/null
+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
--- /dev/null
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+
+#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 <stdio.h>
+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 */
+
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 */
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();
}
-START_TEST(eina_mempool_init_shutdown)
-{
- Eina_Mempool *mp;
-
- _mempool_init();
-
- mp = eina_mempool_new("test", "test", NULL);
- fail_if(mp != NULL);
-
- _mempool_shutdown();
-}
-END_TEST
-
-START_TEST(eina_mempool_chained_mempool)
+static void
+_eina_mempool_test(Eina_Mempool *mp, Eina_Bool with_realloc, Eina_Bool with_gc)
{
- 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)
for (i = 0; i < 256; ++i)
eina_mempool_free(mp, tbl[i]);
- fail_if(eina_mempool_realloc(mp, tbl[500], 25) != NULL);
+ 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;
+
+ _mempool_init();
+
+ mp = eina_mempool_new("test", "test", NULL);
+ fail_if(mp != NULL);
+
+ _mempool_shutdown();
+}
+END_TEST
+
+START_TEST(eina_mempool_chained_mempool)
+{
+ Eina_Mempool *mp;
+
+ _mempool_init();
+
+ mp = eina_mempool_new("chained_mempool", "test", NULL, sizeof (int), 256);
+ _eina_mempool_test(mp, EINA_FALSE, EINA_FALSE);
_mempool_shutdown();
}
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);
-
- for (i = 0; i < 512; ++i)
- {
- tbl[i] = eina_mempool_alloc(mp, sizeof (int));
- fail_if(!tbl[i]);
- *tbl[i] = i;
- }
+ _eina_mempool_test(mp, EINA_TRUE, EINA_FALSE);
- for (i = 0; i < 512; ++i)
- fail_if(*tbl[i] != i);
+ _mempool_shutdown();
+}
+END_TEST
- for (i = 0; i < 256; ++i)
- eina_mempool_free(mp, tbl[i]);
+START_TEST(eina_mempool_fixed_bitmap)
+{
+ Eina_Mempool *mp;
- fail_if(eina_mempool_realloc(mp, tbl[500], 25) == NULL);
+ _mempool_init();
- eina_mempool_delete(mp);
+ mp = eina_mempool_new("fixed_bitmap", "test", NULL, sizeof (int));
+ _eina_mempool_test(mp, EINA_FALSE, EINA_FALSE);
_mempool_shutdown();
}
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();
}
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();
}
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);