cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=554b2cd9da44b55e598f32db94cf98ac43da58a0

commit 554b2cd9da44b55e598f32db94cf98ac43da58a0
Author: Subodh Kumar <s7158.ku...@samsung.com>
Date:   Fri Mar 6 15:48:38 2015 +0100

    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 <ced...@osg.samsung.com>
---
 AUTHORS                                            |  1 +
 .../eina/mp/chained_pool/eina_chained_mempool.c    | 61 ++++++++++++++--------
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index e15446a..8db8538 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -50,6 +50,7 @@ Igor Murzov <e-m...@date.by>
 Vladislav Brovko <v.bro...@samsung.com>
 ChunEon Park (Hermet) <her...@hermet.pe.kr>
 Rajeev Ranjan (Rajeev) <rajee...@samsung.com> <rajeev.jn...@gmail.com>
+Subodh Kumar <s7158.ku...@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 c587ae0..5c916e7 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;

-- 


Reply via email to