Enlightenment CVS committal Author : raster Project : e17 Module : libs/evas
Dir : e17/libs/evas/src/lib Modified Files: main.c Log Message: i'm playign with memory pools for evas lists. it seems to improve things. =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/main.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -3 -r1.8 -r1.9 --- main.c 18 Jun 2005 01:00:29 -0000 1.8 +++ main.c 23 Nov 2005 10:43:54 -0000 1.9 @@ -207,3 +207,437 @@ }; return "<UNKNOWN>"; } + +typedef struct _Evas_Mempool1 Evas_Mempool1; +typedef struct _Evas_Mempool2 Evas_Mempool2; +typedef unsigned int Evas_Mempool_Bitmask; + +struct _Evas_Mempool1 /* used if pool size <= 32 */ +{ + Evas_Mempool_Bitmask allocated; + Evas_Mempool1 *next; + unsigned char *mem; +}; + +struct _Evas_Mempool2 /* used if pool size > 32 */ +{ + Evas_Mempool_Bitmask allocated, filled; + Evas_Mempool_Bitmask allocated_list[32]; + Evas_Mempool2 *next; + unsigned char *mem; +}; + +static Evas_Mempool1 * +_evas_mempoool1_new(Evas_Mempool *pool) +{ + Evas_Mempool1 *mp; + + if (pool->pool_size <= 32) + mp = malloc(sizeof(Evas_Mempool1) + (pool->item_size * pool->pool_size)); + else + mp = malloc(sizeof(Evas_Mempool1) + (pool->item_size * 32)); + mp->allocated = 0; + mp->next = NULL; + mp->mem = (unsigned char *)mp + sizeof(Evas_Mempool1); + return mp; +} + +static void +_evas_mempool1_free(Evas_Mempool1 *mp) +{ + free(mp); +} + +static Evas_Mempool1 * +_evas_mempool1_free_find(Evas_Mempool *pool, int *slot, Evas_Mempool1 **pmp) +{ + Evas_Mempool1 *mp; + int i, psize; + Evas_Mempool_Bitmask allocated; + + psize = pool->pool_size; + if (psize > 32) psize = 32; + for (mp = (Evas_Mempool1 *)pool->first; mp; mp = mp->next) + { + allocated = mp->allocated; + if (allocated != 0xffffffff) + { + for (i = 0; i < psize; i++) + { + if ((allocated & (1 << i)) == 0) + { + *slot = i; + return mp; + } + } + } + *pmp = mp; + if (!mp->next) mp->next = _evas_mempoool1_new(pool); + } + return NULL; +} + +static Evas_Mempool1 * +_evas_mempool1_pointer_find(Evas_Mempool *pool, int *slot, Evas_Mempool1 **pmp, unsigned char *ptr) +{ + Evas_Mempool1 *mp; + int i, psize, isize; + unsigned char *mem; + + psize = pool->pool_size; + if (psize > 32) psize = 32; + isize = pool->item_size; + for (mp = (Evas_Mempool1 *)pool->first; mp; mp = mp->next) + { + mem = mp->mem; + if (ptr >= mem) + { + i = (ptr - mem) / isize; + if (i < psize) + { + *slot = i; + return mp; + } + } + *pmp = mp; + } + return NULL; +} + +static void +_evas_mempool1_slot_set(Evas_Mempool1 *mp, int slot) +{ + mp->allocated |= (1 << slot); +} + +static void +_evas_mempool1_slot_unset(Evas_Mempool1 *mp, int slot) +{ + mp->allocated &= ~(1 << slot); +} + +/* +static void +_evas_mempool1_debug(Evas_Mempool *pool) +{ + Evas_Mempool1 *mp; + int psize, isize, i, j, bits, space, allocated, nodes; + + psize = pool->pool_size; + if (psize > 32) psize = 32; + isize = pool->item_size; + nodes = allocated = space = 0; + for (i = 0, mp = (Evas_Mempool1 *)pool->first; mp; mp = mp->next, i++) + { + bits = 0; + + for (j = 0; j < 32; j++) + { + if ((mp->allocated & (1 << j)) != 0) bits++; + } + allocated += bits * isize; + space += psize * isize; + nodes++; +// printf("pool %i, alloc %08x, full %i/%i\n", +// i, mp->allocated, bits, 32); + } + printf("pool[0-32] %p usage (%i @ %i, %i nodes) %3.1f%%\n", + pool, pool->usage, psize, nodes, + 100.0 * (double)allocated / (double)space); +} +*/ + + + +static Evas_Mempool2 * +_evas_mempoool2_new(Evas_Mempool *pool) +{ + Evas_Mempool2 *mp; + + if (pool->pool_size <= 1024) + mp = malloc(sizeof(Evas_Mempool2) + (pool->item_size * pool->pool_size)); + else + mp = malloc(sizeof(Evas_Mempool2) + (pool->item_size * 1024)); + mp->allocated = 0; + mp->filled = 0; + memset(mp->allocated_list, 0, sizeof(int) * 32); + mp->next = NULL; + mp->mem = (unsigned char *)mp + sizeof(Evas_Mempool2); + return mp; +} + +static void +_evas_mempool2_free(Evas_Mempool2 *mp) +{ + free(mp); +} + +static Evas_Mempool2 * +_evas_mempool2_free_find(Evas_Mempool *pool, int *slot, Evas_Mempool2 **pmp) +{ + Evas_Mempool2 *mp; + int i, j, psize, ps, bsize; + Evas_Mempool_Bitmask allocated, filled; + + psize = pool->pool_size; + if (psize > 1024) psize = 1024; + bsize = (psize + 31) / 32; + for (mp = (Evas_Mempool2 *)pool->first; mp; mp = mp->next) + { + filled = mp->filled; + if (filled != 0xffffffff) + { + for (j = 0; j < bsize; j++) + { + if ((filled & (1 << j)) == 0) + { + if (j == bsize - 1) + ps = psize - (j * 32); + else + ps = 32; + allocated = mp->allocated_list[j]; + for (i = 0; i < ps; i++) + { + if ((allocated & (1 << i)) == 0) + { + *slot = (j * 32) + i; + return mp; + } + } + } + } + } + *pmp = mp; + if (!mp->next) mp->next = _evas_mempoool2_new(pool); + } + return NULL; +} + +static Evas_Mempool2 * +_evas_mempool2_pointer_find(Evas_Mempool *pool, int *slot, Evas_Mempool2 **pmp, unsigned char *ptr) +{ + Evas_Mempool2 *mp; + int i, psize, isize; + unsigned char *mem; + + psize = pool->pool_size; + if (psize > 1024) psize = 1024; + isize = pool->item_size; + for (mp = (Evas_Mempool2 *)pool->first; mp; mp = mp->next) + { + mem = mp->mem; + if (ptr >= mem) + { + i = (ptr - mem) / isize; + if (i < psize) + { + *slot = i; + return mp; + } + } + *pmp = mp; + } + return NULL; +} + +static void +_evas_mempool2_slot_set(Evas_Mempool2 *mp, int slot) +{ + int bucket; + + bucket = slot / 32; + mp->allocated_list[bucket] |= (1 << (slot - (bucket * 32))); + mp->allocated |= (1 << bucket); + if (mp->allocated_list[bucket] == 0xffffffff) + mp->filled |= (1 << bucket); +} + +static void +_evas_mempool2_slot_unset(Evas_Mempool2 *mp, int slot) +{ + int bucket; + + bucket = slot / 32; + mp->allocated_list[bucket] &= ~(1 << (slot - (bucket * 32))); + mp->filled &= ~(1 << bucket); + if (mp->allocated_list[bucket] == 0) + mp->allocated &= ~(1 << bucket); +} + +/* +static void +_evas_mempool2_debug(Evas_Mempool *pool) +{ + Evas_Mempool2 *mp; + int psize, bsize, isize, i, j, ps, bits, allocated, space, nodes; + + psize = pool->pool_size; + if (psize > 1024) psize = 1024; + bsize = (psize + 31) / 32; + isize = pool->item_size; + nodes = allocated = space = 0; + for (i = 0, mp = (Evas_Mempool2 *)pool->first; mp; mp = mp->next, i++) + { + for (i = 0; i < bsize; i++) + { + bits = 0; + if (i == bsize - 1) + ps = psize - (i * 32); + else + ps = 32; + for (j = 0; j < ps; j++) + { + if ((mp->allocated_list[i] & (1 << j)) != 0) bits++; + } +// printf("pool %i, alloc %08x, full %i/%i\n", +// i, mp->allocated, bits, 32); + allocated += bits * isize; + } + space += psize * isize; + nodes++; + } + printf("pool[32-1024] %p usage (%i @ %i, %i nodes) %3.1f%%\n", + pool, pool->usage, psize, nodes, + 100.0 * (double)allocated / (double)space); +} +*/ + +/*#define NOPOOL 1*/ + +void * +evas_mempool_malloc(Evas_Mempool *pool, int size) +#ifdef NOPOOL +{ + return malloc(size); +} +#else +{ + if (pool->pool_size <= 32) + { + Evas_Mempool1 *mp, *pmp = NULL; + int freeslot; + + mp = pool->first; + if (!mp) + { + mp = _evas_mempoool1_new(pool); + pool->first = mp; + freeslot = 0; + } + else mp = _evas_mempool1_free_find(pool, &freeslot, &pmp); + if (!mp) return NULL; + pool->usage++; + _evas_mempool1_slot_set(mp, freeslot); + if (mp->allocated == 0xffffffff) + { + if (mp->next) + { + if (pool->first == mp) pool->first = mp->next; + else pmp->next = mp; + mp->next = NULL; + } + } +/* _evas_mempool1_debug(pool);*/ + return mp->mem + (freeslot * pool->item_size); + } + else + { + Evas_Mempool2 *mp, *pmp = NULL; + int freeslot; + + mp = pool->first; + if (!mp) + { + mp = _evas_mempoool2_new(pool); + pool->first = mp; + freeslot = 0; + } + else mp = _evas_mempool2_free_find(pool, &freeslot, &pmp); + if (!mp) return NULL; + pool->usage++; + _evas_mempool2_slot_set(mp, freeslot); + if (mp->allocated == 0xffffffff) + { + if (mp->next) + { + if (pool->first == mp) pool->first = mp->next; + else pmp->next = mp; + mp->next = NULL; + } + } +/* _evas_mempool2_debug(pool);*/ + return mp->mem + (freeslot * pool->item_size); + } +} +#endif + +void +evas_mempool_free(Evas_Mempool *pool, void *ptr) +#ifdef NOPOOL +{ + free(ptr); +} +#else +{ + if (pool->pool_size <= 32) + { + Evas_Mempool1 *mp, *pmp = NULL; + int allocslot; + + mp = _evas_mempool1_pointer_find(pool, &allocslot, &pmp, (unsigned char*)ptr); + if (!mp) return; + _evas_mempool1_slot_unset(mp, allocslot); + if (mp->allocated == 0) + { + if (pool->first == mp) pool->first = mp->next; + else pmp->next = mp->next; + _evas_mempool1_free(mp); + } + else + { + if (pool->first != mp) + { + pmp->next = mp->next; + mp->next = pool->first; + pool->first = mp; + } + } + pool->usage--; + } + else + { + Evas_Mempool2 *mp, *pmp = NULL; + int allocslot; + + mp = _evas_mempool2_pointer_find(pool, &allocslot, &pmp, (unsigned char*)ptr); + if (!mp) return; + _evas_mempool2_slot_unset(mp, allocslot); + if (mp->allocated == 0) + { + if (pool->first == mp) pool->first = mp->next; + else pmp->next = mp->next; + _evas_mempool2_free(mp); + } + else + { + if (pool->first != mp) + { + pmp->next = mp->next; + mp->next = pool->first; + pool->first = mp; + } + } + pool->usage--; + } +} +#endif + +void * +evas_mempool_calloc(Evas_Mempool *pool, int size) +{ + void *mem; + + mem = evas_mempool_malloc(pool, size); + memset(mem, 0, size); + return mem; +} ------------------------------------------------------- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today Register for a JBoss Training Course. Free Certification Exam for All Training Attendees Through End of 2005. For more info visit: http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs