summaryrefslogtreecommitdiff
path: root/src/modules/eina
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 /src/modules/eina
parent0bd2fc15e9c61adbbe794bdf5bd5639abf20ac6d (diff)
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>
Diffstat (limited to 'src/modules/eina')
-rw-r--r--src/modules/eina/mp/chained_pool/eina_chained_mempool.c61
1 files changed, 39 insertions, 22 deletions
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;
68static int aligned_chained_pool = 0; 68static int aligned_chained_pool = 0;
69static int page_size = 0; 69static int page_size = 0;
70 70
71typedef struct _Chained_Pool Chained_Pool;
72struct _Chained_Pool
73{
74 EINA_INLIST;
75 EINA_RBTREE;
76 Eina_Trash *base;
77 int usage;
78
79 unsigned char *last;
80 unsigned char *limit;
81};
82
71typedef struct _Chained_Mempool Chained_Mempool; 83typedef struct _Chained_Mempool Chained_Mempool;
72struct _Chained_Mempool 84struct _Chained_Mempool
73{ 85{
@@ -79,6 +91,7 @@ struct _Chained_Mempool
79 int alloc_size; 91 int alloc_size;
80 int group_size; 92 int group_size;
81 int usage; 93 int usage;
94 Chained_Pool* first_fill; //All allocation will happen in this chain,unless it is filled
82#ifdef EINA_DEBUG_MALLOC 95#ifdef EINA_DEBUG_MALLOC
83 int minimal_size; 96 int minimal_size;
84#endif 97#endif
@@ -88,17 +101,6 @@ struct _Chained_Mempool
88 Eina_Spinlock mutex; 101 Eina_Spinlock mutex;
89}; 102};
90 103
91typedef struct _Chained_Pool Chained_Pool;
92struct _Chained_Pool
93{
94 EINA_INLIST;
95 EINA_RBTREE;
96 Eina_Trash *base;
97 int usage;
98
99 unsigned char *last;
100 unsigned char *limit;
101};
102 104
103static inline Eina_Rbtree_Direction 105static inline Eina_Rbtree_Direction
104_eina_chained_mp_pool_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, EINA_UNUSED void *data) 106_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)
183 mem = p->last; 185 mem = p->last;
184 p->last += pool->item_alloc; 186 p->last += pool->item_alloc;
185 if (p->last >= p->limit) 187 if (p->last >= p->limit)
186 p->last = NULL; 188 p->last = NULL;
187 } 189 }
188 else 190 else
189 { 191 {
@@ -244,9 +246,14 @@ _eina_chained_mempool_free_in(Chained_Mempool *pool, Chained_Pool *p, void *ptr)
244 pool->first = eina_inlist_remove(pool->first, EINA_INLIST_GET(p)); 246 pool->first = eina_inlist_remove(pool->first, EINA_INLIST_GET(p));
245 pool->root = eina_rbtree_inline_remove(pool->root, EINA_RBTREE_GET(p), 247 pool->root = eina_rbtree_inline_remove(pool->root, EINA_RBTREE_GET(p),
246 _eina_chained_mp_pool_cmp, NULL); 248 _eina_chained_mp_pool_cmp, NULL);
249 if (pool->first_fill == p)
250 {
251 pool->first_fill = NULL;
252 pool->first_fill = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool);
253 }
247 _eina_chained_mp_pool_free(p); 254 _eina_chained_mp_pool_free(p);
248 255
249 return EINA_TRUE; 256 return EINA_TRUE;
250 } 257 }
251 else 258 else
252 { 259 {
@@ -271,12 +278,21 @@ eina_chained_mempool_malloc(void *data, EINA_UNUSED unsigned int size)
271#endif 278#endif
272 } 279 }
273 280
274 // Either we have some free space in the first one, or there is no free space. 281 //we have some free space in first fill chain
275 if (pool->first) p = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool); 282 if (pool->first_fill) p = pool->first_fill;
276 283
277 // base is not NULL - has a free slot 284 // base is not NULL - has a free slot
278 if (p && !p->base && !p->last) 285 if (p && !p->base && !p->last)
279 p = NULL; 286 {
287 //Current pointed chain is filled , so point it to first one
288 pool->first_fill = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool);
289 //Either first one has some free space or every chain is filled
290 if (pool->first_fill && !pool->first_fill->base && !pool->first_fill->last)
291 {
292 p = NULL;
293 pool->first_fill = NULL;
294 }
295 }
280 296
281#ifdef DEBUG 297#ifdef DEBUG
282 if (p == NULL) 298 if (p == NULL)
@@ -287,19 +303,20 @@ eina_chained_mempool_malloc(void *data, EINA_UNUSED unsigned int size)
287 // we have reached the end of the list - no free pools 303 // we have reached the end of the list - no free pools
288 if (!p) 304 if (!p)
289 { 305 {
290 p = _eina_chained_mp_pool_new(pool); 306 //new chain created ,point it to be the first_fill chain
291 if (!p) 307 pool->first_fill = _eina_chained_mp_pool_new(pool);
308 if (!pool->first_fill)
292 { 309 {
293 eina_spinlock_release(&pool->mutex); 310 eina_spinlock_release(&pool->mutex);
294 return NULL; 311 return NULL;
295 } 312 }
296 313
297 pool->first = eina_inlist_prepend(pool->first, EINA_INLIST_GET(p)); 314 pool->first = eina_inlist_prepend(pool->first, EINA_INLIST_GET(pool->first_fill));
298 pool->root = eina_rbtree_inline_insert(pool->root, EINA_RBTREE_GET(p), 315 pool->root = eina_rbtree_inline_insert(pool->root, EINA_RBTREE_GET(pool->first_fill),
299 _eina_chained_mp_pool_cmp, NULL); 316 _eina_chained_mp_pool_cmp, NULL);
300 } 317 }
301 318
302 mem = _eina_chained_mempool_alloc_in(pool, p); 319 mem = _eina_chained_mempool_alloc_in(pool, pool->first_fill);
303 320
304 eina_spinlock_release(&pool->mutex); 321 eina_spinlock_release(&pool->mutex);
305 322
@@ -487,7 +504,7 @@ eina_chained_mempool_init(const char *context,
487#ifdef EINA_HAVE_DEBUG_THREADS 504#ifdef EINA_HAVE_DEBUG_THREADS
488 mp->self = eina_thread_self(); 505 mp->self = eina_thread_self();
489#endif 506#endif
490 507 mp->first_fill = NULL;
491 eina_spinlock_new(&mp->mutex); 508 eina_spinlock_new(&mp->mutex);
492 509
493 return mp; 510 return mp;