aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c')
-rw-r--r--libraries/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/libraries/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c b/libraries/eina/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c
new file mode 100644
index 0000000..e053e15
--- /dev/null
+++ b/libraries/eina/src/modules/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