summaryrefslogtreecommitdiff
path: root/src/modules/eina
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/eina
parentdfc0331373c3f98df7cb996abc588c7dcf44af0a (diff)
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/eina')
-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
16 files changed, 2160 insertions, 0 deletions
diff --git a/src/modules/eina/Makefile.am b/src/modules/eina/Makefile.am
new file mode 100644
index 0000000000..53e28b7bf9
--- /dev/null
+++ b/src/modules/eina/Makefile.am
@@ -0,0 +1,4 @@
1SUBDIRS = mp
2
3MAINTAINERCLEANFILES = \
4Makefile.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 0000000000..435d57a96a
--- /dev/null
+++ b/src/modules/eina/mp/Makefile.am
@@ -0,0 +1,45 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3SUBDIRS =
4
5if EINA_BUILD_BUDDY
6if !EINA_STATIC_BUILD_BUDDY
7SUBDIRS += buddy
8endif
9endif
10
11if EINA_BUILD_CHAINED_POOL
12if !EINA_STATIC_BUILD_CHAINED_POOL
13SUBDIRS += chained_pool
14endif
15endif
16
17if EINA_BUILD_EMEMOA_FIXED
18if !EINA_STATIC_BUILD_EMEMOA_FIXED
19SUBDIRS += ememoa_fixed
20endif
21endif
22
23if EINA_BUILD_EMEMOA_UNKNOWN
24if !EINA_STATIC_BUILD_EMEMOA_UNKNOWN
25SUBDIRS += ememoa_unknown
26endif
27endif
28
29if EINA_BUILD_FIXED_BITMAP
30if !EINA_STATIC_BUILD_FIXED_BITMAP
31SUBDIRS += fixed_bitmap
32endif
33endif
34
35if EINA_BUILD_ONE_BIG
36if !EINA_STATIC_BUILD_ONE_BIG
37SUBDIRS += one_big
38endif
39endif
40
41if EINA_BUILD_PASS_THROUGH
42if !EINA_STATIC_BUILD_PASS_THROUGH
43SUBDIRS += pass_through
44endif
45endif
diff --git a/src/modules/eina/mp/buddy/Makefile.am b/src/modules/eina/mp/buddy/Makefile.am
new file mode 100644
index 0000000000..e43db1aa87
--- /dev/null
+++ b/src/modules/eina/mp/buddy/Makefile.am
@@ -0,0 +1,27 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_builddir)/src/include/eina \
7-I$(top_srcdir)/src/lib/eina \
8-I$(top_builddir)/src/lib/eina \
9@EFL_EINA_BUILD@
10
11controllerdir = $(libdir)/eina/modules/mp/buddy/$(MODULE_ARCH)
12controller_LTLIBRARIES = module.la
13
14module_la_SOURCES = eina_buddy.c
15
16module_la_CFLAGS = @EINA_CFLAGS@
17module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
18module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
19module_la_LIBTOOLFLAGS = --tag=disable-static
20
21install-data-hook:
22 rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
23uninstall-hook:
24 rm -f $(DESTDIR)$(controllerdir)/module.*
25
26clean-local:
27 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 0000000000..7d830dbfbb
--- /dev/null
+++ b/src/modules/eina/mp/buddy/eina_buddy.c
@@ -0,0 +1,292 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2009 Jorge Luis Zapata Muga
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * This is a naive 'buddy' allocator following Knuth's documentation.
21 * The main difference is that we dont store the block information
22 * on the block memory itself but on another malloc'd area.
23 * This is useful for managing memory which isn't as fast as the main
24 * memory like the video memory
25 * The algorithm uses an area to store the linked list of blocks.
26 * Each block size is equal to the minimum allocatable block size for
27 * the memory pool and the number of blocks is equal to the size of the
28 * memory pool divided by the block size.
29 */
30#ifdef HAVE_CONFIG_H
31# include "config.h"
32#endif
33
34#include <stdio.h>
35
36#include "eina_types.h"
37#include "eina_inlist.h"
38#include "eina_module.h"
39#include "eina_mempool.h"
40#include "eina_private.h"
41
42typedef struct _Block
43{
44 EINA_INLIST;
45 Eina_Bool available : 1;
46 unsigned short int order : 7; /* final order is order + min_order */
47} Block;
48
49typedef struct _Buddy
50{
51 void *heap; /* start address of the heap */
52 size_t size; /* total size in bytes of the heap */
53 unsigned int min_order; /* minimum size is 1 << min_order */
54 unsigned int max_order; /* maximum size is 1 << max_order */
55 unsigned int num_order; /* number of orders */
56 Eina_Inlist **areas; /* one area per order */
57 Block *blocks; /* the allocated block information */
58} Buddy;
59
60/* get the minimum order greater or equal to size */
61static inline unsigned int _get_order(Buddy *b, size_t size)
62{
63 unsigned int i;
64 size_t bytes;
65
66 bytes = 1 << b->min_order;
67 for (i = 0; bytes < size && i < b->num_order; i++)
68 {
69 bytes += bytes;
70 }
71 //printf("order for size %d is %d\n", size, i + b->min_order);
72 return i;
73}
74
75static inline void *_get_offset(Buddy *b, Block *block)
76{
77 void *ret;
78
79 ret = (char *)b->heap + ((block - &b->blocks[0]) << b->min_order);
80 return ret;
81}
82
83static void *_init(__UNUSED__ const char *context,
84 __UNUSED__ const char *options,
85 va_list args)
86{
87 Buddy *b;
88 int i;
89 size_t bytes;
90 size_t size;
91 size_t min_order;
92 void *heap;
93
94 heap = va_arg(args, void *);
95 size = va_arg(args, size_t);
96 min_order = va_arg(args, int);
97 /* the minimum order we support is 15 (32K) */
98 min_order = min_order < 15 ? 15 : min_order;
99 bytes = 1 << min_order;
100 for (i = 0; bytes <= size; i++)
101 {
102 bytes += bytes;
103 }
104 if (!i)
105 return NULL;
106
107 b = malloc(sizeof(Buddy));
108 b->heap = heap;
109 b->size = size;
110 b->min_order = min_order;
111 b->max_order = min_order + i - 1;
112 b->num_order = i;
113 b->areas = calloc(b->num_order, sizeof(Eina_Inlist *));
114 b->blocks = calloc(1 << (b->num_order - 1), sizeof(Block));
115 /* setup the initial free area */
116 b->blocks[0].available = EINA_TRUE;
117 b->areas[b->num_order - 1] = EINA_INLIST_GET(&(b->blocks[0]));
118
119 return b;
120}
121
122static void _shutdown(void *data)
123{
124 Buddy *b = data;
125
126 free(b->blocks);
127 free(b->areas);
128 free(b);
129}
130
131static void _free(void *data, void *element)
132{
133 Buddy *b = data;
134 Block *block, *buddy;
135 size_t offset;
136 size_t idx;
137
138 offset = (unsigned char *)element - (unsigned char *)b->heap;
139 if (offset > b->size)
140 return;
141
142 idx = offset >> b->min_order;
143 block = &b->blocks[idx];
144
145 //printf("free %x idx = %d order = %d buddy = %d\n", offset, idx, block->order, idx ^ (1 << block->order));
146 /* we should always work with the buddy at right */
147 if (idx & (1 << block->order))
148 {
149 Block *left;
150
151 idx = idx ^ (1 << block->order);
152 left = &b->blocks[idx];
153 if (!left->available)
154 goto end;
155 else
156 {
157 buddy = block;
158 block = left;
159 b->areas[block->order] = eina_inlist_remove(b->areas[block->order],
160 EINA_INLIST_GET(block));
161 block->order++;
162 }
163 }
164
165check:
166 /* already on the last order */
167 if (block->order + b->min_order == b->max_order)
168 {
169 goto end; /* get the buddy */
170
171 }
172
173 buddy = &b->blocks[idx ^ (1 << block->order)];
174 if (!buddy->available)
175 {
176 goto end; /* merge two blocks */
177
178 }
179
180 b->areas[block->order] = eina_inlist_remove(b->areas[block->order],
181 EINA_INLIST_GET(buddy));
182 block->order++;
183 goto check;
184end:
185 /* add the block to the free list */
186 block->available = EINA_TRUE;
187 b->areas[block->order] = eina_inlist_append(b->areas[block->order],
188 EINA_INLIST_GET(block));
189}
190
191static void *_alloc(void *data, unsigned int size)
192{
193 Buddy *b = data;
194 Block *block, *buddy;
195 unsigned int k, j;
196
197 k = j = _get_order(b, size);
198 /* get a free list of order k where k <= j <= max_order */
199 while ((j < b->num_order) && !b->areas[j])
200 j++;
201 /* check that the order is on our range */
202 if (j + b->min_order > b->max_order)
203 return NULL;
204
205 /* get a free element on this order, if not, go splitting until we find one */
206 //printf("getting order %d (%d) for size %d\n", j, k, size);
207found:
208 if (j == k)
209 {
210 void *ret;
211
212 block = EINA_INLIST_CONTAINER_GET(b->areas[j], Block);
213 block->available = EINA_FALSE;
214 block->order = j;
215 /* remove the block from the list */
216 b->areas[j] = eina_inlist_remove(b->areas[j], EINA_INLIST_GET(block));
217 ret = _get_offset(b, block);
218
219 return ret;
220 }
221
222 block = EINA_INLIST_CONTAINER_GET(b->areas[j], Block);
223 /* split */
224 b->areas[j] = eina_inlist_remove(b->areas[j], EINA_INLIST_GET(block));
225 j--;
226 b->areas[j] = eina_inlist_append(b->areas[j], EINA_INLIST_GET(block));
227 buddy = block + (1 << j);
228 buddy->order = j;
229 buddy->available = EINA_TRUE;
230 b->areas[j] = eina_inlist_append(b->areas[j], EINA_INLIST_GET(buddy));
231
232 goto found;
233}
234
235static void _statistics(void *data)
236{
237 Buddy *b = data;
238 unsigned int i;
239
240 printf("Information:\n");
241 printf(
242 "size = %zu, min_order = %d, max_order = %d, num_order = %d, num_blocks = %d (%uKB)\n",
243 b->size,
244 b->min_order,
245 b->max_order,
246 b->num_order,
247 1 << b->num_order,
248 ((1 << (b->num_order)) * sizeof(Block)) / 1024);
249 printf("Area dumping:");
250 /* iterate over the free lists and dump the maps */
251 for (i = 0; i < b->num_order; i++)
252 {
253 Block *block;
254
255 printf("\n2^%d:", b->min_order + i);
256 EINA_INLIST_FOREACH(b->areas[i], block)
257 {
258 printf(" %d", (block - &b->blocks[0]));
259 }
260 }
261 printf("\nBlocks dumping:\n");
262}
263
264static Eina_Mempool_Backend _backend = {
265 "buddy",
266 &_init,
267 &_free,
268 &_alloc,
269 NULL, /* realloc */
270 NULL, /* garbage collect */
271 &_statistics,
272 &_shutdown,
273 NULL /* repack */
274};
275
276Eina_Bool buddy_init(void)
277{
278 return eina_mempool_register(&_backend);
279}
280
281void buddy_shutdown(void)
282{
283 eina_mempool_unregister(&_backend);
284}
285
286
287#ifndef EINA_STATIC_BUILD_BUDDY
288
289EINA_MODULE_INIT(buddy_init);
290EINA_MODULE_SHUTDOWN(buddy_shutdown);
291
292#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 0000000000..4e93445815
--- /dev/null
+++ b/src/modules/eina/mp/chained_pool/Makefile.am
@@ -0,0 +1,28 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_builddir)/src/include/eina \
7-I$(top_srcdir)/src/lib/eina \
8-I$(top_builddir)/src/lib/eina \
9@EFL_EINA_BUILD@ \
10@VALGRIND_CFLAGS@
11
12controllerdir = $(libdir)/eina/modules/mp/chained_pool/$(MODULE_ARCH)
13controller_LTLIBRARIES = module.la
14
15module_la_SOURCES = eina_chained_mempool.c
16
17module_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@
18module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
19module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version @EFL_PTHREAD_LIBS@
20module_la_LIBTOOLFLAGS = --tag=disable-static
21
22install-data-hook:
23 rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
24uninstall-hook:
25 rm -f $(DESTDIR)$(controllerdir)/module.*
26
27clean-local:
28 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 0000000000..e56df4cee6
--- /dev/null
+++ b/src/modules/eina/mp/chained_pool/eina_chained_mempool.c
@@ -0,0 +1,572 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008-2010 Cedric BAIL, Vincent Torri
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <stdlib.h>
24#include <string.h>
25
26#ifdef EFL_HAVE_POSIX_THREADS
27#include <pthread.h>
28
29# ifdef EFL_DEBUG_THREADS
30# include <assert.h>
31# endif
32#endif
33
34#ifdef EINA_DEBUG_MALLOC
35# include <malloc.h>
36#endif
37
38#ifdef EFL_HAVE_WIN32_THREADS
39# define WIN32_LEAN_AND_MEAN
40# include <windows.h>
41# undef WIN32_LEAN_AND_MEAN
42#endif
43
44#include "eina_inlist.h"
45#include "eina_error.h"
46#include "eina_module.h"
47#include "eina_mempool.h"
48#include "eina_trash.h"
49#include "eina_rbtree.h"
50#include "eina_lock.h"
51
52#include "eina_private.h"
53
54#ifndef NVALGRIND
55# include <memcheck.h>
56#endif
57
58#if defined DEBUG || defined EINA_DEBUG_MALLOC
59#include <assert.h>
60#include "eina_log.h"
61
62static int _eina_chained_mp_log_dom = -1;
63
64#ifdef INF
65#undef INF
66#endif
67#define INF(...) EINA_LOG_DOM_INFO(_eina_chained_mp_log_dom, __VA_ARGS__)
68#endif
69
70typedef struct _Chained_Mempool Chained_Mempool;
71struct _Chained_Mempool
72{
73 Eina_Inlist *first;
74 Eina_Rbtree *root;
75 const char *name;
76 int item_alloc;
77 int pool_size;
78 int alloc_size;
79 int group_size;
80 int usage;
81#ifdef EINA_DEBUG_MALLOC
82 int minimal_size;
83#endif
84#ifdef EFL_DEBUG_THREADS
85 pthread_t self;
86#endif
87 Eina_Lock mutex;
88};
89
90typedef struct _Chained_Pool Chained_Pool;
91struct _Chained_Pool
92{
93 EINA_INLIST;
94 EINA_RBTREE;
95 Eina_Trash *base;
96 int usage;
97
98 unsigned char *last;
99 unsigned char *limit;
100};
101
102static inline Eina_Rbtree_Direction
103_eina_chained_mp_pool_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, __UNUSED__ void *data)
104{
105 if (left < right) return EINA_RBTREE_LEFT;
106 return EINA_RBTREE_RIGHT;
107}
108
109static inline int
110_eina_chained_mp_pool_key_cmp(const Eina_Rbtree *node, const void *key,
111 __UNUSED__ int length, __UNUSED__ void *data)
112{
113 const Chained_Pool *r = EINA_RBTREE_CONTAINER_GET(node, const Chained_Pool);
114
115 if (key > (void *) r->limit) return -1;
116 if (key < (void *) r) return 1;
117 return 0;
118}
119
120static inline Chained_Pool *
121_eina_chained_mp_pool_new(Chained_Mempool *pool)
122{
123 Chained_Pool *p;
124 unsigned char *ptr;
125 unsigned int alignof;
126
127 eina_error_set(0);
128 p = malloc(pool->alloc_size);
129 if (!p)
130 {
131 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
132 return NULL;
133 }
134
135#ifdef EINA_DEBUG_MALLOC
136 {
137 size_t sz;
138
139 sz = malloc_usable_size(p);
140 if (sz - pool->minimal_size > 0)
141 INF("Just allocated %0.2f%% to much memory in '%s' for one block of size %i that means %i bytes to much.",
142 ((float)(sz - pool->minimal_size) * 100) / (float) (pool->alloc_size),
143 pool->name,
144 pool->alloc_size,
145 sz - pool->minimal_size);
146 }
147#endif
148
149 alignof = eina_mempool_alignof(sizeof(Chained_Pool));
150 ptr = (unsigned char *)p + alignof;
151 p->usage = 0;
152 p->base = NULL;
153
154 p->last = ptr;
155 p->limit = ptr + pool->item_alloc * pool->pool_size;
156
157#ifndef NVALGRIND
158 VALGRIND_MAKE_MEM_NOACCESS(ptr, pool->alloc_size - alignof);
159#endif
160
161 return p;
162}
163
164static inline void
165_eina_chained_mp_pool_free(Chained_Pool *p)
166{
167 free(p);
168}
169
170static int
171_eina_chained_mempool_usage_cmp(const Eina_Inlist *l1, const Eina_Inlist *l2)
172{
173 const Chained_Pool *p1;
174 const Chained_Pool *p2;
175
176 p1 = EINA_INLIST_CONTAINER_GET(l1, const Chained_Pool);
177 p2 = EINA_INLIST_CONTAINER_GET(l2, const Chained_Pool);
178
179 return p2->usage - p1->usage;
180}
181
182static void *
183_eina_chained_mempool_alloc_in(Chained_Mempool *pool, Chained_Pool *p)
184{
185 void *mem;
186
187 if (p->last)
188 {
189 mem = p->last;
190 p->last += pool->item_alloc;
191 if (p->last >= p->limit)
192 p->last = NULL;
193 }
194 else
195 {
196#ifndef NVALGRIND
197 VALGRIND_MAKE_MEM_DEFINED(p->base, pool->item_alloc);
198#endif
199 // Request a free pointer
200 mem = eina_trash_pop(&p->base);
201 }
202
203 // move to end - it just filled up
204 if (!p->base && !p->last)
205 pool->first = eina_inlist_demote(pool->first, EINA_INLIST_GET(p));
206
207 p->usage++;
208 pool->usage++;
209
210#ifndef NVALGRIND
211 VALGRIND_MEMPOOL_ALLOC(pool, mem, pool->item_alloc);
212#endif
213
214 return mem;
215}
216
217static Eina_Bool
218_eina_chained_mempool_free_in(Chained_Mempool *pool, Chained_Pool *p, void *ptr)
219{
220 void *pmem;
221
222 // pool mem base
223 pmem = (void *)(((unsigned char *)p) + sizeof(Chained_Pool));
224
225 // is it in pool mem?
226 if (ptr < pmem)
227 {
228#ifdef DEBUG
229 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);
230#endif
231 return EINA_FALSE;
232 }
233
234 // freed node points to prev free node
235 eina_trash_push(&p->base, ptr);
236 // next free node is now the one we freed
237 p->usage--;
238 pool->usage--;
239 if (p->usage == 0)
240 {
241 // free bucket
242 pool->first = eina_inlist_remove(pool->first, EINA_INLIST_GET(p));
243 pool->root = eina_rbtree_inline_remove(pool->root, EINA_RBTREE_GET(p),
244 _eina_chained_mp_pool_cmp, NULL);
245 _eina_chained_mp_pool_free(p);
246
247 return EINA_TRUE;
248 }
249 else
250 {
251 // move to front
252 pool->first = eina_inlist_promote(pool->first, EINA_INLIST_GET(p));
253 }
254
255 return EINA_FALSE;
256}
257
258static void *
259eina_chained_mempool_malloc(void *data, __UNUSED__ unsigned int size)
260{
261 Chained_Mempool *pool = data;
262 Chained_Pool *p = NULL;
263 void *mem;
264
265 if (!eina_lock_take(&pool->mutex))
266 {
267#ifdef EFL_DEBUG_THREADS
268 assert(pthread_equal(pool->self, pthread_self()));
269#endif
270 }
271
272 // Either we have some free space in the first one, or there is no free space.
273 if (pool->first) p = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool);
274
275 // base is not NULL - has a free slot
276 if (p && !p->base && !p->last)
277 p = NULL;
278
279#ifdef DEBUG
280 if (p == NULL)
281 EINA_INLIST_FOREACH(pool->first, p)
282 assert(!p->base && !p->last);
283#endif
284
285 // we have reached the end of the list - no free pools
286 if (!p)
287 {
288 p = _eina_chained_mp_pool_new(pool);
289 if (!p)
290 {
291 eina_lock_release(&pool->mutex);
292 return NULL;
293 }
294
295 pool->first = eina_inlist_prepend(pool->first, EINA_INLIST_GET(p));
296 pool->root = eina_rbtree_inline_insert(pool->root, EINA_RBTREE_GET(p),
297 _eina_chained_mp_pool_cmp, NULL);
298 }
299
300 mem = _eina_chained_mempool_alloc_in(pool, p);
301
302 eina_lock_release(&pool->mutex);
303
304 return mem;
305}
306
307static void
308eina_chained_mempool_free(void *data, void *ptr)
309{
310 Chained_Mempool *pool = data;
311 Eina_Rbtree *r;
312 Chained_Pool *p;
313
314 // look 4 pool
315 if (!eina_lock_take(&pool->mutex))
316 {
317#ifdef EFL_DEBUG_THREADS
318 assert(pthread_equal(pool->self, pthread_self()));
319#endif
320 }
321
322 // searching for the right mempool
323 r = eina_rbtree_inline_lookup(pool->root, ptr, 0, _eina_chained_mp_pool_key_cmp, NULL);
324
325 // related mempool not found
326 if (!r)
327 {
328#ifdef DEBUG
329 INF("%p is not the property of %p Chained_Mempool", ptr, pool);
330#endif
331 goto on_error;
332 }
333
334 p = EINA_RBTREE_CONTAINER_GET(r, Chained_Pool);
335
336 _eina_chained_mempool_free_in(pool, p, ptr);
337
338 on_error:
339#ifndef NVALGRIND
340 if (ptr)
341 {
342 VALGRIND_MEMPOOL_FREE(pool, ptr);
343 }
344#endif
345
346 eina_lock_release(&pool->mutex);
347 return;
348}
349
350static void
351eina_chained_mempool_repack(void *data,
352 Eina_Mempool_Repack_Cb cb,
353 void *cb_data)
354{
355 Chained_Mempool *pool = data;
356 Chained_Pool *start;
357 Chained_Pool *tail;
358
359 /* FIXME: Improvement - per Chained_Pool lock */
360 if (!eina_lock_take(&pool->mutex))
361 {
362#ifdef EFL_DEBUG_THREADS
363 assert(pthread_equal(pool->self, pthread_self()));
364#endif
365 }
366
367 pool->first = eina_inlist_sort(pool->first,
368 (Eina_Compare_Cb) _eina_chained_mempool_usage_cmp);
369
370 /*
371 idea : remove the almost empty pool at the beginning of the list by
372 moving data in the last pool with empty slot
373 */
374 tail = EINA_INLIST_CONTAINER_GET(pool->first->last, Chained_Pool);
375 while (tail && tail->usage == pool->pool_size)
376 tail = EINA_INLIST_CONTAINER_GET((EINA_INLIST_GET(tail)->prev), Chained_Pool);
377
378 while (tail)
379 {
380 unsigned char *src;
381 unsigned char *dst;
382
383 start = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool);
384
385 if (start == tail || start->usage == pool->pool_size)
386 break;
387
388 for (src = start->limit - pool->group_size;
389 src != start->limit;
390 src += pool->item_alloc)
391 {
392 Eina_Bool is_free = EINA_FALSE;
393 Eina_Bool is_dead;
394
395 /* Do we have something inside that piece of memory */
396 if (start->last != NULL && src >= start->last)
397 {
398 is_free = EINA_TRUE;
399 }
400 else
401 {
402 Eina_Trash *over = start->base;
403
404 while (over != NULL && (unsigned char*) over != src)
405 over = over->next;
406
407 if (over == NULL)
408 is_free = EINA_TRUE;
409 }
410
411 if (is_free) continue ;
412
413 /* get a new memory pointer from the latest most occuped pool */
414 dst = _eina_chained_mempool_alloc_in(pool, tail);
415 /* move data from one to another */
416 memcpy(dst, src, pool->item_alloc);
417 /* notify caller */
418 cb(dst, src, cb_data);
419 /* destroy old pointer */
420 is_dead = _eina_chained_mempool_free_in(pool, start, src);
421
422 /* search last tail with empty slot */
423 while (tail && tail->usage == pool->pool_size)
424 tail = EINA_INLIST_CONTAINER_GET((EINA_INLIST_GET(tail)->prev),
425 Chained_Pool);
426 /* no more free space */
427 if (!tail || tail == start) break;
428 if (is_dead) break;
429 }
430 }
431
432 /* FIXME: improvement - reorder pool so that the most used one get in front */
433 eina_lock_release(&pool->mutex);
434}
435
436static void *
437eina_chained_mempool_realloc(__UNUSED__ void *data,
438 __UNUSED__ void *element,
439 __UNUSED__ unsigned int size)
440{
441 return NULL;
442}
443
444static void *
445eina_chained_mempool_init(const char *context,
446 __UNUSED__ const char *option,
447 va_list args)
448{
449 Chained_Mempool *mp;
450 int item_size;
451 size_t length;
452
453 length = context ? strlen(context) + 1 : 0;
454
455 mp = calloc(1, sizeof(Chained_Mempool) + length);
456 if (!mp)
457 return NULL;
458
459 item_size = va_arg(args, int);
460 mp->pool_size = va_arg(args, int);
461
462 if (length)
463 {
464 mp->name = (const char *)(mp + 1);
465 memcpy((char *)mp->name, context, length);
466 }
467
468#ifdef EINA_DEBUG_MALLOC
469 mp->minimal_size = item_size * mp->pool_size + sizeof(Chained_Pool);
470#endif
471
472 mp->item_alloc = eina_mempool_alignof(item_size);
473 mp->group_size = mp->item_alloc * mp->pool_size;
474 mp->alloc_size = mp->group_size + eina_mempool_alignof(sizeof(Chained_Pool));
475
476#ifndef NVALGRIND
477 VALGRIND_CREATE_MEMPOOL(mp, 0, 1);
478#endif
479
480#ifdef EFL_DEBUG_THREADS
481 mp->self = pthread_self();
482#endif
483
484 eina_lock_new(&mp->mutex);
485
486 return mp;
487}
488
489static void
490eina_chained_mempool_shutdown(void *data)
491{
492 Chained_Mempool *mp;
493
494 mp = (Chained_Mempool *)data;
495
496 while (mp->first)
497 {
498 Chained_Pool *p = (Chained_Pool *)mp->first;
499
500#ifdef DEBUG
501 if (p->usage > 0)
502 INF("Bad news we are destroying not an empty mempool [%s]\n",
503 mp->name);
504
505#endif
506
507 mp->first = eina_inlist_remove(mp->first, mp->first);
508 mp->root = eina_rbtree_inline_remove(mp->root, EINA_RBTREE_GET(p),
509 _eina_chained_mp_pool_cmp, NULL);
510 _eina_chained_mp_pool_free(p);
511 }
512
513#ifdef DEBUG
514 if (mp->root)
515 INF("Bad news, list of pool and rbtree are out of sync for %p !", mp);
516#endif
517
518#ifndef NVALGRIND
519 VALGRIND_DESTROY_MEMPOOL(mp);
520#endif
521
522 eina_lock_free(&mp->mutex);
523
524#ifdef EFL_DEBUG_THREADS
525 assert(pthread_equal(mp->self, pthread_self()));
526#endif
527
528 free(mp);
529}
530
531static Eina_Mempool_Backend _eina_chained_mp_backend = {
532 "chained_mempool",
533 &eina_chained_mempool_init,
534 &eina_chained_mempool_free,
535 &eina_chained_mempool_malloc,
536 &eina_chained_mempool_realloc,
537 NULL,
538 NULL,
539 &eina_chained_mempool_shutdown,
540 &eina_chained_mempool_repack
541};
542
543Eina_Bool chained_init(void)
544{
545#if defined DEBUG || defined EINA_DEBUG_MALLOC
546 _eina_chained_mp_log_dom = eina_log_domain_register("eina_mempool",
547 EINA_LOG_COLOR_DEFAULT);
548 if (_eina_chained_mp_log_dom < 0)
549 {
550 EINA_LOG_ERR("Could not register log domain: eina_mempool");
551 return EINA_FALSE;
552 }
553
554#endif
555 return eina_mempool_register(&_eina_chained_mp_backend);
556}
557
558void chained_shutdown(void)
559{
560 eina_mempool_unregister(&_eina_chained_mp_backend);
561#if defined DEBUG || defined EINA_DEBUG_MALLOC
562 eina_log_domain_unregister(_eina_chained_mp_log_dom);
563 _eina_chained_mp_log_dom = -1;
564#endif
565}
566
567#ifndef EINA_STATIC_BUILD_CHAINED_POOL
568
569EINA_MODULE_INIT(chained_init);
570EINA_MODULE_SHUTDOWN(chained_shutdown);
571
572#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 0000000000..50a4115adf
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_fixed/Makefile.am
@@ -0,0 +1,28 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_builddir)/src/include/eina \
7-I$(top_srcdir)/src/lib/eina \
8-I$(top_builddir)/src/lib/eina \
9@EMEMOA_CFLAGS@ \
10@EFL_EINA_BUILD@
11
12controllerdir = $(libdir)/eina/modules/mp/ememoa_fixed/$(MODULE_ARCH)
13controller_LTLIBRARIES = module.la
14
15module_la_SOURCES = eina_ememoa_fixed.c
16
17module_la_CFLAGS = @EINA_CFLAGS@
18module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EMEMOA_LIBS@ @EINA_LIBS@
19module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
20module_la_LIBTOOLFLAGS = --tag=disable-static
21
22install-data-hook:
23 rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
24uninstall-hook:
25 rm -f $(DESTDIR)$(controllerdir)/module.*
26
27clean-local:
28 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 0000000000..0d02f80bbb
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_fixed/eina_ememoa_fixed.c
@@ -0,0 +1,176 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric BAIL
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <stdlib.h>
24#include <string.h>
25#include <ememoa_mempool_fixed.h>
26
27#include "eina_inlist.h"
28#include "eina_error.h"
29#include "eina_module.h"
30#include "eina_mempool.h"
31
32#include "eina_private.h"
33
34typedef struct _Eina_Ememoa_Fixed_Mempool Eina_Ememoa_Fixed_Mempool;
35struct _Eina_Ememoa_Fixed_Mempool
36{
37 struct ememoa_mempool_desc_s *desc;
38 int pool;
39};
40
41static void *
42eina_ememoa_fixed_malloc(void *data, __UNUSED__ unsigned int size)
43{
44 Eina_Ememoa_Fixed_Mempool *efm = data;
45
46 return ememoa_mempool_fixed_pop_object(efm->pool);
47}
48
49static void
50eina_ememoa_fixed_free(void *data, void *ptr)
51{
52 Eina_Ememoa_Fixed_Mempool *efm = data;
53
54 ememoa_mempool_fixed_push_object(efm->pool, ptr);
55}
56
57static void *
58eina_ememoa_fixed_realloc(__UNUSED__ void *data,
59 __UNUSED__ void *element,
60 __UNUSED__ unsigned int size)
61{
62 return NULL;
63}
64
65static void
66eina_ememoa_fixed_gc(void *data)
67{
68 Eina_Ememoa_Fixed_Mempool *efm = data;
69
70 ememoa_mempool_fixed_garbage_collect(efm->pool);
71}
72
73static void
74eina_ememoa_fixed_statistics(void *data)
75{
76 Eina_Ememoa_Fixed_Mempool *efm = data;
77
78 ememoa_mempool_fixed_display_statistic(efm->pool);
79 (void)efm;
80}
81
82static void *
83eina_ememoa_fixed_init(const char *context,
84 __UNUSED__ const char *option,
85 va_list args)
86{
87 struct ememoa_mempool_desc_s *desc = NULL;
88 Eina_Ememoa_Fixed_Mempool *efm = NULL;
89 Eina_Bool thread_protect;
90 int context_length;
91 int item_size;
92 int pool_size;
93
94 if (context)
95 {
96 context_length = strlen(context) + 1;
97
98 desc = calloc(1, sizeof (struct ememoa_mempool_desc_s) + context_length);
99 if (!desc)
100 goto on_error;
101
102 desc->name = (char *)(desc + 1);
103 memcpy((char *)desc->name, context, context_length);
104 }
105
106 item_size = va_arg(args, int);
107 pool_size = va_arg(args, int);
108 thread_protect = va_arg(args, int);
109
110 efm = malloc(sizeof (Eina_Ememoa_Fixed_Mempool));
111 if (!efm)
112 goto on_error;
113
114 efm->desc = desc;
115 efm->pool = ememoa_mempool_fixed_init(
116 item_size,
117 pool_size,
118 thread_protect ?
119 EMEMOA_THREAD_PROTECTION : 0,
120 efm->desc);
121 if (efm->pool < 0)
122 goto on_error;
123
124 return efm;
125
126on_error:
127 if (desc)
128 free(desc);
129
130 if (efm)
131 free(efm);
132
133 return NULL;
134}
135
136static void
137eina_ememoa_fixed_shutdown(void *data)
138{
139 Eina_Ememoa_Fixed_Mempool *efm = data;
140
141 if (efm->desc)
142 free(efm->desc);
143
144 ememoa_mempool_fixed_clean(efm->pool);
145 free(efm);
146}
147
148static Eina_Mempool_Backend _eina_ememoa_mp_backend = {
149 .name = "ememoa_fixed",
150 .init = &eina_ememoa_fixed_init,
151 .shutdown = &eina_ememoa_fixed_shutdown,
152 .realloc = &eina_ememoa_fixed_realloc,
153 .alloc = &eina_ememoa_fixed_malloc,
154 .free = &eina_ememoa_fixed_free,
155 .garbage_collect = &eina_ememoa_fixed_gc,
156 .statistics = &eina_ememoa_fixed_statistics,
157 .repack = NULL
158};
159
160Eina_Bool ememoa_fixed_init(void)
161{
162 return eina_mempool_register(&_eina_ememoa_mp_backend);
163}
164
165void ememoa_fixed_shutdown(void)
166{
167 eina_mempool_unregister(&_eina_ememoa_mp_backend);
168}
169
170
171#ifndef EINA_STATIC_BUILD_EMEMOA_FIXED
172
173EINA_MODULE_INIT(ememoa_fixed_init);
174EINA_MODULE_SHUTDOWN(ememoa_fixed_shutdown);
175
176#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 0000000000..9713137110
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_unknown/Makefile.am
@@ -0,0 +1,28 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_builddir)/src/include/eina \
7-I$(top_srcdir)/src/lib/eina \
8-I$(top_builddir)/src/lib/eina \
9@EMEMOA_CFLAGS@ \
10@EFL_EINA_BUILD@
11
12controllerdir = $(libdir)/eina/modules/mp/ememoa_unknown/$(MODULE_ARCH)
13controller_LTLIBRARIES = module.la
14
15module_la_SOURCES = eina_ememoa_unknown.c
16
17module_la_CFLAGS = @EINA_CFLAGS@
18module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EMEMOA_LIBS@ @EINA_LIBS@
19module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
20module_la_LIBTOOLFLAGS = --tag=disable-static
21
22install-data-hook:
23 rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
24uninstall-hook:
25 rm -f $(DESTDIR)$(controllerdir)/module.*
26
27clean-local:
28 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 0000000000..56b99f66c9
--- /dev/null
+++ b/src/modules/eina/mp/ememoa_unknown/eina_ememoa_unknown.c
@@ -0,0 +1,182 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric BAIL
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <stdlib.h>
24#include <string.h>
25#include <ememoa_mempool_fixed.h>
26#include <ememoa_mempool_unknown_size.h>
27
28#include "eina_types.h"
29#include "eina_module.h"
30#include "eina_private.h"
31#include "eina_mempool.h"
32
33typedef struct _Eina_Ememoa_Unknown_Size_Mempool
34Eina_Ememoa_Unknown_Size_Mempool;
35struct _Eina_Ememoa_Unknown_Size_Mempool
36{
37 struct ememoa_mempool_desc_s *desc;
38 int pool;
39};
40
41static void *
42eina_ememoa_unknown_size_malloc(void *data, unsigned int size)
43{
44 Eina_Ememoa_Unknown_Size_Mempool *efm = data;
45
46 return ememoa_mempool_unknown_size_pop_object(efm->pool, size);
47}
48
49static void
50eina_ememoa_unknown_size_free(void *data, void *ptr)
51{
52 Eina_Ememoa_Unknown_Size_Mempool *efm = data;
53
54 ememoa_mempool_unknown_size_push_object(efm->pool, ptr);
55}
56
57static void *
58eina_ememoa_unknown_size_realloc(void *data, void *element, unsigned int size)
59{
60 Eina_Ememoa_Unknown_Size_Mempool *efm = data;
61
62 return ememoa_mempool_unknown_size_resize_object(efm->pool, element, size);
63}
64
65static void
66eina_ememoa_unknown_size_gc(void *data)
67{
68 Eina_Ememoa_Unknown_Size_Mempool *efm = data;
69
70 ememoa_mempool_unknown_size_garbage_collect(efm->pool);
71}
72
73static void
74eina_ememoa_unknown_size_statistics(void *data)
75{
76 Eina_Ememoa_Unknown_Size_Mempool *efm = data;
77
78 ememoa_mempool_unknown_size_display_statistic(efm->pool);
79}
80
81static void *
82eina_ememoa_unknown_size_init(const char *context,
83 __UNUSED__ const char *option,
84 va_list args)
85{
86 struct ememoa_mempool_desc_s *desc = NULL;
87 Eina_Ememoa_Unknown_Size_Mempool *efm = NULL;
88 Eina_Bool thread_protect;
89 unsigned int *items_map = NULL;
90 unsigned int items_count;
91 unsigned int i;
92 int context_length;
93
94 if (context)
95 {
96 context_length = strlen(context) + 1;
97
98 desc = calloc(1, sizeof (struct ememoa_mempool_desc_s) + context_length);
99 if (!desc)
100 goto on_error;
101
102 desc->name = (char *)(desc + 1);
103 memcpy((char *)desc->name, context, context_length);
104 }
105
106 thread_protect = va_arg(args, int);
107 items_count = va_arg(args, unsigned int);
108
109 items_map = malloc(sizeof (unsigned int) * 2 * items_count);
110
111 for (i = 0; i < (items_count << 1); ++i)
112 items_map[i] = va_arg(args, unsigned int);
113
114 efm = malloc(sizeof (Eina_Ememoa_Unknown_Size_Mempool));
115 if (!efm)
116 goto on_error;
117
118 efm->desc = desc;
119 efm->pool = ememoa_mempool_unknown_size_init(
120 items_count,
121 items_map,
122 thread_protect ?
123 EMEMOA_THREAD_PROTECTION : 0,
124 efm->desc);
125 if (efm->pool < 0)
126 goto on_error;
127
128 return efm;
129
130on_error:
131 if (items_map)
132 free(items_map);
133
134 if (desc)
135 free(desc);
136
137 if (efm)
138 free(efm);
139
140 return NULL;
141}
142
143static void
144eina_ememoa_unknown_size_shutdown(void *data)
145{
146 Eina_Ememoa_Unknown_Size_Mempool *efm = data;
147
148 if (efm->desc)
149 free(efm->desc);
150
151 ememoa_mempool_unknown_size_clean(efm->pool);
152 free(efm);
153}
154
155static Eina_Mempool_Backend _eina_ememoa_unknown_mp_backend = {
156 .name = "ememoa_unknown",
157 .init = &eina_ememoa_unknown_size_init,
158 .shutdown = &eina_ememoa_unknown_size_shutdown,
159 .realloc = &eina_ememoa_unknown_size_realloc,
160 .alloc = &eina_ememoa_unknown_size_malloc,
161 .free = &eina_ememoa_unknown_size_free,
162 .garbage_collect = &eina_ememoa_unknown_size_gc,
163 .statistics = &eina_ememoa_unknown_size_statistics,
164 .repack = NULL
165};
166
167Eina_Bool ememoa_unknown_init(void)
168{
169 return eina_mempool_register(&_eina_ememoa_unknown_mp_backend);
170}
171
172void ememoa_unknown_shutdown(void)
173{
174 eina_mempool_unregister(&_eina_ememoa_unknown_mp_backend);
175}
176
177#ifndef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
178
179EINA_MODULE_INIT(ememoa_unknown_init);
180EINA_MODULE_SHUTDOWN(ememoa_unknown_shutdown);
181
182#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 0000000000..2143676008
--- /dev/null
+++ b/src/modules/eina/mp/fixed_bitmap/Makefile.am
@@ -0,0 +1,27 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_builddir)/src/include/eina \
7-I$(top_srcdir)/src/lib/eina \
8-I$(top_builddir)/src/lib/eina \
9@EFL_EINA_BUILD@
10
11controllerdir = $(libdir)/eina/modules/mp/fixed_bitmap/$(MODULE_ARCH)
12controller_LTLIBRARIES = module.la
13
14module_la_SOURCES = eina_fixed_bitmap.c
15
16module_la_CFLAGS = @EINA_CFLAGS@
17module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
18module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
19module_la_LIBTOOLFLAGS = --tag=disable-static
20
21install-data-hook:
22 rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
23uninstall-hook:
24 rm -f $(DESTDIR)$(controllerdir)/module.*
25
26clean-local:
27 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 0000000000..e053e15790
--- /dev/null
+++ b/src/modules/eina/mp/fixed_bitmap/eina_fixed_bitmap.c
@@ -0,0 +1,270 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric BAIL
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#ifndef _MSC_VER
24# include <stdint.h>
25#endif
26#include <string.h>
27#include <assert.h>
28
29#ifdef HAVE_EVIL
30# include <Evil.h>
31#endif
32
33#include "eina_inlist.h"
34#include "eina_rbtree.h"
35#include "eina_error.h"
36
37#include "eina_mempool.h"
38
39#include "eina_private.h"
40
41typedef struct _Eina_Fixed_Bitmap Eina_Fixed_Bitmap;
42typedef struct _Eina_Fixed_Bitmap_Pool Eina_Fixed_Bitmap_Pool;
43
44struct _Eina_Fixed_Bitmap
45{
46 Eina_Rbtree *lookup;
47 Eina_Inlist *head;
48
49 int item_size;
50};
51
52struct _Eina_Fixed_Bitmap_Pool
53{
54 EINA_RBTREE;
55 EINA_INLIST;
56
57 uint32_t bitmask;
58};
59
60static inline size_t
61_eina_rbtree_inlist_delta(void)
62{
63 Eina_Fixed_Bitmap_Pool tmp;
64 void *a = &tmp.__rbtree;
65 void *b = &tmp.__in_list;
66
67 return (char *)a - (char *)b;
68}
69
70static Eina_Rbtree_Direction
71_eina_fixed_cmp(const Eina_Rbtree *left,
72 const Eina_Rbtree *right,
73 __UNUSED__ void *data)
74{
75 if (left - right < 0)
76 return EINA_RBTREE_LEFT;
77
78 return EINA_RBTREE_RIGHT;
79}
80
81static int
82_eina_fixed_cmp_key(const Eina_Rbtree *node,
83 const void *key,
84 __UNUSED__ int length,
85 Eina_Fixed_Bitmap *mp)
86{
87 const void *a = node;
88 const void *b = key;
89 ssize_t delta;
90 ssize_t limit;
91
92 limit = sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32;
93 delta = (char *)a - (char *)b;
94
95 if (delta > 0)
96 return 1;
97
98 if (delta + limit < 0)
99 return -1;
100
101 return 0;
102}
103
104static void
105_eina_fixed_bitmap_pool_free(Eina_Fixed_Bitmap_Pool *pool,
106 __UNUSED__ void *data)
107{
108 free(pool);
109}
110
111static void *
112eina_fixed_bitmap_malloc(void *data, __UNUSED__ unsigned int size)
113{
114 Eina_Fixed_Bitmap *mp = data;
115 Eina_Fixed_Bitmap_Pool *pool = NULL;
116 void *ptr;
117 int idx;
118
119 if (mp->head)
120 {
121 pool =
122 (Eina_Fixed_Bitmap_Pool *)((unsigned char *)mp->head +
123 _eina_rbtree_inlist_delta());
124
125 if (pool->bitmask == 0)
126 pool = NULL;
127 }
128
129 if (!pool)
130 {
131 eina_error_set(0);
132 pool = malloc(sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32);
133 if (!pool)
134 {
135 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
136 return NULL;
137 }
138
139 pool->bitmask = 0xFFFFFFFF;
140
141 mp->head = eina_inlist_prepend(mp->head, EINA_INLIST_GET(pool));
142 mp->lookup = eina_rbtree_inline_insert(mp->lookup, EINA_RBTREE_GET(
143 pool),
144 EINA_RBTREE_CMP_NODE_CB(
145 _eina_fixed_cmp), NULL);
146 }
147
148 idx = ffs(pool->bitmask) - 1;
149 pool->bitmask &= ~(1 << idx);
150 ptr = (unsigned char *)(pool + 1) + idx * mp->item_size;
151
152 if (pool->bitmask == 0)
153 mp->head = eina_inlist_demote(mp->head, EINA_INLIST_GET(pool));
154
155 return ptr;
156}
157
158static void
159eina_fixed_bitmap_free(void *data, void *ptr)
160{
161 Eina_Fixed_Bitmap *mp = data;
162 Eina_Fixed_Bitmap_Pool *pool;
163 void *a;
164 Eina_Bool push_front = EINA_FALSE;
165 ssize_t delta;
166
167 pool = (Eina_Fixed_Bitmap_Pool *)eina_rbtree_inline_lookup(
168 mp->lookup,
169 ptr,
170 0,
171 EINA_RBTREE_CMP_KEY_CB(
172 _eina_fixed_cmp_key),
173 mp);
174 if (!pool)
175 return;
176
177 if (pool->bitmask != 0xFFFFFFFF)
178 push_front = EINA_TRUE;
179
180 a = pool;
181 delta =
182 ((char *)ptr - (char *)a -
183 sizeof (Eina_Fixed_Bitmap_Pool)) / mp->item_size;
184
185 assert(delta >= 0 && delta < 32);
186
187 pool->bitmask |= (1 << (delta & 0x1F));
188
189 if (pool->bitmask == 0xFFFFFFFF)
190 {
191 mp->head = eina_inlist_remove(mp->head, EINA_INLIST_GET(pool));
192 mp->lookup = eina_rbtree_inline_remove(mp->lookup, EINA_RBTREE_GET(
193 pool),
194 EINA_RBTREE_CMP_NODE_CB(
195 _eina_fixed_cmp), NULL);
196 free(pool);
197 }
198 else if (push_front)
199 mp->head = eina_inlist_promote(mp->head, EINA_INLIST_GET(pool));
200}
201
202static void *
203eina_fixed_bitmap_realloc(__UNUSED__ void *data,
204 __UNUSED__ void *element,
205 __UNUSED__ unsigned int size)
206{
207 return NULL;
208}
209
210static void *
211eina_fixed_bitmap_init(__UNUSED__ const char *context,
212 __UNUSED__ const char *option,
213 va_list args)
214{
215 Eina_Fixed_Bitmap *mp;
216 int item_size;
217
218 mp = malloc(sizeof (Eina_Fixed_Bitmap));
219 if (!mp)
220 return NULL;
221
222 item_size = va_arg(args, int);
223
224 mp->item_size = eina_mempool_alignof(item_size);
225
226 mp->lookup = NULL;
227 mp->head = NULL;
228
229 return mp;
230}
231
232static void
233eina_fixed_bitmap_shutdown(void *data)
234{
235 Eina_Fixed_Bitmap *mp = data;
236
237 eina_rbtree_delete(mp->lookup,
238 EINA_RBTREE_FREE_CB(_eina_fixed_bitmap_pool_free), NULL);
239 free(mp);
240}
241
242static Eina_Mempool_Backend _eina_fixed_bitmap_mp_backend = {
243 "fixed_bitmap",
244 &eina_fixed_bitmap_init,
245 &eina_fixed_bitmap_free,
246 &eina_fixed_bitmap_malloc,
247 &eina_fixed_bitmap_realloc,
248 NULL,
249 NULL,
250 &eina_fixed_bitmap_shutdown,
251 NULL
252};
253
254Eina_Bool fixed_bitmap_init(void)
255{
256 return eina_mempool_register(&_eina_fixed_bitmap_mp_backend);
257}
258
259void fixed_bitmap_shutdown(void)
260{
261 eina_mempool_unregister(&_eina_fixed_bitmap_mp_backend);
262}
263
264#ifndef EINA_STATIC_BUILD_FIXED_BITMAP
265
266EINA_MODULE_INIT(fixed_bitmap_init);
267EINA_MODULE_SHUTDOWN(fixed_bitmap_shutdown);
268
269#endif /* ! EINA_STATIC_BUILD_FIXED_BITMAP */
270
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 0000000000..6a5efa531e
--- /dev/null
+++ b/src/modules/eina/mp/one_big/Makefile.am
@@ -0,0 +1,28 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_builddir)/src/include/eina \
7-I$(top_srcdir)/src/lib/eina \
8-I$(top_builddir)/src/lib/eina \
9@EFL_EINA_BUILD@ \
10@VALGRIND_CFLAGS@
11
12controllerdir = $(libdir)/eina/modules/mp/one_big/$(MODULE_ARCH)
13controller_LTLIBRARIES = module.la
14
15module_la_SOURCES = eina_one_big.c
16
17module_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@
18module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
19module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version @EFL_PTHREAD_LIBS@
20module_la_LIBTOOLFLAGS = --tag=disable-static
21
22install-data-hook:
23 rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
24uninstall-hook:
25 rm -f $(DESTDIR)$(controllerdir)/module.*
26
27clean-local:
28 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 0000000000..1159378dee
--- /dev/null
+++ b/src/modules/eina/mp/one_big/eina_one_big.c
@@ -0,0 +1,336 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2010 Cedric BAIL, Vincent Torri
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <stdlib.h>
24#include <string.h>
25
26#ifdef EFL_HAVE_POSIX_THREADS
27# include <pthread.h>
28#endif
29
30#include <assert.h>
31
32#ifdef EFL_HAVE_WIN32_THREADS
33# define WIN32_LEAN_AND_MEAN
34# include <windows.h>
35# undef WIN32_LEAN_AND_MEAN
36#endif
37
38#include "eina_mempool.h"
39#include "eina_trash.h"
40#include "eina_inlist.h"
41#include "eina_log.h"
42#include "eina_lock.h"
43
44#ifndef NVALGRIND
45# include <memcheck.h>
46#endif
47
48#include "eina_private.h"
49
50#ifdef INF
51#undef INF
52#endif
53#define INF(...) EINA_LOG_DOM_INFO(_eina_mempool_log_dom, __VA_ARGS__)
54
55#ifdef WRN
56#undef WRN
57#endif
58#define WRN(...) EINA_LOG_DOM_WARN(_eina_one_big_mp_log_dom, __VA_ARGS__)
59
60static int _eina_one_big_mp_log_dom = -1;
61
62typedef struct _One_Big One_Big;
63struct _One_Big
64{
65 const char *name;
66
67 int item_size;
68
69 int usage;
70 int over;
71
72 int served;
73 int max;
74 unsigned char *base;
75
76 Eina_Trash *empty;
77 Eina_Inlist *over_list;
78
79#ifdef EFL_DEBUG_THREADS
80 pthread_t self;
81#endif
82 Eina_Lock mutex;
83};
84
85static void *
86eina_one_big_malloc(void *data, __UNUSED__ unsigned int size)
87{
88 One_Big *pool = data;
89 unsigned char *mem = NULL;
90
91 if (!eina_lock_take(&pool->mutex))
92 {
93#ifdef EFL_DEBUG_THREADS
94 assert(pthread_equal(pool->self, pthread_self()));
95#endif
96 }
97
98 if (pool->empty)
99 {
100#ifndef NVALGRIND
101 VALGRIND_MAKE_MEM_DEFINED(pool->empty, pool->item_size);
102#endif
103 mem = eina_trash_pop(&pool->empty);
104 pool->usage++;
105 goto on_exit;
106 }
107
108 if (!pool->base)
109 {
110 pool->base = malloc(pool->item_size * pool->max);
111 if (!pool->base)
112 {
113 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
114 goto retry_smaller;
115 }
116#ifndef NVALGRIND
117 VALGRIND_MAKE_MEM_NOACCESS(pool->base, pool->item_size * pool->max);
118#endif
119 }
120
121 if (pool->served < pool->max)
122 {
123 mem = pool->base + (pool->served++ *pool->item_size);
124 pool->usage++;
125 goto on_exit;
126 }
127
128 retry_smaller:
129 eina_error_set(0);
130 mem = malloc(sizeof(Eina_Inlist) + pool->item_size);
131 if (!mem)
132 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
133 else
134 {
135 pool->over++;
136 memset(mem, 0, sizeof(Eina_Inlist));
137 pool->over_list = eina_inlist_append(pool->over_list,
138 (Eina_Inlist *)mem);
139 mem = ((unsigned char *)mem) + sizeof(Eina_Inlist);
140 }
141#ifndef NVALGRIND
142 VALGRIND_MAKE_MEM_NOACCESS(mem, pool->item_size);
143#endif
144
145on_exit:
146 eina_lock_release(&pool->mutex);
147
148#ifndef NVALGRIND
149 VALGRIND_MEMPOOL_ALLOC(pool, mem, pool->item_size);
150#endif
151 return mem;
152}
153
154static void
155eina_one_big_free(void *data, void *ptr)
156{
157 One_Big *pool = data;
158
159 if (!eina_lock_take(&pool->mutex))
160 {
161#ifdef EFL_DEBUG_THREADS
162 assert(pthread_equal(pool->self, pthread_self()));
163#endif
164 }
165
166 if ((void *)pool->base <= ptr
167 && ptr < (void *)(pool->base + (pool->max * pool->item_size)))
168 {
169 eina_trash_push(&pool->empty, ptr);
170 pool->usage--;
171 }
172 else
173 {
174#ifndef NDEBUG
175 Eina_Inlist *it;
176#endif
177 Eina_Inlist *il;
178
179 il = (Eina_Inlist *)(((unsigned char *)ptr) - sizeof(Eina_Inlist));
180
181#ifndef NDEBUG
182 for (it = pool->over_list; it != NULL; it = it->next)
183 if (it == il) break;
184
185 assert(it != NULL);
186#endif
187
188 pool->over_list = eina_inlist_remove(pool->over_list, il);
189 free(il);
190 pool->over--;
191 }
192
193#ifndef NVALGRIND
194 VALGRIND_MEMPOOL_FREE(pool, ptr);
195#endif
196
197 eina_lock_release(&pool->mutex);
198}
199
200static void *
201eina_one_big_realloc(__UNUSED__ void *data,
202 __UNUSED__ void *element,
203 __UNUSED__ unsigned int size)
204{
205 return NULL;
206}
207
208static void *
209eina_one_big_init(const char *context,
210 __UNUSED__ const char *option,
211 va_list args)
212{
213 One_Big *pool;
214 int item_size;
215 size_t length;
216
217 length = context ? strlen(context) + 1 : 0;
218
219 pool = calloc(1, sizeof (One_Big) + length);
220 if (!pool)
221 return NULL;
222
223 item_size = va_arg(args, int);
224
225 pool->item_size = eina_mempool_alignof(item_size);
226 pool->max = va_arg(args, int);
227
228 if (length)
229 {
230 pool->name = (const char *)(pool + 1);
231 memcpy((char *)pool->name, context, length);
232 }
233
234#ifdef EFL_DEBUG_THREADS
235 pool->self = pthread_self();
236#endif
237 eina_lock_new(&pool->mutex);
238
239#ifndef NVALGRIND
240 VALGRIND_CREATE_MEMPOOL(pool, 0, 1);
241#endif
242
243 return pool;
244}
245
246static void
247eina_one_big_shutdown(void *data)
248{
249 One_Big *pool = data;
250
251 if (!pool) return;
252 if (!eina_lock_take(&pool->mutex))
253 {
254#ifdef EFL_DEBUG_THREADS
255 assert(pthread_equal(pool->self, pthread_self()));
256#endif
257 }
258
259 if (pool->over > 0)
260 {
261// FIXME: should we warn here? one_big mempool exceeded its alloc and now
262// mempool is cleaning up the mess created. be quiet for now as we were before
263// but edje seems to be a big offender at the moment! bad cedric! :)
264// WRN(
265// "Pool [%s] over by %i. cleaning up for you",
266// pool->name, pool->over);
267 while (pool->over_list)
268 {
269 Eina_Inlist *il = pool->over_list;
270 pool->over_list = eina_inlist_remove(pool->over_list, il);
271 free(il);
272 pool->over--;
273 }
274 }
275 if (pool->over > 0)
276 {
277 WRN(
278 "Pool [%s] still over by %i\n",
279 pool->name, pool->over);
280 }
281
282#ifndef NVALGRIND
283 VALGRIND_DESTROY_MEMPOOL(pool);
284#endif
285
286 if (pool->base) free(pool->base);
287
288 eina_lock_release(&pool->mutex);
289 eina_lock_free(&pool->mutex);
290 free(pool);
291}
292
293
294static Eina_Mempool_Backend _eina_one_big_mp_backend = {
295 "one_big",
296 &eina_one_big_init,
297 &eina_one_big_free,
298 &eina_one_big_malloc,
299 &eina_one_big_realloc,
300 NULL,
301 NULL,
302 &eina_one_big_shutdown,
303 NULL
304};
305
306Eina_Bool one_big_init(void)
307{
308#ifdef DEBUG
309 _eina_one_big_mp_log_dom = eina_log_domain_register("eina_one_big_mempool",
310 EINA_LOG_COLOR_DEFAULT);
311 if (_eina_one_big_mp_log_dom < 0)
312 {
313 EINA_LOG_ERR("Could not register log domain: eina_one_big_mempool");
314 return EINA_FALSE;
315 }
316
317#endif
318 return eina_mempool_register(&_eina_one_big_mp_backend);
319}
320
321void one_big_shutdown(void)
322{
323 eina_mempool_unregister(&_eina_one_big_mp_backend);
324#ifdef DEBUG
325 eina_log_domain_unregister(_eina_one_big_mp_log_dom);
326 _eina_one_big_mp_log_dom = -1;
327#endif
328}
329
330#ifndef EINA_STATIC_BUILD_ONE_BIG
331
332EINA_MODULE_INIT(one_big_init);
333EINA_MODULE_SHUTDOWN(one_big_shutdown);
334
335#endif /* ! EINA_STATIC_BUILD_ONE_BIG */
336
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 0000000000..6d5f1687ee
--- /dev/null
+++ b/src/modules/eina/mp/pass_through/Makefile.am
@@ -0,0 +1,27 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_builddir)/src/include/eina \
7-I$(top_srcdir)/src/lib/eina \
8-I$(top_builddir)/src/lib/eina \
9@EFL_EINA_BUILD@
10
11controllerdir = $(libdir)//eina/modules/mp/pass_through/$(MODULE_ARCH)
12controller_LTLIBRARIES = module.la
13
14module_la_SOURCES = eina_pass_through.c
15
16module_la_CFLAGS = @EINA_CFLAGS@
17module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
18module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
19module_la_LIBTOOLFLAGS = --tag=disable-static
20
21install-data-hook:
22 rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
23uninstall-hook:
24 rm -f $(DESTDIR)$(controllerdir)/module.*
25
26clean-local:
27 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 0000000000..196868ecba
--- /dev/null
+++ b/src/modules/eina/mp/pass_through/eina_pass_through.c
@@ -0,0 +1,90 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric BAIL
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <stdlib.h>
24
25#include "eina_types.h"
26#include "eina_module.h"
27#include "eina_mempool.h"
28#include "eina_private.h"
29
30static void *
31eina_pass_through_malloc(__UNUSED__ void *data, unsigned int size)
32{
33 return malloc(size);
34}
35
36static void
37eina_pass_through_free(__UNUSED__ void *data, void *ptr)
38{
39 free(ptr);
40}
41
42static void *
43eina_pass_through_realloc(__UNUSED__ void *data, void *ptr, unsigned int size)
44{
45 return realloc(ptr, size);
46}
47
48static void *
49eina_pass_through_init(__UNUSED__ const char *context,
50 __UNUSED__ const char *option,
51 __UNUSED__ va_list args)
52{
53 return (void *)0x1;
54}
55
56static void
57eina_pass_through_shutdown(__UNUSED__ void *data)
58{
59}
60
61
62static Eina_Mempool_Backend _eina_pass_through_mp_backend = {
63 "pass_through",
64 &eina_pass_through_init,
65 &eina_pass_through_free,
66 &eina_pass_through_malloc,
67 &eina_pass_through_realloc,
68 NULL,
69 NULL,
70 &eina_pass_through_shutdown,
71 NULL
72};
73
74Eina_Bool pass_through_init(void)
75{
76 return eina_mempool_register(&_eina_pass_through_mp_backend);
77}
78
79void pass_through_shutdown(void)
80{
81 eina_mempool_unregister(&_eina_pass_through_mp_backend);
82}
83
84#ifndef EINA_STATIC_BUILD_PASS_THROUGH
85
86EINA_MODULE_INIT(pass_through_init);
87EINA_MODULE_SHUTDOWN(pass_through_shutdown);
88
89#endif /* ! EINA_STATIC_BUILD_PASS_THROUGH */
90