summaryrefslogtreecommitdiff
path: root/legacy/evas/src/lib/main.c
diff options
context:
space:
mode:
authorCarsten Haitzler <raster@rasterman.com>2005-11-23 10:43:54 +0000
committerCarsten Haitzler <raster@rasterman.com>2005-11-23 10:43:54 +0000
commit4ae547119941cc9939ea81d7b11b59abc5b99234 (patch)
treea4bf624def90ea2d5e5d2506bdace2a05a81cea0 /legacy/evas/src/lib/main.c
parentd7aa8d7dc9b6f6de095fe6dd1e5eba562a5ad83e (diff)
i'm playign with memory pools for evas lists. it seems to improve things.
SVN revision: 18612
Diffstat (limited to '')
-rw-r--r--legacy/evas/src/lib/main.c434
1 files changed, 434 insertions, 0 deletions
diff --git a/legacy/evas/src/lib/main.c b/legacy/evas/src/lib/main.c
index fce3bcb286..ac647f6fb9 100644
--- a/legacy/evas/src/lib/main.c
+++ b/legacy/evas/src/lib/main.c
@@ -207,3 +207,437 @@ evas_debug_magic_string_get(DATA32 magic)
207 }; 207 };
208 return "<UNKNOWN>"; 208 return "<UNKNOWN>";
209} 209}
210
211typedef struct _Evas_Mempool1 Evas_Mempool1;
212typedef struct _Evas_Mempool2 Evas_Mempool2;
213typedef unsigned int Evas_Mempool_Bitmask;
214
215struct _Evas_Mempool1 /* used if pool size <= 32 */
216{
217 Evas_Mempool_Bitmask allocated;
218 Evas_Mempool1 *next;
219 unsigned char *mem;
220};
221
222struct _Evas_Mempool2 /* used if pool size > 32 */
223{
224 Evas_Mempool_Bitmask allocated, filled;
225 Evas_Mempool_Bitmask allocated_list[32];
226 Evas_Mempool2 *next;
227 unsigned char *mem;
228};
229
230static Evas_Mempool1 *
231_evas_mempoool1_new(Evas_Mempool *pool)
232{
233 Evas_Mempool1 *mp;
234
235 if (pool->pool_size <= 32)
236 mp = malloc(sizeof(Evas_Mempool1) + (pool->item_size * pool->pool_size));
237 else
238 mp = malloc(sizeof(Evas_Mempool1) + (pool->item_size * 32));
239 mp->allocated = 0;
240 mp->next = NULL;
241 mp->mem = (unsigned char *)mp + sizeof(Evas_Mempool1);
242 return mp;
243}
244
245static void
246_evas_mempool1_free(Evas_Mempool1 *mp)
247{
248 free(mp);
249}
250
251static Evas_Mempool1 *
252_evas_mempool1_free_find(Evas_Mempool *pool, int *slot, Evas_Mempool1 **pmp)
253{
254 Evas_Mempool1 *mp;
255 int i, psize;
256 Evas_Mempool_Bitmask allocated;
257
258 psize = pool->pool_size;
259 if (psize > 32) psize = 32;
260 for (mp = (Evas_Mempool1 *)pool->first; mp; mp = mp->next)
261 {
262 allocated = mp->allocated;
263 if (allocated != 0xffffffff)
264 {
265 for (i = 0; i < psize; i++)
266 {
267 if ((allocated & (1 << i)) == 0)
268 {
269 *slot = i;
270 return mp;
271 }
272 }
273 }
274 *pmp = mp;
275 if (!mp->next) mp->next = _evas_mempoool1_new(pool);
276 }
277 return NULL;
278}
279
280static Evas_Mempool1 *
281_evas_mempool1_pointer_find(Evas_Mempool *pool, int *slot, Evas_Mempool1 **pmp, unsigned char *ptr)
282{
283 Evas_Mempool1 *mp;
284 int i, psize, isize;
285 unsigned char *mem;
286
287 psize = pool->pool_size;
288 if (psize > 32) psize = 32;
289 isize = pool->item_size;
290 for (mp = (Evas_Mempool1 *)pool->first; mp; mp = mp->next)
291 {
292 mem = mp->mem;
293 if (ptr >= mem)
294 {
295 i = (ptr - mem) / isize;
296 if (i < psize)
297 {
298 *slot = i;
299 return mp;
300 }
301 }
302 *pmp = mp;
303 }
304 return NULL;
305}
306
307static void
308_evas_mempool1_slot_set(Evas_Mempool1 *mp, int slot)
309{
310 mp->allocated |= (1 << slot);
311}
312
313static void
314_evas_mempool1_slot_unset(Evas_Mempool1 *mp, int slot)
315{
316 mp->allocated &= ~(1 << slot);
317}
318
319/*
320static void
321_evas_mempool1_debug(Evas_Mempool *pool)
322{
323 Evas_Mempool1 *mp;
324 int psize, isize, i, j, bits, space, allocated, nodes;
325
326 psize = pool->pool_size;
327 if (psize > 32) psize = 32;
328 isize = pool->item_size;
329 nodes = allocated = space = 0;
330 for (i = 0, mp = (Evas_Mempool1 *)pool->first; mp; mp = mp->next, i++)
331 {
332 bits = 0;
333
334 for (j = 0; j < 32; j++)
335 {
336 if ((mp->allocated & (1 << j)) != 0) bits++;
337 }
338 allocated += bits * isize;
339 space += psize * isize;
340 nodes++;
341// printf("pool %i, alloc %08x, full %i/%i\n",
342// i, mp->allocated, bits, 32);
343 }
344 printf("pool[0-32] %p usage (%i @ %i, %i nodes) %3.1f%%\n",
345 pool, pool->usage, psize, nodes,
346 100.0 * (double)allocated / (double)space);
347}
348*/
349
350
351
352static Evas_Mempool2 *
353_evas_mempoool2_new(Evas_Mempool *pool)
354{
355 Evas_Mempool2 *mp;
356
357 if (pool->pool_size <= 1024)
358 mp = malloc(sizeof(Evas_Mempool2) + (pool->item_size * pool->pool_size));
359 else
360 mp = malloc(sizeof(Evas_Mempool2) + (pool->item_size * 1024));
361 mp->allocated = 0;
362 mp->filled = 0;
363 memset(mp->allocated_list, 0, sizeof(int) * 32);
364 mp->next = NULL;
365 mp->mem = (unsigned char *)mp + sizeof(Evas_Mempool2);
366 return mp;
367}
368
369static void
370_evas_mempool2_free(Evas_Mempool2 *mp)
371{
372 free(mp);
373}
374
375static Evas_Mempool2 *
376_evas_mempool2_free_find(Evas_Mempool *pool, int *slot, Evas_Mempool2 **pmp)
377{
378 Evas_Mempool2 *mp;
379 int i, j, psize, ps, bsize;
380 Evas_Mempool_Bitmask allocated, filled;
381
382 psize = pool->pool_size;
383 if (psize > 1024) psize = 1024;
384 bsize = (psize + 31) / 32;
385 for (mp = (Evas_Mempool2 *)pool->first; mp; mp = mp->next)
386 {
387 filled = mp->filled;
388 if (filled != 0xffffffff)
389 {
390 for (j = 0; j < bsize; j++)
391 {
392 if ((filled & (1 << j)) == 0)
393 {
394 if (j == bsize - 1)
395 ps = psize - (j * 32);
396 else
397 ps = 32;
398 allocated = mp->allocated_list[j];
399 for (i = 0; i < ps; i++)
400 {
401 if ((allocated & (1 << i)) == 0)
402 {
403 *slot = (j * 32) + i;
404 return mp;
405 }
406 }
407 }
408 }
409 }
410 *pmp = mp;
411 if (!mp->next) mp->next = _evas_mempoool2_new(pool);
412 }
413 return NULL;
414}
415
416static Evas_Mempool2 *
417_evas_mempool2_pointer_find(Evas_Mempool *pool, int *slot, Evas_Mempool2 **pmp, unsigned char *ptr)
418{
419 Evas_Mempool2 *mp;
420 int i, psize, isize;
421 unsigned char *mem;
422
423 psize = pool->pool_size;
424 if (psize > 1024) psize = 1024;
425 isize = pool->item_size;
426 for (mp = (Evas_Mempool2 *)pool->first; mp; mp = mp->next)
427 {
428 mem = mp->mem;
429 if (ptr >= mem)
430 {
431 i = (ptr - mem) / isize;
432 if (i < psize)
433 {
434 *slot = i;
435 return mp;
436 }
437 }
438 *pmp = mp;
439 }
440 return NULL;
441}
442
443static void
444_evas_mempool2_slot_set(Evas_Mempool2 *mp, int slot)
445{
446 int bucket;
447
448 bucket = slot / 32;
449 mp->allocated_list[bucket] |= (1 << (slot - (bucket * 32)));
450 mp->allocated |= (1 << bucket);
451 if (mp->allocated_list[bucket] == 0xffffffff)
452 mp->filled |= (1 << bucket);
453}
454
455static void
456_evas_mempool2_slot_unset(Evas_Mempool2 *mp, int slot)
457{
458 int bucket;
459
460 bucket = slot / 32;
461 mp->allocated_list[bucket] &= ~(1 << (slot - (bucket * 32)));
462 mp->filled &= ~(1 << bucket);
463 if (mp->allocated_list[bucket] == 0)
464 mp->allocated &= ~(1 << bucket);
465}
466
467/*
468static void
469_evas_mempool2_debug(Evas_Mempool *pool)
470{
471 Evas_Mempool2 *mp;
472 int psize, bsize, isize, i, j, ps, bits, allocated, space, nodes;
473
474 psize = pool->pool_size;
475 if (psize > 1024) psize = 1024;
476 bsize = (psize + 31) / 32;
477 isize = pool->item_size;
478 nodes = allocated = space = 0;
479 for (i = 0, mp = (Evas_Mempool2 *)pool->first; mp; mp = mp->next, i++)
480 {
481 for (i = 0; i < bsize; i++)
482 {
483 bits = 0;
484 if (i == bsize - 1)
485 ps = psize - (i * 32);
486 else
487 ps = 32;
488 for (j = 0; j < ps; j++)
489 {
490 if ((mp->allocated_list[i] & (1 << j)) != 0) bits++;
491 }
492// printf("pool %i, alloc %08x, full %i/%i\n",
493// i, mp->allocated, bits, 32);
494 allocated += bits * isize;
495 }
496 space += psize * isize;
497 nodes++;
498 }
499 printf("pool[32-1024] %p usage (%i @ %i, %i nodes) %3.1f%%\n",
500 pool, pool->usage, psize, nodes,
501 100.0 * (double)allocated / (double)space);
502}
503*/
504
505/*#define NOPOOL 1*/
506
507void *
508evas_mempool_malloc(Evas_Mempool *pool, int size)
509#ifdef NOPOOL
510{
511 return malloc(size);
512}
513#else
514{
515 if (pool->pool_size <= 32)
516 {
517 Evas_Mempool1 *mp, *pmp = NULL;
518 int freeslot;
519
520 mp = pool->first;
521 if (!mp)
522 {
523 mp = _evas_mempoool1_new(pool);
524 pool->first = mp;
525 freeslot = 0;
526 }
527 else mp = _evas_mempool1_free_find(pool, &freeslot, &pmp);
528 if (!mp) return NULL;
529 pool->usage++;
530 _evas_mempool1_slot_set(mp, freeslot);
531 if (mp->allocated == 0xffffffff)
532 {
533 if (mp->next)
534 {
535 if (pool->first == mp) pool->first = mp->next;
536 else pmp->next = mp;
537 mp->next = NULL;
538 }
539 }
540/* _evas_mempool1_debug(pool);*/
541 return mp->mem + (freeslot * pool->item_size);
542 }
543 else
544 {
545 Evas_Mempool2 *mp, *pmp = NULL;
546 int freeslot;
547
548 mp = pool->first;
549 if (!mp)
550 {
551 mp = _evas_mempoool2_new(pool);
552 pool->first = mp;
553 freeslot = 0;
554 }
555 else mp = _evas_mempool2_free_find(pool, &freeslot, &pmp);
556 if (!mp) return NULL;
557 pool->usage++;
558 _evas_mempool2_slot_set(mp, freeslot);
559 if (mp->allocated == 0xffffffff)
560 {
561 if (mp->next)
562 {
563 if (pool->first == mp) pool->first = mp->next;
564 else pmp->next = mp;
565 mp->next = NULL;
566 }
567 }
568/* _evas_mempool2_debug(pool);*/
569 return mp->mem + (freeslot * pool->item_size);
570 }
571}
572#endif
573
574void
575evas_mempool_free(Evas_Mempool *pool, void *ptr)
576#ifdef NOPOOL
577{
578 free(ptr);
579}
580#else
581{
582 if (pool->pool_size <= 32)
583 {
584 Evas_Mempool1 *mp, *pmp = NULL;
585 int allocslot;
586
587 mp = _evas_mempool1_pointer_find(pool, &allocslot, &pmp, (unsigned char*)ptr);
588 if (!mp) return;
589 _evas_mempool1_slot_unset(mp, allocslot);
590 if (mp->allocated == 0)
591 {
592 if (pool->first == mp) pool->first = mp->next;
593 else pmp->next = mp->next;
594 _evas_mempool1_free(mp);
595 }
596 else
597 {
598 if (pool->first != mp)
599 {
600 pmp->next = mp->next;
601 mp->next = pool->first;
602 pool->first = mp;
603 }
604 }
605 pool->usage--;
606 }
607 else
608 {
609 Evas_Mempool2 *mp, *pmp = NULL;
610 int allocslot;
611
612 mp = _evas_mempool2_pointer_find(pool, &allocslot, &pmp, (unsigned char*)ptr);
613 if (!mp) return;
614 _evas_mempool2_slot_unset(mp, allocslot);
615 if (mp->allocated == 0)
616 {
617 if (pool->first == mp) pool->first = mp->next;
618 else pmp->next = mp->next;
619 _evas_mempool2_free(mp);
620 }
621 else
622 {
623 if (pool->first != mp)
624 {
625 pmp->next = mp->next;
626 mp->next = pool->first;
627 pool->first = mp;
628 }
629 }
630 pool->usage--;
631 }
632}
633#endif
634
635void *
636evas_mempool_calloc(Evas_Mempool *pool, int size)
637{
638 void *mem;
639
640 mem = evas_mempool_malloc(pool, size);
641 memset(mem, 0, size);
642 return mem;
643}