diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/eina/src/modules/mp/one_big/eina_one_big.c | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/libraries/eina/src/modules/mp/one_big/eina_one_big.c b/libraries/eina/src/modules/mp/one_big/eina_one_big.c deleted file mode 100644 index 1159378..0000000 --- a/libraries/eina/src/modules/mp/one_big/eina_one_big.c +++ /dev/null | |||
@@ -1,336 +0,0 @@ | |||
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 | |||
60 | static int _eina_one_big_mp_log_dom = -1; | ||
61 | |||
62 | typedef struct _One_Big One_Big; | ||
63 | struct _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 | |||
85 | static void * | ||
86 | eina_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 | |||
145 | on_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 | |||
154 | static void | ||
155 | eina_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 | |||
200 | static void * | ||
201 | eina_one_big_realloc(__UNUSED__ void *data, | ||
202 | __UNUSED__ void *element, | ||
203 | __UNUSED__ unsigned int size) | ||
204 | { | ||
205 | return NULL; | ||
206 | } | ||
207 | |||
208 | static void * | ||
209 | eina_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 | |||
246 | static void | ||
247 | eina_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 | |||
294 | static 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 | |||
306 | Eina_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 | |||
321 | void 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 | |||
332 | EINA_MODULE_INIT(one_big_init); | ||
333 | EINA_MODULE_SHUTDOWN(one_big_shutdown); | ||
334 | |||
335 | #endif /* ! EINA_STATIC_BUILD_ONE_BIG */ | ||
336 | |||