1 /* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric BAIL
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/>.
33 #include "eina_inlist.h"
34 #include "eina_rbtree.h"
35 #include "eina_error.h"
37 #include "eina_mempool.h"
39 #include "eina_private.h"
41 typedef struct _Eina_Fixed_Bitmap Eina_Fixed_Bitmap;
42 typedef struct _Eina_Fixed_Bitmap_Pool Eina_Fixed_Bitmap_Pool;
44 struct _Eina_Fixed_Bitmap
52 struct _Eina_Fixed_Bitmap_Pool
61 _eina_rbtree_inlist_delta(void)
63 Eina_Fixed_Bitmap_Pool tmp;
64 void *a = &tmp.__rbtree;
65 void *b = &tmp.__in_list;
67 return (char *)a - (char *)b;
70 static Eina_Rbtree_Direction
71 _eina_fixed_cmp(const Eina_Rbtree *left,
72 const Eina_Rbtree *right,
73 __UNUSED__ void *data)
76 return EINA_RBTREE_LEFT;
78 return EINA_RBTREE_RIGHT;
82 _eina_fixed_cmp_key(const Eina_Rbtree *node,
84 __UNUSED__ int length,
85 Eina_Fixed_Bitmap *mp)
92 limit = sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32;
93 delta = (char *)a - (char *)b;
98 if (delta + limit < 0)
105 _eina_fixed_bitmap_pool_free(Eina_Fixed_Bitmap_Pool *pool,
106 __UNUSED__ void *data)
112 eina_fixed_bitmap_malloc(void *data, __UNUSED__ unsigned int size)
114 Eina_Fixed_Bitmap *mp = data;
115 Eina_Fixed_Bitmap_Pool *pool = NULL;
122 (Eina_Fixed_Bitmap_Pool *)((unsigned char *)mp->head +
123 _eina_rbtree_inlist_delta());
125 if (pool->bitmask == 0)
132 pool = malloc(sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32);
135 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
139 pool->bitmask = 0xFFFFFFFF;
141 mp->head = eina_inlist_prepend(mp->head, EINA_INLIST_GET(pool));
142 mp->lookup = eina_rbtree_inline_insert(mp->lookup, EINA_RBTREE_GET(
144 EINA_RBTREE_CMP_NODE_CB(
145 _eina_fixed_cmp), NULL);
148 idx = ffs(pool->bitmask) - 1;
149 pool->bitmask &= ~(1 << idx);
150 ptr = (unsigned char *)(pool + 1) + idx * mp->item_size;
152 if (pool->bitmask == 0)
153 mp->head = eina_inlist_demote(mp->head, EINA_INLIST_GET(pool));
159 eina_fixed_bitmap_free(void *data, void *ptr)
161 Eina_Fixed_Bitmap *mp = data;
162 Eina_Fixed_Bitmap_Pool *pool;
164 Eina_Bool push_front = EINA_FALSE;
167 pool = (Eina_Fixed_Bitmap_Pool *)eina_rbtree_inline_lookup(
171 EINA_RBTREE_CMP_KEY_CB(
172 _eina_fixed_cmp_key),
177 if (pool->bitmask != 0xFFFFFFFF)
178 push_front = EINA_TRUE;
182 ((char *)ptr - (char *)a -
183 sizeof (Eina_Fixed_Bitmap_Pool)) / mp->item_size;
185 assert(delta >= 0 && delta < 32);
187 pool->bitmask |= (1 << (delta & 0x1F));
189 if (pool->bitmask == 0xFFFFFFFF)
191 mp->head = eina_inlist_remove(mp->head, EINA_INLIST_GET(pool));
192 mp->lookup = eina_rbtree_inline_remove(mp->lookup, EINA_RBTREE_GET(
194 EINA_RBTREE_CMP_NODE_CB(
195 _eina_fixed_cmp), NULL);
199 mp->head = eina_inlist_promote(mp->head, EINA_INLIST_GET(pool));
203 eina_fixed_bitmap_realloc(__UNUSED__ void *data,
204 __UNUSED__ void *element,
205 __UNUSED__ unsigned int size)
211 eina_fixed_bitmap_init(__UNUSED__ const char *context,
212 __UNUSED__ const char *option,
215 Eina_Fixed_Bitmap *mp;
218 mp = malloc(sizeof (Eina_Fixed_Bitmap));
222 item_size = va_arg(args, int);
224 mp->item_size = eina_mempool_alignof(item_size);
233 eina_fixed_bitmap_shutdown(void *data)
235 Eina_Fixed_Bitmap *mp = data;
237 eina_rbtree_delete(mp->lookup,
238 EINA_RBTREE_FREE_CB(_eina_fixed_bitmap_pool_free), NULL);
242 static Eina_Mempool_Backend _eina_fixed_bitmap_mp_backend = {
244 &eina_fixed_bitmap_init,
245 &eina_fixed_bitmap_free,
246 &eina_fixed_bitmap_malloc,
247 &eina_fixed_bitmap_realloc,
250 &eina_fixed_bitmap_shutdown,
254 Eina_Bool fixed_bitmap_init(void)
256 return eina_mempool_register(&_eina_fixed_bitmap_mp_backend);
259 void fixed_bitmap_shutdown(void)
261 eina_mempool_unregister(&_eina_fixed_bitmap_mp_backend);
264 #ifndef EINA_STATIC_BUILD_FIXED_BITMAP
266 EINA_MODULE_INIT(fixed_bitmap_init);
267 EINA_MODULE_SHUTDOWN(fixed_bitmap_shutdown);
269 #endif /* ! EINA_STATIC_BUILD_FIXED_BITMAP */