aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-09-16 10:57:48 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-09-16 10:57:48 +0000
commit785f2a6b3a70454ecfe94addc6480ebf20c44c13 (patch)
tree17a195d2c1f022cd480fd0e0b95be5035ad915e2 /src/modules
parentdfc0331373c3f98df7cb996abc588c7dcf44af0a (diff)
downloadefl-785f2a6b3a70454ecfe94addc6480ebf20c44c13.tar.gz
efl-785f2a6b3a70454ecfe94addc6480ebf20c44c13.tar.xz
efl-785f2a6b3a70454ecfe94addc6480ebf20c44c13.zip
merge : add eina
currently, examples, tests and benchmark are not set. That's the next things i'll do SVN revision: 76710
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/Makefile.am3
-rw-r--r--src/modules/eina/Makefile.am4
-rw-r--r--src/modules/eina/mp/Makefile.am45
-rw-r--r--src/modules/eina/mp/buddy/Makefile.am27
-rw-r--r--src/modules/eina/mp/buddy/eina_buddy.c292
-rw-r--r--src/modules/eina/mp/chained_pool/Makefile.am28
-rw-r--r--src/modules/eina/mp/chained_pool/eina_chained_mempool.c572
-rw-r--r--src/modules/eina/mp/ememoa_fixed/Makefile.am28
-rw-r--r--src/modules/eina/mp/ememoa_fixed/eina_ememoa_fixed.c176
-rw-r--r--src/modules/eina/mp/ememoa_unknown/Makefile.am28
-rw-r--r--src/modules/eina/mp/ememoa_unknown/eina_ememoa_unknown.c182
-rw-r--r--src/modules/eina/mp/fixed_bitmap/Makefile.am27
-rw-r--r--src/modules/eina/mp/fixed_bitmap/eina_fixed_bitmap.c270
-rw-r--r--src/modules/eina/mp/one_big/Makefile.am28
-rw-r--r--src/modules/eina/mp/one_big/eina_one_big.c336
-rw-r--r--src/modules/eina/mp/pass_through/Makefile.am27
-rw-r--r--src/modules/eina/mp/pass_through/eina_pass_through.c90
17 files changed, 2163 insertions, 0 deletions
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
new file mode 100644
index 000000000..b8f642fb7
--- /dev/null
+++ b/src/modules/Makefile.am
@@ -0,0 +1,3 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS = eina
diff --git a/src/modules/eina/Makefile.am b/src/modules/eina/Makefile.am
new file mode 100644
index 000000000..53e28b7bf
--- /dev/null
+++ b/src/modules/eina/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS = mp
+
+MAINTAINERCLEANFILES = \
+Makefile.in \ No newline at end of file
diff --git a/src/modules/eina/mp/Makefile.am b/src/modules/eina/mp/Makefile.am
new file mode 100644
index 000000000..435d57a96
--- /dev/null
+++ b/src/modules/eina/mp/Makefile.am
@@ -0,0 +1,45 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS =
+
+if EINA_BUILD_BUDDY
+if !EINA_STATIC_BUILD_BUDDY
+SUBDIRS += buddy
+endif
+endif
+
+if EINA_BUILD_CHAINED_POOL
+if !EINA_STATIC_BUILD_CHAINED_POOL
+SUBDIRS += chained_pool
+endif
+endif
+
+if EINA_BUILD_EMEMOA_FIXED
+if !EINA_STATIC_BUILD_EMEMOA_FIXED
+SUBDIRS += ememoa_fixed
+endif
+endif
+
+if EINA_BUILD_EMEMOA_UNKNOWN
+if !EINA_STATIC_BUILD_EMEMOA_UNKNOWN
+SUBDIRS += ememoa_unknown
+endif
+endif
+
+if EINA_BUILD_FIXED_BITMAP
+if !EINA_STATIC_BUILD_FIXED_BITMAP
+SUBDIRS += fixed_bitmap
+endif
+endif
+
+if EINA_BUILD_ONE_BIG
+if !EINA_STATIC_BUILD_ONE_BIG
+SUBDIRS += one_big
+endif
+endif
+
+if EINA_BUILD_PASS_THROUGH
+if !EINA_STATIC_BUILD_PASS_THROUGH
+SUBDIRS += pass_through
+endif
+endif
diff --git a/src/modules/eina/mp/buddy/Makefile.am b/src/modules/eina/mp/buddy/Makefile.am
new file mode 100644
index 000000000..e43db1aa8
--- /dev/null
+++ b/src/modules/eina/mp/buddy/Makefile.am
@@ -0,0 +1,27 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include/eina \
+-I$(top_builddir)/src/include/eina \
+-I$(top_srcdir)/src/lib/eina \
+-I$(top_builddir)/src/lib/eina \
+@EFL_EINA_BUILD@
+
+controllerdir = $(libdir)/eina/modules/mp/buddy/$(MODULE_ARCH)
+controller_LTLIBRARIES = module.la
+
+module_la_SOURCES = eina_buddy.c
+
+module_la_CFLAGS = @EINA_CFLAGS@
+module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+install-data-hook:
+ rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
+uninstall-hook:
+ rm -f $(DESTDIR)$(controllerdir)/module.*
+
+clean-local:
+ rm -rf *.gcno
diff --git a/src/modules/eina/mp/buddy/eina_buddy.c b/src/modules/eina/mp/buddy/eina_buddy.c
new file mode 100644
index 000000000..7d830dbfb
--- /dev/null
+++ b/src/modules/eina/mp/buddy/eina_buddy.c
@@ -0,0 +1,292 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2009 Jorge Luis Zapata Muga
+ *
+ * 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/>.
+ */
+
+/*
+ * This is a naive 'buddy' allocator following Knuth's documentation.
+ * The main difference is that we dont store the block information
+ * on the block memory itself but on another malloc'd area.
+ * This is useful for managing memory which isn't as fast as the main
+ * memory like the video memory
+ * The algorithm uses an area to store the linked list of blocks.
+ * Each block size is equal to the minimum allocatable block size for
+ * the memory pool and the number of blocks is equal to the size of the
+ * memory pool divided by the block size.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "eina_types.h"
+#include "eina_inlist.h"
+#include "eina_module.h"
+#include "eina_mempool.h"
+#include "eina_private.h"
+
+typedef struct _Block
+{
+ EINA_INLIST;
+ Eina_Bool available : 1;
+ unsigned short int order : 7; /* final order is order + min_order */
+} Block;
+
+typedef struct _Buddy
+{
+ void *heap; /* start address of the heap */
+ size_t size; /* total size in bytes of the heap */
+ unsigned int min_order; /* minimum size is 1 << min_order */
+ unsigned int max_order; /* maximum size is 1 << max_order */
+ unsigned int num_order; /* number of orders */
+ Eina_Inlist **areas; /* one area per order */
+ Block *blocks; /* the allocated block information */
+} Buddy;
+
+/* get the minimum order greater or equal to size */
+static inline unsigned int _get_order(Buddy *b, size_t size)
+{
+ unsigned int i;
+ size_t bytes;
+
+ bytes = 1 << b->min_order;
+ for (i = 0; bytes < size && i < b->num_order; i++)
+ {
+ bytes += bytes;
+ }
+ //printf("order for size %d is %d\n", size, i + b->min_order);
+ return i;
+}
+
+static inline void *_get_offset(Buddy *b, Block *block)
+{
+ void *ret;
+
+ ret = (char *)b->heap + ((block - &b->blocks[0]) << b->min_order);
+ return ret;
+}
+
+static void *_init(__UNUSED__ const char *context,
+ __UNUSED__ const char *options,
+ va_list args)
+{
+ Buddy *b;
+ int i;
+ size_t bytes;
+ size_t size;
+ size_t min_order;
+ void *heap;
+
+ heap = va_arg(args, void *);
+ size = va_arg(args, size_t);
+ min_order = va_arg(args, int);
+ /* the minimum order we support is 15 (32K) */
+ min_order = min_order < 15 ? 15 : min_order;
+ bytes = 1 << min_order;
+ for (i = 0; bytes <= size; i++)
+ {
+ bytes += bytes;
+ }
+ if (!i)
+ return NULL;
+
+ b = malloc(sizeof(Buddy));
+ b->heap = heap;
+ b->size = size;
+ b->min_order = min_order;
+ b->max_order = min_order + i - 1;
+ b->num_order = i;
+ b->areas = calloc(b->num_order, sizeof(Eina_Inlist *));
+ b->blocks = calloc(1 << (b->num_order - 1), sizeof(Block));
+ /* setup the initial free area */
+ b->blocks[0].available = EINA_TRUE;
+ b->areas[b->num_order - 1] = EINA_INLIST_GET(&(b->blocks[0]));
+
+ return b;
+}
+
+static void _shutdown(void *data)
+{
+ Buddy *b = data;
+
+ free(b->blocks);
+ free(b->areas);
+ free(b);
+}
+
+static void _free(void *data, void *element)
+{
+ Buddy *b = data;
+ Block *block, *buddy;
+ size_t offset;
+ size_t idx;
+
+ offset = (unsigned char *)element - (unsigned char *)b->heap;
+ if (offset > b->size)
+ return;
+
+ idx = offset >> b->min_order;
+ block = &b->blocks[idx];
+
+ //printf("free %x idx = %d order = %d buddy = %d\n", offset, idx, block->order, idx ^ (1 << block->order));
+ /* we should always work with the buddy at right */
+ if (idx & (1 << block->order))
+ {
+ Block *left;
+
+ idx = idx ^ (1 << block->order);
+ left = &b->blocks[idx];
+ if (!left->available)
+ goto end;
+ else
+ {
+ buddy = block;
+ block = left;
+ b->areas[block->order] = eina_inlist_remove(b->areas[block->order],
+ EINA_INLIST_GET(block));
+ block->order++;
+ }
+ }
+
+check:
+ /* already on the last order */
+ if (block->order + b->min_order == b->max_order)
+ {
+ goto end; /* get the buddy */
+
+ }
+
+ buddy = &b->blocks[idx ^ (1 << block->order)];
+ if (!buddy->available)
+ {
+ goto end; /* merge two blocks */
+
+ }
+
+ b->areas[block->order] = eina_inlist_remove(b->areas[block->order],
+ EINA_INLIST_GET(buddy));
+ block->order++;
+ goto check;
+end:
+ /* add the block to the free list */
+ block->available = EINA_TRUE;
+ b->areas[block->order] = eina_inlist_append(b->areas[block->order],
+ EINA_INLIST_GET(block));
+}
+
+static void *_alloc(void *data, unsigned int size)
+{
+ Buddy *b = data;
+ Block *block, *buddy;
+ unsigned int k, j;
+
+ k = j = _get_order(b, size);
+ /* get a free list of order k where k <= j <= max_order */
+ while ((j < b->num_order) && !b->areas[j])
+ j++;
+ /* check that the order is on our range */
+ if (j + b->min_order > b->max_order)
+ return NULL;
+
+ /* get a free element on this order, if not, go splitting until we find one */
+ //printf("getting order %d (%d) for size %d\n", j, k, size);
+found:
+ if (j == k)
+ {
+ void *ret;
+
+ block = EINA_INLIST_CONTAINER_GET(b->areas[j], Block);
+ block->available = EINA_FALSE;
+ block->order = j;
+ /* remove the block from the list */
+ b->areas[j] = eina_inlist_remove(b->areas[j], EINA_INLIST_GET(block));
+ ret = _get_offset(b, block);
+
+ return ret;
+ }
+
+ block = EINA_INLIST_CONTAINER_GET(b->areas[j], Block);
+ /* split */
+ b->areas[j] = eina_inlist_remove(b->areas[j], EINA_INLIST_GET(block));
+ j--;
+ b->areas[j] = eina_inlist_append(b->areas[j], EINA_INLIST_GET(block));
+ buddy = block + (1 << j);
+ buddy->order = j;
+ buddy->available = EINA_TRUE;
+ b->areas[j] = eina_inlist_append(b->areas[j], EINA_INLIST_GET(buddy));
+
+ goto found;
+}
+
+static void _statistics(void *data)
+{
+ Buddy *b = data;
+ unsigned int i;
+
+ printf("Information:\n");
+ printf(
+ "size = %zu, min_order = %d, max_order = %d, num_order = %d, num_blocks = %d (%uKB)\n",
+ b->size,
+ b->min_order,
+ b->max_order,
+ b->num_order,
+ 1 << b->num_order,
+ ((1 << (b->num_order)) * sizeof(Block)) / 1024);
+ printf("Area dumping:");
+ /* iterate over the free lists and dump the maps */
+ for (i = 0; i < b->num_order; i++)
+ {
+ Block *block;
+
+ printf("\n2^%d:", b->min_order + i);
+ EINA_INLIST_FOREACH(b->areas[i], block)
+ {
+ printf(" %d", (block - &b->blocks[0]));
+ }
+ }
+ printf("\nBlocks dumping:\n");
+}
+
+static Eina_Mempool_Backend _backend = {
+ "buddy",
+ &_init,
+ &_free,
+ &_alloc,
+ NULL, /* realloc */
+ NULL, /* garbage collect */
+ &_statistics,
+ &_shutdown,
+ NULL /* repack */
+};
+
+Eina_Bool buddy_init(void)
+{
+ return eina_mempool_register(&_backend);
+}
+
+void buddy_shutdown(void)
+{
+ eina_mempool_unregister(&_backend);
+}
+
+
+#ifndef EINA_STATIC_BUILD_BUDDY
+
+EINA_MODULE_INIT(buddy_init);
+EINA_MODULE_SHUTDOWN(buddy_shutdown);
+
+#endif /* ! EINA_STATIC_BUILD_BUDDY */
diff --git a/src/modules/eina/mp/chained_pool/Makefile.am b/src/modules/eina/mp/chained_pool/Makefile.am
new file mode 100644
index 000000000..4e9344581
--- /dev/null
+++ b/src/modules/eina/mp/chained_pool/Makefile.am
@@ -0,0 +1,28 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include/eina \
+-I$(top_builddir)/src/include/eina \
+-I$(top_srcdir)/src/lib/eina \
+-I$(top_builddir)/src/lib/eina \
+@EFL_EINA_BUILD@ \
+@VALGRIND_CFLAGS@
+
+controllerdir = $(libdir)/eina/modules/mp/chained_pool/$(MODULE_ARCH)
+controller_LTLIBRARIES = module.la
+
+module_la_SOURCES = eina_chained_mempool.c
+
+module_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@
+module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version @EFL_PTHREAD_LIBS@
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+install-data-hook:
+ rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
+uninstall-hook:
+ rm -f $(DESTDIR)$(controllerdir)/module.*
+
+clean-local:
+ rm -rf *.gcno
diff --git a/src/modules/eina/mp/chained_pool/eina_chained_mempool.c b/src/modules/eina/mp/chained_pool/eina_chained_mempool.c
new file mode 100644
index 000000000..e56df4cee
--- /dev/null
+++ b/src/modules/eina/mp/chained_pool/eina_chained_mempool.c
@@ -0,0 +1,572 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2008-2010 Cedric BAIL, Vincent Torri
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#ifdef EFL_HAVE_POSIX_THREADS
+#include <pthread.h>
+
+# ifdef EFL_DEBUG_THREADS
+# include <assert.h>
+# endif
+#endif
+
+#ifdef EINA_DEBUG_MALLOC
+# include <malloc.h>
+#endif
+
+#ifdef EFL_HAVE_WIN32_THREADS
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#include "eina_inlist.h"
+#include "eina_error.h"
+#include "eina_module.h"
+#include "eina_mempool.h"
+#include "eina_trash.h"
+#include "eina_rbtree.h"
+#include "eina_lock.h"
+
+#include "eina_private.h"
+
+#ifndef NVALGRIND
+# include <memcheck.h>
+#endif
+
+#if defined DEBUG || defined EINA_DEBUG_MALLOC
+#include <assert.h>
+#include "eina_log.h"
+
+static int _eina_chained_mp_log_dom = -1;
+
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_eina_chained_mp_log_dom, __VA_ARGS__)
+#endif
+
+typedef struct _Chained_Mempool Chained_Mempool;
+struct _Chained_Mempool
+{
+ Eina_Inlist *first;
+ Eina_Rbtree *root;
+ const char *name;
+ int item_alloc;
+ int pool_size;
+ int alloc_size;
+ int group_size;
+ int usage;
+#ifdef EINA_DEBUG_MALLOC
+ int minimal_size;
+#endif
+#ifdef EFL_DEBUG_THREADS
+ pthread_t self;
+#endif
+ Eina_Lock mutex;
+};
+
+typedef struct _Chained_Pool Chained_Pool;
+struct _Chained_Pool
+{
+ EINA_INLIST;
+ EINA_RBTREE;
+ Eina_Trash *base;
+ int usage;
+
+ unsigned char *last;
+ unsigned char *limit;
+};
+
+static inline Eina_Rbtree_Direction
+_eina_chained_mp_pool_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, __UNUSED__ void *data)
+{
+ if (left < right) return EINA_RBTREE_LEFT;
+ return EINA_RBTREE_RIGHT;
+}
+
+static inline int
+_eina_chained_mp_pool_key_cmp(const Eina_Rbtree *node, const void *key,
+ __UNUSED__ int length, __UNUSED__ void *data)
+{
+ const Chained_Pool *r = EINA_RBTREE_CONTAINER_GET(node, const Chained_Pool);
+
+ if (key > (void *) r->limit) return -1;
+ if (key < (void *) r) return 1;
+ return 0;
+}
+
+static inline Chained_Pool *
+_eina_chained_mp_pool_new(Chained_Mempool *pool)
+{
+ Chained_Pool *p;
+ unsigned char *ptr;
+ unsigned int alignof;
+
+ eina_error_set(0);
+ p = malloc(pool->alloc_size);
+ if (!p)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+#ifdef EINA_DEBUG_MALLOC
+ {
+ size_t sz;
+
+ sz = malloc_usable_size(p);
+ if (sz - pool->minimal_size > 0)
+ INF("Just allocated %0.2f%% to much memory in '%s' for one block of size %i that means %i bytes to much.",
+ ((float)(sz - pool->minimal_size) * 100) / (float) (pool->alloc_size),
+ pool->name,
+ pool->alloc_size,
+ sz - pool->minimal_size);
+ }
+#endif
+
+ alignof = eina_mempool_alignof(sizeof(Chained_Pool));
+ ptr = (unsigned char *)p + alignof;
+ p->usage = 0;
+ p->base = NULL;
+
+ p->last = ptr;
+ p->limit = ptr + pool->item_alloc * pool->pool_size;
+
+#ifndef NVALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS(ptr, pool->alloc_size - alignof);
+#endif
+
+ return p;
+}
+
+static inline void
+_eina_chained_mp_pool_free(Chained_Pool *p)
+{
+ free(p);
+}
+
+static int
+_eina_chained_mempool_usage_cmp(const Eina_Inlist *l1, const Eina_Inlist *l2)
+{
+ const Chained_Pool *p1;
+ const Chained_Pool *p2;
+
+ p1 = EINA_INLIST_CONTAINER_GET(l1, const Chained_Pool);
+ p2 = EINA_INLIST_CONTAINER_GET(l2, const Chained_Pool);
+
+ return p2->usage - p1->usage;
+}
+
+static void *
+_eina_chained_mempool_alloc_in(Chained_Mempool *pool, Chained_Pool *p)
+{
+ void *mem;
+
+ if (p->last)
+ {
+ mem = p->last;
+ p->last += pool->item_alloc;
+ if (p->last >= p->limit)
+ p->last = NULL;
+ }
+ else
+ {
+#ifndef NVALGRIND
+ VALGRIND_MAKE_MEM_DEFINED(p->base, pool->item_alloc);
+#endif
+ // Request a free pointer
+ mem = eina_trash_pop(&p->base);
+ }
+
+ // move to end - it just filled up
+ if (!p->base && !p->last)
+ pool->first = eina_inlist_demote(pool->first, EINA_INLIST_GET(p));
+
+ p->usage++;
+ pool->usage++;
+
+#ifndef NVALGRIND
+ VALGRIND_MEMPOOL_ALLOC(pool, mem, pool->item_alloc);
+#endif
+
+ return mem;
+}
+
+static Eina_Bool
+_eina_chained_mempool_free_in(Chained_Mempool *pool, Chained_Pool *p, void *ptr)
+{
+ void *pmem;
+
+ // pool mem base
+ pmem = (void *)(((unsigned char *)p) + sizeof(Chained_Pool));
+
+ // is it in pool mem?
+ if (ptr < pmem)
+ {
+#ifdef DEBUG
+ INF("%p is inside the private part of %p pool from %p Chained_Mempool (could be the sign of a buffer underrun).", ptr, p, pool);
+#endif
+ return EINA_FALSE;
+ }
+
+ // freed node points to prev free node
+ eina_trash_push(&p->base, ptr);
+ // next free node is now the one we freed
+ p->usage--;
+ pool->usage--;
+ if (p->usage == 0)
+ {
+ // free bucket
+ pool->first = eina_inlist_remove(pool->first, EINA_INLIST_GET(p));
+ pool->root = eina_rbtree_inline_remove(pool->root, EINA_RBTREE_GET(p),
+ _eina_chained_mp_pool_cmp, NULL);
+ _eina_chained_mp_pool_free(p);
+
+ return EINA_TRUE;
+ }
+ else
+ {
+ // move to front
+ pool->first = eina_inlist_promote(pool->first, EINA_INLIST_GET(p));
+ }
+
+ return EINA_FALSE;
+}
+
+static void *
+eina_chained_mempool_malloc(void *data, __UNUSED__ unsigned int size)
+{
+ Chained_Mempool *pool = data;
+ Chained_Pool *p = NULL;
+ void *mem;
+
+ if (!eina_lock_take(&pool->mutex))
+ {
+#ifdef EFL_DEBUG_THREADS
+ assert(pthread_equal(pool->self, pthread_self()));
+#endif
+ }
+
+ // Either we have some free space in the first one, or there is no free space.
+ if (pool->first) p = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool);
+
+ // base is not NULL - has a free slot
+ if (p && !p->base && !p->last)
+ p = NULL;
+
+#ifdef DEBUG
+ if (p == NULL)
+ EINA_INLIST_FOREACH(pool->first, p)
+ assert(!p->base && !p->last);
+#endif
+
+ // we have reached the end of the list - no free pools
+ if (!p)
+ {
+ p = _eina_chained_mp_pool_new(pool);
+ if (!p)
+ {
+ eina_lock_release(&pool->mutex);
+ return NULL;
+ }
+
+ pool->first = eina_inlist_prepend(pool->first, EINA_INLIST_GET(p));
+ pool->root = eina_rbtree_inline_insert(pool->root, EINA_RBTREE_GET(p),
+ _eina_chained_mp_pool_cmp, NULL);
+ }
+
+ mem = _eina_chained_mempool_alloc_in(pool, p);
+
+ eina_lock_release(&pool->mutex);
+
+ return mem;
+}
+
+static void
+eina_chained_mempool_free(void *data, void *ptr)
+{
+ Chained_Mempool *pool = data;
+ Eina_Rbtree *r;
+ Chained_Pool *p;
+
+ // look 4 pool
+ if (!eina_lock_take(&pool->mutex))
+ {
+#ifdef EFL_DEBUG_THREADS
+ assert(pthread_equal(pool->self, pthread_self()));
+#endif
+ }
+
+ // searching for the right mempool
+ r = eina_rbtree_inline_lookup(pool->root, ptr, 0, _eina_chained_mp_pool_key_cmp, NULL);
+
+ // related mempool not found
+ if (!r)
+ {
+#ifdef DEBUG
+ INF("%p is not the property of %p Chained_Mempool", ptr, pool);
+#endif
+ goto on_error;
+ }
+
+ p = EINA_RBTREE_CONTAINER_GET(r, Chained_Pool);
+
+ _eina_chained_mempool_free_in(pool, p, ptr);
+
+ on_error:
+#ifndef NVALGRIND
+ if (ptr)
+ {
+ VALGRIND_MEMPOOL_FREE(pool, ptr);
+ }
+#endif
+
+ eina_lock_release(&pool->mutex);
+ return;
+}
+
+static void
+eina_chained_mempool_repack(void *data,
+ Eina_Mempool_Repack_Cb cb,
+ void *cb_data)
+{
+ Chained_Mempool *pool = data;
+ Chained_Pool *start;
+ Chained_Pool *tail;
+
+ /* FIXME: Improvement - per Chained_Pool lock */
+ if (!eina_lock_take(&pool->mutex))
+ {
+#ifdef EFL_DEBUG_THREADS
+ assert(pthread_equal(pool->self, pthread_self()));
+#endif
+ }
+
+ pool->first = eina_inlist_sort(pool->first,
+ (Eina_Compare_Cb) _eina_chained_mempool_usage_cmp);
+
+ /*
+ idea : remove the almost empty pool at the beginning of the list by
+ moving data in the last pool with empty slot
+ */
+ tail = EINA_INLIST_CONTAINER_GET(pool->first->last, Chained_Pool);
+ while (tail && tail->usage == pool->pool_size)
+ tail = EINA_INLIST_CONTAINER_GET((EINA_INLIST_GET(tail)->prev), Chained_Pool);
+
+ while (tail)
+ {
+ unsigned char *src;
+ unsigned char *dst;
+
+ start = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool);
+
+ if (start == tail || start->usage == pool->pool_size)
+ break;
+
+ for (src = start->limit - pool->group_size;
+ src != start->limit;
+ src += pool->item_alloc)
+ {
+ Eina_Bool is_free = EINA_FALSE;
+ Eina_Bool is_dead;
+
+ /* Do we have something inside that piece of memory */
+ if (start->last != NULL && src >= start->last)
+ {
+ is_free = EINA_TRUE;
+ }
+ else
+ {
+ Eina_Trash *over = start->base;
+
+ while (over != NULL && (unsigned char*) over != src)
+ over = over->next;
+
+ if (over == NULL)
+ is_free = EINA_TRUE;
+ }
+
+ if (is_free) continue ;
+
+ /* get a new memory pointer from the latest most occuped pool */
+ dst = _eina_chained_mempool_alloc_in(pool, tail);
+ /* move data from one to another */
+ memcpy(dst, src, pool->item_alloc);
+ /* notify caller */
+ cb(dst, src, cb_data);
+ /* destroy old pointer */
+ is_dead = _eina_chained_mempool_free_in(pool, start, src);
+
+ /* search last tail with empty slot */
+ while (tail && tail->usage == pool->pool_size)
+ tail = EINA_INLIST_CONTAINER_GET((EINA_INLIST_GET(tail)->prev),
+ Chained_Pool);
+ /* no more free space */
+ if (!tail || tail == start) break;
+ if (is_dead) break;
+ }
+ }
+
+ /* FIXME: improvement - reorder pool so that the most used one get in front */
+ eina_lock_release(&pool->mutex);
+}
+
+static void *
+eina_chained_mempool_realloc(__UNUSED__ void *data,
+ __UNUSED__ void *element,
+ __UNUSED__ unsigned int size)
+{
+ return NULL;
+}
+
+static void *
+eina_chained_mempool_init(const char *context,
+ __UNUSED__ const char *option,
+ va_list args)
+{
+ Chained_Mempool *mp;
+ int item_size;
+ size_t length;
+
+ length = context ? strlen(context) + 1 : 0;
+
+ mp = calloc(1, sizeof(Chained_Mempool) + length);
+ if (!mp)
+ return NULL;
+
+ item_size = va_arg(args, int);
+ mp->pool_size = va_arg(args, int);
+
+ if (length)
+ {
+ mp->name = (const char *)(mp + 1);
+ memcpy((char *)mp->name, context, length);
+ }
+
+#ifdef EINA_DEBUG_MALLOC
+ mp->minimal_size = item_size * mp->pool_size + sizeof(Chained_Pool);
+#endif
+
+ mp->item_alloc = eina_mempool_alignof(item_size);
+ mp->group_size = mp->item_alloc * mp->pool_size;
+ mp->alloc_size = mp->group_size + eina_mempool_alignof(sizeof(Chained_Pool));
+
+#ifndef NVALGRIND
+ VALGRIND_CREATE_MEMPOOL(mp, 0, 1);
+#endif
+
+#ifdef EFL_DEBUG_THREADS
+ mp->self = pthread_self();
+#endif
+
+ eina_lock_new(&mp->mutex);
+
+ return mp;
+}
+
+static void
+eina_chained_mempool_shutdown(void *data)
+{
+ Chained_Mempool *mp;
+
+ mp = (Chained_Mempool *)data;
+
+ while (mp->first)
+ {
+ Chained_Pool *p = (Chained_Pool *)mp->first;
+
+#ifdef DEBUG
+ if (p->usage > 0)
+ INF("Bad news we are destroying not an empty mempool [%s]\n",
+ mp->name);
+
+#endif
+
+ mp->first = eina_inlist_remove(mp->first, mp->first);
+ mp->root = eina_rbtree_inline_remove(mp->root, EINA_RBTREE_GET(p),
+ _eina_chained_mp_pool_cmp, NULL);
+ _eina_chained_mp_pool_free(p);
+ }
+
+#ifdef DEBUG
+ if (mp->root)
+ INF("Bad news, list of pool and rbtree are out of sync for %p !", mp);
+#endif
+
+#ifndef NVALGRIND
+ VALGRIND_DESTROY_MEMPOOL(mp);
+#endif
+
+ eina_lock_free(&mp->mutex);
+
+#ifdef EFL_DEBUG_THREADS
+ assert(pthread_equal(mp->self, pthread_self()));
+#endif
+
+ free(mp);
+}
+
+static Eina_Mempool_Backend _eina_chained_mp_backend = {
+ "chained_mempool",
+ &eina_chained_mempool_init,
+ &eina_chained_mempool_free,
+ &eina_chained_mempool_malloc,
+ &eina_chained_mempool_realloc,
+ NULL,
+ NULL,
+ &eina_chained_mempool_shutdown,
+ &eina_chained_mempool_repack
+};
+
+Eina_Bool chained_init(void)
+{
+#if defined DEBUG || defined EINA_DEBUG_MALLOC
+ _eina_chained_mp_log_dom = eina_log_domain_register("eina_mempool",
+ EINA_LOG_COLOR_DEFAULT);
+ if (_eina_chained_mp_log_dom < 0)
+ {
+ EINA_LOG_ERR("Could not register log domain: eina_mempool");
+ return EINA_FALSE;
+ }
+
+#endif
+ return eina_mempool_register(&_eina_chained_mp_backend);
+}
+
+void chained_shutdown(void)
+{
+ eina_mempool_unregister(&_eina_chained_mp_backend);
+#if defined DEBUG || defined EINA_DEBUG_MALLOC
+ eina_log_domain_unregister(_eina_chained_mp_log_dom);
+ _eina_chained_mp_log_dom = -1;
+#endif
+}
+
+#ifndef EINA_STATIC_BUILD_CHAINED_POOL
+
+EINA_MODULE_INIT(chained_init);
+EINA_MODULE_SHUTDOWN(chained_shutdown);
+
+#endif /* ! EINA_STATIC_BUILD_CHAINED_POOL */
diff --git a/src/modules/eina/mp/ememoa_fixed/Makefile.am b/src/modules/eina/mp/ememoa_fixed/Makefile.am
new file mode 100644
index 000000000..50a4115ad
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_fixed/Makefile.am
@@ -0,0 +1,28 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include/eina \
+-I$(top_builddir)/src/include/eina \
+-I$(top_srcdir)/src/lib/eina \
+-I$(top_builddir)/src/lib/eina \
+@EMEMOA_CFLAGS@ \
+@EFL_EINA_BUILD@
+
+controllerdir = $(libdir)/eina/modules/mp/ememoa_fixed/$(MODULE_ARCH)
+controller_LTLIBRARIES = module.la
+
+module_la_SOURCES = eina_ememoa_fixed.c
+
+module_la_CFLAGS = @EINA_CFLAGS@
+module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EMEMOA_LIBS@ @EINA_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+install-data-hook:
+ rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
+uninstall-hook:
+ rm -f $(DESTDIR)$(controllerdir)/module.*
+
+clean-local:
+ rm -rf *.gcno
diff --git a/src/modules/eina/mp/ememoa_fixed/eina_ememoa_fixed.c b/src/modules/eina/mp/ememoa_fixed/eina_ememoa_fixed.c
new file mode 100644
index 000000000..0d02f80bb
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_fixed/eina_ememoa_fixed.c
@@ -0,0 +1,176 @@
+/* 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 <stdlib.h>
+#include <string.h>
+#include <ememoa_mempool_fixed.h>
+
+#include "eina_inlist.h"
+#include "eina_error.h"
+#include "eina_module.h"
+#include "eina_mempool.h"
+
+#include "eina_private.h"
+
+typedef struct _Eina_Ememoa_Fixed_Mempool Eina_Ememoa_Fixed_Mempool;
+struct _Eina_Ememoa_Fixed_Mempool
+{
+ struct ememoa_mempool_desc_s *desc;
+ int pool;
+};
+
+static void *
+eina_ememoa_fixed_malloc(void *data, __UNUSED__ unsigned int size)
+{
+ Eina_Ememoa_Fixed_Mempool *efm = data;
+
+ return ememoa_mempool_fixed_pop_object(efm->pool);
+}
+
+static void
+eina_ememoa_fixed_free(void *data, void *ptr)
+{
+ Eina_Ememoa_Fixed_Mempool *efm = data;
+
+ ememoa_mempool_fixed_push_object(efm->pool, ptr);
+}
+
+static void *
+eina_ememoa_fixed_realloc(__UNUSED__ void *data,
+ __UNUSED__ void *element,
+ __UNUSED__ unsigned int size)
+{
+ return NULL;
+}
+
+static void
+eina_ememoa_fixed_gc(void *data)
+{
+ Eina_Ememoa_Fixed_Mempool *efm = data;
+
+ ememoa_mempool_fixed_garbage_collect(efm->pool);
+}
+
+static void
+eina_ememoa_fixed_statistics(void *data)
+{
+ Eina_Ememoa_Fixed_Mempool *efm = data;
+
+ ememoa_mempool_fixed_display_statistic(efm->pool);
+ (void)efm;
+}
+
+static void *
+eina_ememoa_fixed_init(const char *context,
+ __UNUSED__ const char *option,
+ va_list args)
+{
+ struct ememoa_mempool_desc_s *desc = NULL;
+ Eina_Ememoa_Fixed_Mempool *efm = NULL;
+ Eina_Bool thread_protect;
+ int context_length;
+ int item_size;
+ int pool_size;
+
+ if (context)
+ {
+ context_length = strlen(context) + 1;
+
+ desc = calloc(1, sizeof (struct ememoa_mempool_desc_s) + context_length);
+ if (!desc)
+ goto on_error;
+
+ desc->name = (char *)(desc + 1);
+ memcpy((char *)desc->name, context, context_length);
+ }
+
+ item_size = va_arg(args, int);
+ pool_size = va_arg(args, int);
+ thread_protect = va_arg(args, int);
+
+ efm = malloc(sizeof (Eina_Ememoa_Fixed_Mempool));
+ if (!efm)
+ goto on_error;
+
+ efm->desc = desc;
+ efm->pool = ememoa_mempool_fixed_init(
+ item_size,
+ pool_size,
+ thread_protect ?
+ EMEMOA_THREAD_PROTECTION : 0,
+ efm->desc);
+ if (efm->pool < 0)
+ goto on_error;
+
+ return efm;
+
+on_error:
+ if (desc)
+ free(desc);
+
+ if (efm)
+ free(efm);
+
+ return NULL;
+}
+
+static void
+eina_ememoa_fixed_shutdown(void *data)
+{
+ Eina_Ememoa_Fixed_Mempool *efm = data;
+
+ if (efm->desc)
+ free(efm->desc);
+
+ ememoa_mempool_fixed_clean(efm->pool);
+ free(efm);
+}
+
+static Eina_Mempool_Backend _eina_ememoa_mp_backend = {
+ .name = "ememoa_fixed",
+ .init = &eina_ememoa_fixed_init,
+ .shutdown = &eina_ememoa_fixed_shutdown,
+ .realloc = &eina_ememoa_fixed_realloc,
+ .alloc = &eina_ememoa_fixed_malloc,
+ .free = &eina_ememoa_fixed_free,
+ .garbage_collect = &eina_ememoa_fixed_gc,
+ .statistics = &eina_ememoa_fixed_statistics,
+ .repack = NULL
+};
+
+Eina_Bool ememoa_fixed_init(void)
+{
+ return eina_mempool_register(&_eina_ememoa_mp_backend);
+}
+
+void ememoa_fixed_shutdown(void)
+{
+ eina_mempool_unregister(&_eina_ememoa_mp_backend);
+}
+
+
+#ifndef EINA_STATIC_BUILD_EMEMOA_FIXED
+
+EINA_MODULE_INIT(ememoa_fixed_init);
+EINA_MODULE_SHUTDOWN(ememoa_fixed_shutdown);
+
+#endif /* ! EINA_STATIC_BUILD_EMEMOA_FIXED */
diff --git a/src/modules/eina/mp/ememoa_unknown/Makefile.am b/src/modules/eina/mp/ememoa_unknown/Makefile.am
new file mode 100644
index 000000000..971313711
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_unknown/Makefile.am
@@ -0,0 +1,28 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include/eina \
+-I$(top_builddir)/src/include/eina \
+-I$(top_srcdir)/src/lib/eina \
+-I$(top_builddir)/src/lib/eina \
+@EMEMOA_CFLAGS@ \
+@EFL_EINA_BUILD@
+
+controllerdir = $(libdir)/eina/modules/mp/ememoa_unknown/$(MODULE_ARCH)
+controller_LTLIBRARIES = module.la
+
+module_la_SOURCES = eina_ememoa_unknown.c
+
+module_la_CFLAGS = @EINA_CFLAGS@
+module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EMEMOA_LIBS@ @EINA_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+install-data-hook:
+ rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
+uninstall-hook:
+ rm -f $(DESTDIR)$(controllerdir)/module.*
+
+clean-local:
+ rm -rf *.gcno
diff --git a/src/modules/eina/mp/ememoa_unknown/eina_ememoa_unknown.c b/src/modules/eina/mp/ememoa_unknown/eina_ememoa_unknown.c
new file mode 100644
index 000000000..56b99f66c
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_unknown/eina_ememoa_unknown.c
@@ -0,0 +1,182 @@
+/* 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 <stdlib.h>
+#include <string.h>
+#include <ememoa_mempool_fixed.h>
+#include <ememoa_mempool_unknown_size.h>
+
+#include "eina_types.h"
+#include "eina_module.h"
+#include "eina_private.h"
+#include "eina_mempool.h"
+
+typedef struct _Eina_Ememoa_Unknown_Size_Mempool
+Eina_Ememoa_Unknown_Size_Mempool;
+struct _Eina_Ememoa_Unknown_Size_Mempool
+{
+ struct ememoa_mempool_desc_s *desc;
+ int pool;
+};
+
+static void *
+eina_ememoa_unknown_size_malloc(void *data, unsigned int size)
+{
+ Eina_Ememoa_Unknown_Size_Mempool *efm = data;
+
+ return ememoa_mempool_unknown_size_pop_object(efm->pool, size);
+}
+
+static void
+eina_ememoa_unknown_size_free(void *data, void *ptr)
+{
+ Eina_Ememoa_Unknown_Size_Mempool *efm = data;
+
+ ememoa_mempool_unknown_size_push_object(efm->pool, ptr);
+}
+
+static void *
+eina_ememoa_unknown_size_realloc(void *data, void *element, unsigned int size)
+{
+ Eina_Ememoa_Unknown_Size_Mempool *efm = data;
+
+ return ememoa_mempool_unknown_size_resize_object(efm->pool, element, size);
+}
+
+static void
+eina_ememoa_unknown_size_gc(void *data)
+{
+ Eina_Ememoa_Unknown_Size_Mempool *efm = data;
+
+ ememoa_mempool_unknown_size_garbage_collect(efm->pool);
+}
+
+static void
+eina_ememoa_unknown_size_statistics(void *data)
+{
+ Eina_Ememoa_Unknown_Size_Mempool *efm = data;
+
+ ememoa_mempool_unknown_size_display_statistic(efm->pool);
+}
+
+static void *
+eina_ememoa_unknown_size_init(const char *context,
+ __UNUSED__ const char *option,
+ va_list args)
+{
+ struct ememoa_mempool_desc_s *desc = NULL;
+ Eina_Ememoa_Unknown_Size_Mempool *efm = NULL;
+ Eina_Bool thread_protect;
+ unsigned int *items_map = NULL;
+ unsigned int items_count;
+ unsigned int i;
+ int context_length;
+
+ if (context)
+ {
+ context_length = strlen(context) + 1;
+
+ desc = calloc(1, sizeof (struct ememoa_mempool_desc_s) + context_length);
+ if (!desc)
+ goto on_error;
+
+ desc->name = (char *)(desc + 1);
+ memcpy((char *)desc->name, context, context_length);
+ }
+
+ thread_protect = va_arg(args, int);
+ items_count = va_arg(args, unsigned int);
+
+ items_map = malloc(sizeof (unsigned int) * 2 * items_count);
+
+ for (i = 0; i < (items_count << 1); ++i)
+ items_map[i] = va_arg(args, unsigned int);
+
+ efm = malloc(sizeof (Eina_Ememoa_Unknown_Size_Mempool));
+ if (!efm)
+ goto on_error;
+
+ efm->desc = desc;
+ efm->pool = ememoa_mempool_unknown_size_init(
+ items_count,
+ items_map,
+ thread_protect ?
+ EMEMOA_THREAD_PROTECTION : 0,
+ efm->desc);
+ if (efm->pool < 0)
+ goto on_error;
+
+ return efm;
+
+on_error:
+ if (items_map)
+ free(items_map);
+
+ if (desc)
+ free(desc);
+
+ if (efm)
+ free(efm);
+
+ return NULL;
+}
+
+static void
+eina_ememoa_unknown_size_shutdown(void *data)
+{
+ Eina_Ememoa_Unknown_Size_Mempool *efm = data;
+
+ if (efm->desc)
+ free(efm->desc);
+
+ ememoa_mempool_unknown_size_clean(efm->pool);
+ free(efm);
+}
+
+static Eina_Mempool_Backend _eina_ememoa_unknown_mp_backend = {
+ .name = "ememoa_unknown",
+ .init = &eina_ememoa_unknown_size_init,
+ .shutdown = &eina_ememoa_unknown_size_shutdown,
+ .realloc = &eina_ememoa_unknown_size_realloc,
+ .alloc = &eina_ememoa_unknown_size_malloc,
+ .free = &eina_ememoa_unknown_size_free,
+ .garbage_collect = &eina_ememoa_unknown_size_gc,
+ .statistics = &eina_ememoa_unknown_size_statistics,
+ .repack = NULL
+};
+
+Eina_Bool ememoa_unknown_init(void)
+{
+ return eina_mempool_register(&_eina_ememoa_unknown_mp_backend);
+}
+
+void ememoa_unknown_shutdown(void)
+{
+ eina_mempool_unregister(&_eina_ememoa_unknown_mp_backend);
+}
+
+#ifndef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
+
+EINA_MODULE_INIT(ememoa_unknown_init);
+EINA_MODULE_SHUTDOWN(ememoa_unknown_shutdown);
+
+#endif /* ! EINA_STATIC_BUILD_EMEMOA_UNKNOWN */
diff --git a/src/modules/eina/mp/fixed_bitmap/Makefile.am b/src/modules/eina/mp/fixed_bitmap/Makefile.am
new file mode 100644
index 000000000..214367600
--- /dev/null
+++ b/src/modules/eina/mp/fixed_bitmap/Makefile.am
@@ -0,0 +1,27 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include/eina \
+-I$(top_builddir)/src/include/eina \
+-I$(top_srcdir)/src/lib/eina \
+-I$(top_builddir)/src/lib/eina \
+@EFL_EINA_BUILD@
+
+controllerdir = $(libdir)/eina/modules/mp/fixed_bitmap/$(MODULE_ARCH)
+controller_LTLIBRARIES = module.la
+
+module_la_SOURCES = eina_fixed_bitmap.c
+
+module_la_CFLAGS = @EINA_CFLAGS@
+module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+install-data-hook:
+ rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
+uninstall-hook:
+ rm -f $(DESTDIR)$(controllerdir)/module.*
+
+clean-local:
+ rm -rf *.gcno
diff --git a/src/modules/eina/mp/fixed_bitmap/eina_fixed_bitmap.c b/src/modules/eina/mp/fixed_bitmap/eina_fixed_bitmap.c
new file mode 100644
index 000000000..e053e1579
--- /dev/null
+++ b/src/modules/eina/mp/fixed_bitmap/eina_fixed_bitmap.c
@@ -0,0 +1,270 @@
+/* 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
+
+#ifndef _MSC_VER
+# include <stdint.h>
+#endif
+#include <string.h>
+#include <assert.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#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 size_t
+_eina_rbtree_inlist_delta(void)
+{
+ Eina_Fixed_Bitmap_Pool tmp;
+ void *a = &tmp.__rbtree;
+ void *b = &tmp.__in_list;
+
+ return (char *)a - (char *)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;
+ ssize_t delta;
+ ssize_t limit;
+
+ limit = sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32;
+ delta = (char *)a - (char *)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 = NULL;
+ void *ptr;
+ int idx;
+
+ 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);
+ }
+
+ idx = ffs(pool->bitmask) - 1;
+ pool->bitmask &= ~(1 << idx);
+ ptr = (unsigned char *)(pool + 1) + idx * mp->item_size;
+
+ if (pool->bitmask == 0)
+ mp->head = eina_inlist_demote(mp->head, EINA_INLIST_GET(pool));
+
+ return ptr;
+}
+
+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;
+ ssize_t 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 =
+ ((char *)ptr - (char *)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_promote(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;
+ int item_size;
+
+ mp = malloc(sizeof (Eina_Fixed_Bitmap));
+ if (!mp)
+ return NULL;
+
+ item_size = va_arg(args, int);
+
+ mp->item_size = eina_mempool_alignof(item_size);
+
+ 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 _eina_fixed_bitmap_mp_backend = {
+ "fixed_bitmap",
+ &eina_fixed_bitmap_init,
+ &eina_fixed_bitmap_free,
+ &eina_fixed_bitmap_malloc,
+ &eina_fixed_bitmap_realloc,
+ NULL,
+ NULL,
+ &eina_fixed_bitmap_shutdown,
+ NULL
+};
+
+Eina_Bool fixed_bitmap_init(void)
+{
+ return eina_mempool_register(&_eina_fixed_bitmap_mp_backend);
+}
+
+void fixed_bitmap_shutdown(void)
+{
+ eina_mempool_unregister(&_eina_fixed_bitmap_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/src/modules/eina/mp/one_big/Makefile.am b/src/modules/eina/mp/one_big/Makefile.am
new file mode 100644
index 000000000..6a5efa531
--- /dev/null
+++ b/src/modules/eina/mp/one_big/Makefile.am
@@ -0,0 +1,28 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include/eina \
+-I$(top_builddir)/src/include/eina \
+-I$(top_srcdir)/src/lib/eina \
+-I$(top_builddir)/src/lib/eina \
+@EFL_EINA_BUILD@ \
+@VALGRIND_CFLAGS@
+
+controllerdir = $(libdir)/eina/modules/mp/one_big/$(MODULE_ARCH)
+controller_LTLIBRARIES = module.la
+
+module_la_SOURCES = eina_one_big.c
+
+module_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@
+module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version @EFL_PTHREAD_LIBS@
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+install-data-hook:
+ rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
+uninstall-hook:
+ rm -f $(DESTDIR)$(controllerdir)/module.*
+
+clean-local:
+ rm -rf *.gcno
diff --git a/src/modules/eina/mp/one_big/eina_one_big.c b/src/modules/eina/mp/one_big/eina_one_big.c
new file mode 100644
index 000000000..1159378de
--- /dev/null
+++ b/src/modules/eina/mp/one_big/eina_one_big.c
@@ -0,0 +1,336 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2010 Cedric BAIL, Vincent Torri
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#ifdef EFL_HAVE_POSIX_THREADS
+# include <pthread.h>
+#endif
+
+#include <assert.h>
+
+#ifdef EFL_HAVE_WIN32_THREADS
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#include "eina_mempool.h"
+#include "eina_trash.h"
+#include "eina_inlist.h"
+#include "eina_log.h"
+#include "eina_lock.h"
+
+#ifndef NVALGRIND
+# include <memcheck.h>
+#endif
+
+#include "eina_private.h"
+
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_eina_mempool_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_eina_one_big_mp_log_dom, __VA_ARGS__)
+
+static int _eina_one_big_mp_log_dom = -1;
+
+typedef struct _One_Big One_Big;
+struct _One_Big
+{
+ const char *name;
+
+ int item_size;
+
+ int usage;
+ int over;
+
+ int served;
+ int max;
+ unsigned char *base;
+
+ Eina_Trash *empty;
+ Eina_Inlist *over_list;
+
+#ifdef EFL_DEBUG_THREADS
+ pthread_t self;
+#endif
+ Eina_Lock mutex;
+};
+
+static void *
+eina_one_big_malloc(void *data, __UNUSED__ unsigned int size)
+{
+ One_Big *pool = data;
+ unsigned char *mem = NULL;
+
+ if (!eina_lock_take(&pool->mutex))
+ {
+#ifdef EFL_DEBUG_THREADS
+ assert(pthread_equal(pool->self, pthread_self()));
+#endif
+ }
+
+ if (pool->empty)
+ {
+#ifndef NVALGRIND
+ VALGRIND_MAKE_MEM_DEFINED(pool->empty, pool->item_size);
+#endif
+ mem = eina_trash_pop(&pool->empty);
+ pool->usage++;
+ goto on_exit;
+ }
+
+ if (!pool->base)
+ {
+ pool->base = malloc(pool->item_size * pool->max);
+ if (!pool->base)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ goto retry_smaller;
+ }
+#ifndef NVALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS(pool->base, pool->item_size * pool->max);
+#endif
+ }
+
+ if (pool->served < pool->max)
+ {
+ mem = pool->base + (pool->served++ *pool->item_size);
+ pool->usage++;
+ goto on_exit;
+ }
+
+ retry_smaller:
+ eina_error_set(0);
+ mem = malloc(sizeof(Eina_Inlist) + pool->item_size);
+ if (!mem)
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ else
+ {
+ pool->over++;
+ memset(mem, 0, sizeof(Eina_Inlist));
+ pool->over_list = eina_inlist_append(pool->over_list,
+ (Eina_Inlist *)mem);
+ mem = ((unsigned char *)mem) + sizeof(Eina_Inlist);
+ }
+#ifndef NVALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS(mem, pool->item_size);
+#endif
+
+on_exit:
+ eina_lock_release(&pool->mutex);
+
+#ifndef NVALGRIND
+ VALGRIND_MEMPOOL_ALLOC(pool, mem, pool->item_size);
+#endif
+ return mem;
+}
+
+static void
+eina_one_big_free(void *data, void *ptr)
+{
+ One_Big *pool = data;
+
+ if (!eina_lock_take(&pool->mutex))
+ {
+#ifdef EFL_DEBUG_THREADS
+ assert(pthread_equal(pool->self, pthread_self()));
+#endif
+ }
+
+ if ((void *)pool->base <= ptr
+ && ptr < (void *)(pool->base + (pool->max * pool->item_size)))
+ {
+ eina_trash_push(&pool->empty, ptr);
+ pool->usage--;
+ }
+ else
+ {
+#ifndef NDEBUG
+ Eina_Inlist *it;
+#endif
+ Eina_Inlist *il;
+
+ il = (Eina_Inlist *)(((unsigned char *)ptr) - sizeof(Eina_Inlist));
+
+#ifndef NDEBUG
+ for (it = pool->over_list; it != NULL; it = it->next)
+ if (it == il) break;
+
+ assert(it != NULL);
+#endif
+
+ pool->over_list = eina_inlist_remove(pool->over_list, il);
+ free(il);
+ pool->over--;
+ }
+
+#ifndef NVALGRIND
+ VALGRIND_MEMPOOL_FREE(pool, ptr);
+#endif
+
+ eina_lock_release(&pool->mutex);
+}
+
+static void *
+eina_one_big_realloc(__UNUSED__ void *data,
+ __UNUSED__ void *element,
+ __UNUSED__ unsigned int size)
+{
+ return NULL;
+}
+
+static void *
+eina_one_big_init(const char *context,
+ __UNUSED__ const char *option,
+ va_list args)
+{
+ One_Big *pool;
+ int item_size;
+ size_t length;
+
+ length = context ? strlen(context) + 1 : 0;
+
+ pool = calloc(1, sizeof (One_Big) + length);
+ if (!pool)
+ return NULL;
+
+ item_size = va_arg(args, int);
+
+ pool->item_size = eina_mempool_alignof(item_size);
+ pool->max = va_arg(args, int);
+
+ if (length)
+ {
+ pool->name = (const char *)(pool + 1);
+ memcpy((char *)pool->name, context, length);
+ }
+
+#ifdef EFL_DEBUG_THREADS
+ pool->self = pthread_self();
+#endif
+ eina_lock_new(&pool->mutex);
+
+#ifndef NVALGRIND
+ VALGRIND_CREATE_MEMPOOL(pool, 0, 1);
+#endif
+
+ return pool;
+}
+
+static void
+eina_one_big_shutdown(void *data)
+{
+ One_Big *pool = data;
+
+ if (!pool) return;
+ if (!eina_lock_take(&pool->mutex))
+ {
+#ifdef EFL_DEBUG_THREADS
+ assert(pthread_equal(pool->self, pthread_self()));
+#endif
+ }
+
+ if (pool->over > 0)
+ {
+// FIXME: should we warn here? one_big mempool exceeded its alloc and now
+// mempool is cleaning up the mess created. be quiet for now as we were before
+// but edje seems to be a big offender at the moment! bad cedric! :)
+// WRN(
+// "Pool [%s] over by %i. cleaning up for you",
+// pool->name, pool->over);
+ while (pool->over_list)
+ {
+ Eina_Inlist *il = pool->over_list;
+ pool->over_list = eina_inlist_remove(pool->over_list, il);
+ free(il);
+ pool->over--;
+ }
+ }
+ if (pool->over > 0)
+ {
+ WRN(
+ "Pool [%s] still over by %i\n",
+ pool->name, pool->over);
+ }
+
+#ifndef NVALGRIND
+ VALGRIND_DESTROY_MEMPOOL(pool);
+#endif
+
+ if (pool->base) free(pool->base);
+
+ eina_lock_release(&pool->mutex);
+ eina_lock_free(&pool->mutex);
+ free(pool);
+}
+
+
+static Eina_Mempool_Backend _eina_one_big_mp_backend = {
+ "one_big",
+ &eina_one_big_init,
+ &eina_one_big_free,
+ &eina_one_big_malloc,
+ &eina_one_big_realloc,
+ NULL,
+ NULL,
+ &eina_one_big_shutdown,
+ NULL
+};
+
+Eina_Bool one_big_init(void)
+{
+#ifdef DEBUG
+ _eina_one_big_mp_log_dom = eina_log_domain_register("eina_one_big_mempool",
+ EINA_LOG_COLOR_DEFAULT);
+ if (_eina_one_big_mp_log_dom < 0)
+ {
+ EINA_LOG_ERR("Could not register log domain: eina_one_big_mempool");
+ return EINA_FALSE;
+ }
+
+#endif
+ return eina_mempool_register(&_eina_one_big_mp_backend);
+}
+
+void one_big_shutdown(void)
+{
+ eina_mempool_unregister(&_eina_one_big_mp_backend);
+#ifdef DEBUG
+ eina_log_domain_unregister(_eina_one_big_mp_log_dom);
+ _eina_one_big_mp_log_dom = -1;
+#endif
+}
+
+#ifndef EINA_STATIC_BUILD_ONE_BIG
+
+EINA_MODULE_INIT(one_big_init);
+EINA_MODULE_SHUTDOWN(one_big_shutdown);
+
+#endif /* ! EINA_STATIC_BUILD_ONE_BIG */
+
diff --git a/src/modules/eina/mp/pass_through/Makefile.am b/src/modules/eina/mp/pass_through/Makefile.am
new file mode 100644
index 000000000..6d5f1687e
--- /dev/null
+++ b/src/modules/eina/mp/pass_through/Makefile.am
@@ -0,0 +1,27 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include/eina \
+-I$(top_builddir)/src/include/eina \
+-I$(top_srcdir)/src/lib/eina \
+-I$(top_builddir)/src/lib/eina \
+@EFL_EINA_BUILD@
+
+controllerdir = $(libdir)//eina/modules/mp/pass_through/$(MODULE_ARCH)
+controller_LTLIBRARIES = module.la
+
+module_la_SOURCES = eina_pass_through.c
+
+module_la_CFLAGS = @EINA_CFLAGS@
+module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+install-data-hook:
+ rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
+uninstall-hook:
+ rm -f $(DESTDIR)$(controllerdir)/module.*
+
+clean-local:
+ rm -rf *.gcno
diff --git a/src/modules/eina/mp/pass_through/eina_pass_through.c b/src/modules/eina/mp/pass_through/eina_pass_through.c
new file mode 100644
index 000000000..196868ecb
--- /dev/null
+++ b/src/modules/eina/mp/pass_through/eina_pass_through.c
@@ -0,0 +1,90 @@
+/* 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 <stdlib.h>
+
+#include "eina_types.h"
+#include "eina_module.h"
+#include "eina_mempool.h"
+#include "eina_private.h"
+
+static void *
+eina_pass_through_malloc(__UNUSED__ void *data, unsigned int size)
+{
+ return malloc(size);
+}
+
+static void
+eina_pass_through_free(__UNUSED__ void *data, void *ptr)
+{
+ free(ptr);
+}
+
+static void *
+eina_pass_through_realloc(__UNUSED__ void *data, void *ptr, unsigned int size)
+{
+ return realloc(ptr, size);
+}
+
+static void *
+eina_pass_through_init(__UNUSED__ const char *context,
+ __UNUSED__ const char *option,
+ __UNUSED__ va_list args)
+{
+ return (void *)0x1;
+}
+
+static void
+eina_pass_through_shutdown(__UNUSED__ void *data)
+{
+}
+
+
+static Eina_Mempool_Backend _eina_pass_through_mp_backend = {
+ "pass_through",
+ &eina_pass_through_init,
+ &eina_pass_through_free,
+ &eina_pass_through_malloc,
+ &eina_pass_through_realloc,
+ NULL,
+ NULL,
+ &eina_pass_through_shutdown,
+ NULL
+};
+
+Eina_Bool pass_through_init(void)
+{
+ return eina_mempool_register(&_eina_pass_through_mp_backend);
+}
+
+void pass_through_shutdown(void)
+{
+ eina_mempool_unregister(&_eina_pass_through_mp_backend);
+}
+
+#ifndef EINA_STATIC_BUILD_PASS_THROUGH
+
+EINA_MODULE_INIT(pass_through_init);
+EINA_MODULE_SHUTDOWN(pass_through_shutdown);
+
+#endif /* ! EINA_STATIC_BUILD_PASS_THROUGH */
+