aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_mempool.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_mempool.c')
-rw-r--r--libraries/eina/src/lib/eina_mempool.c387
1 files changed, 387 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_mempool.c b/libraries/eina/src/lib/eina_mempool.c
new file mode 100644
index 0000000..065532e
--- /dev/null
+++ b/libraries/eina/src/lib/eina_mempool.c
@@ -0,0 +1,387 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2007-2008 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#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <assert.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27
28#include "eina_config.h"
29#include "eina_private.h"
30#include "eina_hash.h"
31#include "eina_module.h"
32#include "eina_log.h"
33#include "eina_main.h"
34
35/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
36#include "eina_safety_checks.h"
37#include "eina_mempool.h"
38
39/*============================================================================*
40* Local *
41*============================================================================*/
42
43/**
44 * @cond LOCAL
45 */
46
47static Eina_Hash *_backends;
48static Eina_Array *_modules;
49static int _eina_mempool_log_dom = -1;
50
51#ifdef ERR
52#undef ERR
53#endif
54#define ERR(...) EINA_LOG_DOM_ERR(_eina_mempool_log_dom, __VA_ARGS__)
55
56#ifdef DBG
57#undef DBG
58#endif
59#define DBG(...) EINA_LOG_DOM_DBG(_eina_mempool_log_dom, __VA_ARGS__)
60
61
62static Eina_Mempool *
63_new_va(const char *name,
64 const char *context,
65 const char *options,
66 va_list args)
67{
68 Eina_Mempool_Backend *be;
69 Eina_Mempool *mp;
70
71 Eina_Error err = EINA_ERROR_NOT_MEMPOOL_MODULE;
72
73 eina_error_set(0);
74 be = eina_hash_find(_backends, name);
75 if ((!be) || (!be->init))
76 goto on_error;
77
78 err = EINA_ERROR_OUT_OF_MEMORY;
79 mp = calloc(1, sizeof(Eina_Mempool));
80 if (!mp)
81 goto on_error;
82
83 /* Work around ABI incompability introduced in Eina 1.1 */
84#define SBP(Property) mp->backend.Property = be->Property;
85 SBP(name);
86 SBP(init);
87 SBP(free);
88 SBP(alloc);
89 SBP(realloc);
90 SBP(garbage_collect);
91 SBP(statistics);
92 SBP(shutdown);
93#undef SBP
94
95 if (be->repack)
96 {
97 mp->backend2 = calloc(1, sizeof (Eina_Mempool_Backend_ABI2));
98 if (mp->backend2)
99 mp->backend2->repack = be->repack;
100 }
101
102 mp->backend_data = mp->backend.init(context, options, args);
103
104 return mp;
105
106on_error:
107 eina_error_set(err);
108 return NULL;
109}
110
111/* Built-in backend's prototypes */
112
113#ifdef EINA_STATIC_BUILD_BUDDY
114Eina_Bool buddy_init(void);
115void buddy_shutdown(void);
116#endif
117
118#ifdef EINA_STATIC_BUILD_CHAINED_POOL
119Eina_Bool chained_init(void);
120void chained_shutdown(void);
121#endif
122
123#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
124Eina_Bool ememoa_fixed_init(void);
125void ememoa_fixed_shutdown(void);
126#endif
127
128#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
129Eina_Bool ememoa_unknown_init(void);
130void ememoa_unknown_shutdown(void);
131#endif
132
133#ifdef EINA_STATIC_BUILD_FIXED_BITMAP
134Eina_Bool fixed_bitmap_init(void);
135void fixed_bitmap_shutdown(void);
136#endif
137
138#ifdef EINA_STATIC_BUILD_ONE_BIG
139Eina_Bool one_big_init(void);
140void one_big_shutdown(void);
141#endif
142
143#ifdef EINA_STATIC_BUILD_PASS_THROUGH
144Eina_Bool pass_through_init(void);
145void pass_through_shutdown(void);
146#endif
147
148/**
149 * @endcond
150 */
151
152/*============================================================================*
153* Global *
154*============================================================================*/
155
156/**
157 * @cond LOCAL
158 */
159
160EAPI Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE = 0;
161
162static const char EINA_ERROR_NOT_MEMPOOL_MODULE_STR[] =
163 "Not a memory pool module.";
164
165/**
166 * @endcond
167 */
168
169EAPI Eina_Bool
170eina_mempool_register(Eina_Mempool_Backend *be)
171{
172 EINA_SAFETY_ON_NULL_RETURN_VAL(be, 0);
173 DBG("be=%p, name=%p", be, be->name);
174 return eina_hash_add(_backends, be->name, be);
175}
176
177EAPI void
178eina_mempool_unregister(Eina_Mempool_Backend *be)
179{
180 EINA_SAFETY_ON_NULL_RETURN(be);
181 DBG("be=%p, name=%p", be, be->name);
182 eina_hash_del(_backends, be->name, be);
183}
184
185Eina_Bool
186eina_mempool_init(void)
187{
188 char *path;
189
190 _eina_mempool_log_dom = eina_log_domain_register("eina_mempool",
191 EINA_LOG_COLOR_DEFAULT);
192 if (_eina_mempool_log_dom < 0)
193 {
194 EINA_LOG_ERR("Could not register log domain: eina_mempool");
195 return 0;
196 }
197
198 EINA_ERROR_NOT_MEMPOOL_MODULE = eina_error_msg_static_register(
199 EINA_ERROR_NOT_MEMPOOL_MODULE_STR);
200 _backends = eina_hash_string_superfast_new(NULL);
201
202 /* dynamic backends */
203 _modules = eina_module_arch_list_get(NULL,
204 PACKAGE_LIB_DIR "/eina/modules/mp",
205 MODULE_ARCH);
206
207 path = eina_module_environment_path_get("HOME", "/.eina/mp/modules/mp");
208 _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH);
209 if (path)
210 free(path);
211
212 path = eina_module_environment_path_get("EINA_MODULES_MEMPOOL_DIR",
213 "/eina/modules/mp");
214 _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH);
215 if (path)
216 free(path);
217
218 path = eina_module_symbol_path_get((const void *)eina_init,
219 "/eina/modules/mp");
220 _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH);
221 if (path)
222 free(path);
223
224 if (!_modules)
225 {
226 ERR("no mempool modules able to be loaded.");
227 eina_hash_free(_backends);
228 goto mempool_init_error;
229 }
230
231 eina_module_list_load(_modules);
232
233 /* builtin backends */
234#ifdef EINA_STATIC_BUILD_BUDDY
235 buddy_init();
236#endif
237#ifdef EINA_STATIC_BUILD_CHAINED_POOL
238 chained_init();
239#endif
240#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
241 ememoa_fixed_init();
242#endif
243#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
244 ememoa_unknown_init();
245#endif
246#ifdef EINA_STATIC_BUILD_FIXED_BITMAP
247 fixed_bitmap_init();
248#endif
249#ifdef EINA_STATIC_BUILD_ONE_BIG
250 one_big_init();
251#endif
252#ifdef EINA_STATIC_BUILD_PASS_THROUGH
253 pass_through_init();
254#endif
255
256 return EINA_TRUE;
257
258mempool_init_error:
259 eina_log_domain_unregister(_eina_mempool_log_dom);
260 _eina_mempool_log_dom = -1;
261
262 return EINA_FALSE;
263}
264
265Eina_Bool
266eina_mempool_shutdown(void)
267{
268 /* builtin backends */
269#ifdef EINA_STATIC_BUILD_BUDDY
270 buddy_shutdown();
271#endif
272#ifdef EINA_STATIC_BUILD_CHAINED_POOL
273 chained_shutdown();
274#endif
275#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
276 ememoa_fixed_shutdown();
277#endif
278#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
279 ememoa_unknown_shutdown();
280#endif
281#ifdef EINA_STATIC_BUILD_FIXED_BITMAP
282 fixed_bitmap_shutdown();
283#endif
284#ifdef EINA_STATIC_BUILD_ONE_BIG
285 one_big_shutdown();
286#endif
287#ifdef EINA_STATIC_BUILD_PASS_THROUGH
288 pass_through_shutdown();
289#endif
290 /* dynamic backends */
291 eina_module_list_free(_modules);
292 if (_modules)
293 eina_array_free(_modules);
294
295 if (_backends)
296 eina_hash_free(_backends);
297
298 eina_log_domain_unregister(_eina_mempool_log_dom);
299 _eina_mempool_log_dom = -1;
300
301 return EINA_TRUE;
302}
303
304/*============================================================================*
305* API *
306*============================================================================*/
307
308EAPI Eina_Mempool *
309eina_mempool_add(const char *name,
310 const char *context,
311 const char *options,
312 ...)
313{
314 Eina_Mempool *mp;
315 va_list args;
316
317 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
318 DBG("name=%s, context=%s, options=%s",
319 name, context ? context : "", options ? options : "");
320
321 va_start(args, options);
322 mp = _new_va(name, context, options, args);
323 va_end(args);
324
325 DBG("name=%s, context=%s, options=%s, mp=%p",
326 name, context ? context : "", options ? options : "", mp);
327
328 return mp;
329}
330
331EAPI void eina_mempool_del(Eina_Mempool *mp)
332{
333 EINA_SAFETY_ON_NULL_RETURN(mp);
334 EINA_SAFETY_ON_NULL_RETURN(mp->backend.shutdown);
335 DBG("mp=%p", mp);
336 mp->backend.shutdown(mp->backend_data);
337 free(mp->backend2);
338 free(mp);
339}
340
341EAPI void eina_mempool_repack(Eina_Mempool *mp, Eina_Mempool_Repack_Cb cb, void *data)
342{
343 EINA_SAFETY_ON_NULL_RETURN(mp);
344 EINA_SAFETY_ON_NULL_RETURN(mp->backend2);
345 EINA_SAFETY_ON_NULL_RETURN(mp->backend2->repack);
346 DBG("mp=%p", mp);
347 mp->backend2->repack(mp->backend_data, cb, data);
348}
349
350EAPI void eina_mempool_gc(Eina_Mempool *mp)
351{
352 EINA_SAFETY_ON_NULL_RETURN(mp);
353 EINA_SAFETY_ON_NULL_RETURN(mp->backend.garbage_collect);
354 DBG("mp=%p", mp);
355 mp->backend.garbage_collect(mp->backend_data);
356}
357
358EAPI void eina_mempool_statistics(Eina_Mempool *mp)
359{
360 EINA_SAFETY_ON_NULL_RETURN(mp);
361 EINA_SAFETY_ON_NULL_RETURN(mp->backend.statistics);
362 DBG("mp=%p", mp);
363 mp->backend.statistics(mp->backend_data);
364}
365
366EAPI unsigned int
367eina_mempool_alignof(unsigned int size)
368{
369 int align;
370
371 if (size <= 2)
372 align = 2;
373 else if (size < 8)
374 align = 4;
375 else
376#if __WORDSIZE == 32
377 align = 8;
378
379#else
380 if (size < 16)
381 align = 8;
382 else
383 align = 16;
384#endif
385
386 return ((size / align) + 1) * align;
387}