forked from enlightenment/efl
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>
This commit is contained in:
parent
0bd2fc15e9
commit
554b2cd9da
1
AUTHORS
1
AUTHORS
|
@ -50,6 +50,7 @@ Igor Murzov <e-mail@date.by>
|
||||||
Vladislav Brovko <v.brovko@samsung.com>
|
Vladislav Brovko <v.brovko@samsung.com>
|
||||||
ChunEon Park (Hermet) <hermet@hermet.pe.kr>
|
ChunEon Park (Hermet) <hermet@hermet.pe.kr>
|
||||||
Rajeev Ranjan (Rajeev) <rajeev.r@samsung.com> <rajeev.jnnce@gmail.com>
|
Rajeev Ranjan (Rajeev) <rajeev.r@samsung.com> <rajeev.jnnce@gmail.com>
|
||||||
|
Subodh Kumar <s7158.kumar@samsung.com>
|
||||||
|
|
||||||
Eet
|
Eet
|
||||||
---
|
---
|
||||||
|
|
|
@ -68,26 +68,6 @@ static int _eina_chained_mp_log_dom = -1;
|
||||||
static int aligned_chained_pool = 0;
|
static int aligned_chained_pool = 0;
|
||||||
static int page_size = 0;
|
static int page_size = 0;
|
||||||
|
|
||||||
typedef struct _Chained_Mempool Chained_Mempool;
|
|
||||||
struct _Chained_Mempool
|
|
||||||
{
|
|
||||||
Eina_Inlist *first;
|
|
||||||
Eina_Rbtree *root;
|
|
||||||
const char *name;
|
|
||||||
int item_alloc;
|
|
||||||
int pool_size;
|
|
||||||
int alloc_size;
|
|
||||||
int group_size;
|
|
||||||
int usage;
|
|
||||||
#ifdef EINA_DEBUG_MALLOC
|
|
||||||
int minimal_size;
|
|
||||||
#endif
|
|
||||||
#ifdef EINA_HAVE_DEBUG_THREADS
|
|
||||||
Eina_Thread self;
|
|
||||||
#endif
|
|
||||||
Eina_Spinlock mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _Chained_Pool Chained_Pool;
|
typedef struct _Chained_Pool Chained_Pool;
|
||||||
struct _Chained_Pool
|
struct _Chained_Pool
|
||||||
{
|
{
|
||||||
|
@ -100,6 +80,28 @@ struct _Chained_Pool
|
||||||
unsigned char *limit;
|
unsigned char *limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _Chained_Mempool Chained_Mempool;
|
||||||
|
struct _Chained_Mempool
|
||||||
|
{
|
||||||
|
Eina_Inlist *first;
|
||||||
|
Eina_Rbtree *root;
|
||||||
|
const char *name;
|
||||||
|
int item_alloc;
|
||||||
|
int pool_size;
|
||||||
|
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
|
||||||
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
Eina_Thread self;
|
||||||
|
#endif
|
||||||
|
Eina_Spinlock mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static inline Eina_Rbtree_Direction
|
static inline Eina_Rbtree_Direction
|
||||||
_eina_chained_mp_pool_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, EINA_UNUSED void *data)
|
_eina_chained_mp_pool_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, EINA_UNUSED void *data)
|
||||||
{
|
{
|
||||||
|
@ -244,6 +246,11 @@ _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->first = eina_inlist_remove(pool->first, EINA_INLIST_GET(p));
|
||||||
pool->root = eina_rbtree_inline_remove(pool->root, EINA_RBTREE_GET(p),
|
pool->root = eina_rbtree_inline_remove(pool->root, EINA_RBTREE_GET(p),
|
||||||
_eina_chained_mp_pool_cmp, NULL);
|
_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);
|
_eina_chained_mp_pool_free(p);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -271,12 +278,21 @@ eina_chained_mempool_malloc(void *data, EINA_UNUSED unsigned int size)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either we have some free space in the first one, or there is no free space.
|
//we have some free space in first fill chain
|
||||||
if (pool->first) p = EINA_INLIST_CONTAINER_GET(pool->first, Chained_Pool);
|
if (pool->first_fill) p = pool->first_fill;
|
||||||
|
|
||||||
// base is not NULL - has a free slot
|
// base is not NULL - has a free slot
|
||||||
if (p && !p->base && !p->last)
|
if (p && !p->base && !p->last)
|
||||||
|
{
|
||||||
|
//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;
|
p = NULL;
|
||||||
|
pool->first_fill = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (p == NULL)
|
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
|
// we have reached the end of the list - no free pools
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
p = _eina_chained_mp_pool_new(pool);
|
//new chain created ,point it to be the first_fill chain
|
||||||
if (!p)
|
pool->first_fill = _eina_chained_mp_pool_new(pool);
|
||||||
|
if (!pool->first_fill)
|
||||||
{
|
{
|
||||||
eina_spinlock_release(&pool->mutex);
|
eina_spinlock_release(&pool->mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pool->first = eina_inlist_prepend(pool->first, EINA_INLIST_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(p),
|
pool->root = eina_rbtree_inline_insert(pool->root, EINA_RBTREE_GET(pool->first_fill),
|
||||||
_eina_chained_mp_pool_cmp, NULL);
|
_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);
|
eina_spinlock_release(&pool->mutex);
|
||||||
|
|
||||||
|
@ -487,7 +504,7 @@ eina_chained_mempool_init(const char *context,
|
||||||
#ifdef EINA_HAVE_DEBUG_THREADS
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
mp->self = eina_thread_self();
|
mp->self = eina_thread_self();
|
||||||
#endif
|
#endif
|
||||||
|
mp->first_fill = NULL;
|
||||||
eina_spinlock_new(&mp->mutex);
|
eina_spinlock_new(&mp->mutex);
|
||||||
|
|
||||||
return mp;
|
return mp;
|
||||||
|
|
Loading…
Reference in New Issue