summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubodh Kumar <s7158.kumar@samsung.com>2015-03-06 15:48:38 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-03-06 20:19:20 +0100
commit554b2cd9da44b55e598f32db94cf98ac43da58a0 (patch)
treec07845831f0e25288a999151d6673240e5d659f1
parent0bd2fc15e9c61adbbe794bdf5bd5639abf20ac6d (diff)
downloadefl-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--AUTHORS1
-rw-r--r--src/modules/eina/mp/chained_pool/eina_chained_mempool.c61
2 files changed, 40 insertions, 22 deletions
diff --git a/AUTHORS b/AUTHORS
index e15446a8e3..8db85383b2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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;