1 /* EINA - EFL data type library
2 * Copyright (C) 2007-2008 Jorge Luis Zapata Muga
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.
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.
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/>.
28 #include "eina_config.h"
29 #include "eina_private.h"
30 #include "eina_hash.h"
31 #include "eina_module.h"
33 #include "eina_main.h"
35 /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
36 #include "eina_safety_checks.h"
37 #include "eina_mempool.h"
39 /*============================================================================*
41 *============================================================================*/
47 static Eina_Hash *_backends;
48 static Eina_Array *_modules;
49 static int _eina_mempool_log_dom = -1;
54 #define ERR(...) EINA_LOG_DOM_ERR(_eina_mempool_log_dom, __VA_ARGS__)
59 #define DBG(...) EINA_LOG_DOM_DBG(_eina_mempool_log_dom, __VA_ARGS__)
63 _new_va(const char *name,
68 Eina_Mempool_Backend *be = NULL;
71 Eina_Error err = EINA_ERROR_NOT_MEMPOOL_MODULE;
74 if (getenv("EINA_MEMPOOL_PASS"))
76 be = eina_hash_find(_backends, "pass_through");
77 if (!be) be = eina_hash_find(_backends, name);
79 else be = eina_hash_find(_backends, name);
80 if ((!be) || (!be->init)) goto on_error;
82 err = EINA_ERROR_OUT_OF_MEMORY;
83 mp = calloc(1, sizeof(Eina_Mempool));
87 /* Work around ABI incompability introduced in Eina 1.1 */
88 #define SBP(Property) mp->backend.Property = be->Property;
101 mp->backend2 = calloc(1, sizeof (Eina_Mempool_Backend_ABI2));
103 mp->backend2->repack = be->repack;
106 mp->backend_data = mp->backend.init(context, options, args);
115 /* Built-in backend's prototypes */
117 #ifdef EINA_STATIC_BUILD_BUDDY
118 Eina_Bool buddy_init(void);
119 void buddy_shutdown(void);
122 #ifdef EINA_STATIC_BUILD_CHAINED_POOL
123 Eina_Bool chained_init(void);
124 void chained_shutdown(void);
127 #ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
128 Eina_Bool ememoa_fixed_init(void);
129 void ememoa_fixed_shutdown(void);
132 #ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
133 Eina_Bool ememoa_unknown_init(void);
134 void ememoa_unknown_shutdown(void);
137 #ifdef EINA_STATIC_BUILD_FIXED_BITMAP
138 Eina_Bool fixed_bitmap_init(void);
139 void fixed_bitmap_shutdown(void);
142 #ifdef EINA_STATIC_BUILD_ONE_BIG
143 Eina_Bool one_big_init(void);
144 void one_big_shutdown(void);
147 #ifdef EINA_STATIC_BUILD_PASS_THROUGH
148 Eina_Bool pass_through_init(void);
149 void pass_through_shutdown(void);
156 /*============================================================================*
158 *============================================================================*/
164 EAPI Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE = 0;
166 static const char EINA_ERROR_NOT_MEMPOOL_MODULE_STR[] =
167 "Not a memory pool module.";
174 eina_mempool_register(Eina_Mempool_Backend *be)
176 EINA_SAFETY_ON_NULL_RETURN_VAL(be, 0);
177 DBG("be=%p, name=%p", be, be->name);
178 return eina_hash_add(_backends, be->name, be);
182 eina_mempool_unregister(Eina_Mempool_Backend *be)
184 EINA_SAFETY_ON_NULL_RETURN(be);
185 DBG("be=%p, name=%p", be, be->name);
186 eina_hash_del(_backends, be->name, be);
190 eina_mempool_init(void)
194 _eina_mempool_log_dom = eina_log_domain_register("eina_mempool",
195 EINA_LOG_COLOR_DEFAULT);
196 if (_eina_mempool_log_dom < 0)
198 EINA_LOG_ERR("Could not register log domain: eina_mempool");
202 EINA_ERROR_NOT_MEMPOOL_MODULE = eina_error_msg_static_register(
203 EINA_ERROR_NOT_MEMPOOL_MODULE_STR);
204 _backends = eina_hash_string_superfast_new(NULL);
206 /* dynamic backends */
207 _modules = eina_module_arch_list_get(NULL,
208 PACKAGE_LIB_DIR "/eina/modules/mp",
211 path = eina_module_environment_path_get("HOME", "/.eina/mp/modules/mp");
212 _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH);
216 path = eina_module_environment_path_get("EINA_MODULES_MEMPOOL_DIR",
218 _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH);
222 path = eina_module_symbol_path_get((const void *)eina_init,
224 _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH);
230 ERR("no mempool modules able to be loaded.");
231 eina_hash_free(_backends);
232 goto mempool_init_error;
235 eina_module_list_load(_modules);
237 /* builtin backends */
238 #ifdef EINA_STATIC_BUILD_BUDDY
241 #ifdef EINA_STATIC_BUILD_CHAINED_POOL
244 #ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
247 #ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
248 ememoa_unknown_init();
250 #ifdef EINA_STATIC_BUILD_FIXED_BITMAP
253 #ifdef EINA_STATIC_BUILD_ONE_BIG
256 #ifdef EINA_STATIC_BUILD_PASS_THROUGH
263 eina_log_domain_unregister(_eina_mempool_log_dom);
264 _eina_mempool_log_dom = -1;
270 eina_mempool_shutdown(void)
272 /* builtin backends */
273 #ifdef EINA_STATIC_BUILD_BUDDY
276 #ifdef EINA_STATIC_BUILD_CHAINED_POOL
279 #ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
280 ememoa_fixed_shutdown();
282 #ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
283 ememoa_unknown_shutdown();
285 #ifdef EINA_STATIC_BUILD_FIXED_BITMAP
286 fixed_bitmap_shutdown();
288 #ifdef EINA_STATIC_BUILD_ONE_BIG
291 #ifdef EINA_STATIC_BUILD_PASS_THROUGH
292 pass_through_shutdown();
294 /* dynamic backends */
295 eina_module_list_free(_modules);
297 eina_array_free(_modules);
300 eina_hash_free(_backends);
302 eina_log_domain_unregister(_eina_mempool_log_dom);
303 _eina_mempool_log_dom = -1;
308 /*============================================================================*
310 *============================================================================*/
313 eina_mempool_add(const char *name,
321 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
322 DBG("name=%s, context=%s, options=%s",
323 name, context ? context : "", options ? options : "");
325 va_start(args, options);
326 mp = _new_va(name, context, options, args);
329 DBG("name=%s, context=%s, options=%s, mp=%p",
330 name, context ? context : "", options ? options : "", mp);
335 EAPI void eina_mempool_del(Eina_Mempool *mp)
337 EINA_SAFETY_ON_NULL_RETURN(mp);
338 EINA_SAFETY_ON_NULL_RETURN(mp->backend.shutdown);
340 mp->backend.shutdown(mp->backend_data);
345 EAPI void eina_mempool_repack(Eina_Mempool *mp, Eina_Mempool_Repack_Cb cb, void *data)
347 EINA_SAFETY_ON_NULL_RETURN(mp);
348 EINA_SAFETY_ON_NULL_RETURN(mp->backend2);
349 EINA_SAFETY_ON_NULL_RETURN(mp->backend2->repack);
351 mp->backend2->repack(mp->backend_data, cb, data);
354 EAPI void eina_mempool_gc(Eina_Mempool *mp)
356 EINA_SAFETY_ON_NULL_RETURN(mp);
357 EINA_SAFETY_ON_NULL_RETURN(mp->backend.garbage_collect);
359 mp->backend.garbage_collect(mp->backend_data);
362 EAPI void eina_mempool_statistics(Eina_Mempool *mp)
364 EINA_SAFETY_ON_NULL_RETURN(mp);
365 EINA_SAFETY_ON_NULL_RETURN(mp->backend.statistics);
367 mp->backend.statistics(mp->backend_data);
371 eina_mempool_alignof(unsigned int size)
390 return ((size / align) + 1) * align;