diff options
author | Subodh Kumar <s7158.kumar@samsung.com> | 2015-03-06 15:48:38 +0100 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2015-03-06 20:19:20 +0100 |
commit | 554b2cd9da44b55e598f32db94cf98ac43da58a0 (patch) | |
tree | c07845831f0e25288a999151d6673240e5d659f1 | |
parent | 0bd2fc15e9c61adbbe794bdf5bd5639abf20ac6d (diff) | |
download | efl-554b2cd9da44b55e598f32db94cf98ac43da58a0.tar.gz |
eina: minimize fragmentation of chainned mempool.
Summary:
Previously: Each allocation happened in the first chain after any free.
Now: All allocation will happen in one chain until all buckets are full, this can reduce
fragmentation to some extent.
Reviewers: seoz, govi, shilpasingh, raster, cedric
Reviewed By: cedric
Subscribers: cedric, rajeshps
Differential Revision: https://phab.enlightenment.org/D2071
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/modules/eina/mp/chained_pool/eina_chained_mempool.c | 61 |
2 files changed, 40 insertions, 22 deletions
@@ -50,6 +50,7 @@ Igor Murzov <e-mail@date.by> Vladislav Brovko <v.brovko@samsung.com> ChunEon Park (Hermet) <hermet@hermet.pe.kr> Rajeev Ranjan (Rajeev) <rajeev.r@samsung.com> <rajeev.jnnce@gmail.com> +Subodh Kumar <s7158.kumar@samsung.com> Eet --- diff --git a/src/modules/eina/mp/chained_pool/eina_chained_mempool.c b/src/modules/eina/mp/chained_pool/eina_chained_mempool.c index c587ae030c..5c916e7ef1 100644 --- a/src/modules/eina/mp/chained_pool/eina_chained_mempool.c +++ b/src/modules/eina/mp/chained_pool/eina_chained_mempool.c @@ -68,6 +68,18 @@ static int _eina_chained_mp_log_dom = -1; static int aligned_chained_pool = 0; static int page_size = 0; +typedef struct _Chained_Pool Chained_Pool; +struct _Chained_Pool +{ + EINA_INLIST; + EINA_RBTREE; + Eina_Trash *base; + int usage; + + unsigned char *last; + unsigned char *limit; +}; + typedef struct _Chained_Mempool Chained_Mempool; struct _Chained_Mempool { @@ -79,6 +91,7 @@ struct _Chained_Mempool int alloc_size; int group_size; int usage; + Chained_Pool* first_fill; //All allocation will happen in this chain,unless it is filled #ifdef EINA_DEBUG_MALLOC int minimal_size; #endif @@ -88,17 +101,6 @@ struct _Chained_Mempool Eina_Spinlock mutex; }; -typedef struct _Chained_Pool Chained_Pool; -struct _Chained_Pool -{ - EINA_INLIST; - EINA_RBTREE; - Eina_Trash *base; - int usage; - - unsigned char *last; - unsigned char *limit; -}; static inline Eina_Rbtree_Direction _eina_chained_mp_pool_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, EINA_UNUSED void *data) @@ -183,7 +185,7 @@ _eina_chained_mempool_alloc_in(Chained_Mempool *pool, Chained_Pool *p) mem = p->last; p->last += pool->item_alloc; if (p->last >= p->limit) - p->last = NULL; + p->last = NULL; } else { @@ -244,9 +246,14 @@ _eina_chained_mempool_free_in(Chained_Mempool *pool, Chained_Pool *p, void *ptr) pool->first = eina_inlist_remove(pool->first, EINA_INLIST_GET(p)); pool->root = eina_rbtree_inline_remove(pool->root, EINA_RBTREE_GET(p), _eina_chained_mp_pool_cmp, NULL); + if (pool->first_fill == p) + { + pool->first_fill = NULL; + pool->first_fill = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool); + } _eina_chained_mp_pool_free(p); - return EINA_TRUE; + return EINA_TRUE; } else { @@ -271,12 +278,21 @@ eina_chained_mempool_malloc(void *data, EINA_UNUSED unsigned int size) #endif } - // Either we have some free space in the first one, or there is no free space. - if (pool->first) p = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool); + //we have some free space in first fill chain + if (pool->first_fill) p = pool->first_fill; // base is not NULL - has a free slot if (p && !p->base && !p->last) - p = NULL; + { + //Current pointed chain is filled , so point it to first one + pool->first_fill = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool); + //Either first one has some free space or every chain is filled + if (pool->first_fill && !pool->first_fill->base && !pool->first_fill->last) + { + p = NULL; + pool->first_fill = NULL; + } + } #ifdef DEBUG if (p == NULL) @@ -287,19 +303,20 @@ eina_chained_mempool_malloc(void *data, EINA_UNUSED unsigned int size) // we have reached the end of the list - no free pools if (!p) { - p = _eina_chained_mp_pool_new(pool); - if (!p) + //new chain created ,point it to be the first_fill chain + pool->first_fill = _eina_chained_mp_pool_new(pool); + if (!pool->first_fill) { eina_spinlock_release(&pool->mutex); return NULL; } - pool->first = eina_inlist_prepend(pool->first, EINA_INLIST_GET(p)); - pool->root = eina_rbtree_inline_insert(pool->root, EINA_RBTREE_GET(p), + pool->first = eina_inlist_prepend(pool->first, EINA_INLIST_GET(pool->first_fill)); + pool->root = eina_rbtree_inline_insert(pool->root, EINA_RBTREE_GET(pool->first_fill), _eina_chained_mp_pool_cmp, NULL); } - mem = _eina_chained_mempool_alloc_in(pool, p); + mem = _eina_chained_mempool_alloc_in(pool, pool->first_fill); eina_spinlock_release(&pool->mutex); @@ -487,7 +504,7 @@ eina_chained_mempool_init(const char *context, #ifdef EINA_HAVE_DEBUG_THREADS mp->self = eina_thread_self(); #endif - + mp->first_fill = NULL; eina_spinlock_new(&mp->mutex); return mp; |