forked from enlightenment/efl
eina: implement a memory cache for Eina_Rbtree_Iterator.
So it seems we are using Eina_Hash_Iterator quite a lot more than before. This lead to a huge amount of alloc/free of Eina_Rbtree_Iterator that was noticable in Enlightenment callgrind trace. This patch make it vanish from the trace :-)
This commit is contained in:
parent
7da4d8a4ae
commit
b4456121be
|
@ -153,6 +153,7 @@ EAPI Eina_Inlist *_eina_tracking = NULL;
|
|||
S(cow);
|
||||
S(cpu);
|
||||
S(thread_queue);
|
||||
S(rbtree);
|
||||
/* no model for now
|
||||
S(model);
|
||||
*/
|
||||
|
@ -198,7 +199,8 @@ static const struct eina_desc_setup _eina_desc_setup[] = {
|
|||
S(thread),
|
||||
S(cow),
|
||||
S(cpu),
|
||||
S(thread_queue)
|
||||
S(thread_queue),
|
||||
S(rbtree)
|
||||
/* no model for now
|
||||
S(model)
|
||||
*/
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "eina_private.h"
|
||||
#include "eina_array.h"
|
||||
#include "eina_trash.h"
|
||||
#include "eina_lock.h"
|
||||
|
||||
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
|
||||
#include "eina_safety_checks.h"
|
||||
|
@ -64,6 +65,9 @@ struct _Eina_Iterator_Rbtree_List
|
|||
Eina_Bool up : 1;
|
||||
};
|
||||
|
||||
static Eina_Array iterator_trash;
|
||||
static Eina_Spinlock iterator_trash_lock;
|
||||
|
||||
static Eina_Iterator_Rbtree_List *
|
||||
_eina_rbtree_iterator_list_new(Eina_Iterator_Rbtree *it, const Eina_Rbtree *tree)
|
||||
{
|
||||
|
@ -93,7 +97,7 @@ _eina_rbtree_iterator_get_content(Eina_Iterator_Rbtree *it)
|
|||
}
|
||||
|
||||
static void
|
||||
_eina_rbtree_iterator_free(Eina_Iterator_Rbtree *it)
|
||||
_eina_rbtree_iterator_forced_free(Eina_Iterator_Rbtree *it)
|
||||
{
|
||||
Eina_Iterator_Rbtree_List *item;
|
||||
Eina_Array_Iterator et;
|
||||
|
@ -109,6 +113,22 @@ _eina_rbtree_iterator_free(Eina_Iterator_Rbtree *it)
|
|||
free(it);
|
||||
}
|
||||
|
||||
static void
|
||||
_eina_rbtree_iterator_free(Eina_Iterator_Rbtree *it)
|
||||
{
|
||||
if (eina_array_count(&iterator_trash) >= 7)
|
||||
{
|
||||
_eina_rbtree_iterator_forced_free(it);
|
||||
return ;
|
||||
}
|
||||
|
||||
eina_array_flush(it->stack);
|
||||
|
||||
eina_spinlock_take(&iterator_trash_lock);
|
||||
eina_array_push(&iterator_trash, it);
|
||||
eina_spinlock_release(&iterator_trash_lock);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_rbtree_iterator_next(Eina_Iterator_Rbtree *it, void **data)
|
||||
{
|
||||
|
@ -190,18 +210,23 @@ _eina_rbtree_iterator_build(const Eina_Rbtree *root, unsigned char mask)
|
|||
Eina_Iterator_Rbtree_List *first;
|
||||
Eina_Iterator_Rbtree *it;
|
||||
|
||||
it = calloc(1, sizeof (Eina_Iterator_Rbtree));
|
||||
if (!it) return NULL;
|
||||
eina_spinlock_take(&iterator_trash_lock);
|
||||
it = eina_array_pop(&iterator_trash);
|
||||
eina_spinlock_release(&iterator_trash_lock);
|
||||
|
||||
eina_trash_init(&it->trash);
|
||||
if (!it)
|
||||
{
|
||||
it = calloc(1, sizeof (Eina_Iterator_Rbtree));
|
||||
if (!it) return NULL;
|
||||
|
||||
it->stack = eina_array_new(8);
|
||||
if (!it->stack)
|
||||
goto on_error2;
|
||||
eina_trash_init(&it->trash);
|
||||
|
||||
it->stack = eina_array_new(8);
|
||||
if (!it->stack) goto on_error;
|
||||
}
|
||||
|
||||
first = _eina_rbtree_iterator_list_new(it, root);
|
||||
if (!first)
|
||||
goto on_error;
|
||||
if (!first) goto on_error;
|
||||
|
||||
eina_array_push(it->stack, first);
|
||||
|
||||
|
@ -218,10 +243,7 @@ _eina_rbtree_iterator_build(const Eina_Rbtree *root, unsigned char mask)
|
|||
return &it->iterator;
|
||||
|
||||
on_error:
|
||||
eina_array_free(it->stack);
|
||||
on_error2:
|
||||
free(it);
|
||||
|
||||
_eina_rbtree_iterator_free(it);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -512,3 +534,22 @@ eina_rbtree_delete(Eina_Rbtree *root, Eina_Rbtree_Free_Cb func, void *data)
|
|||
eina_rbtree_delete(root->son[1], func, data);
|
||||
func(root, data);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eina_rbtree_init(void)
|
||||
{
|
||||
eina_array_step_set(&iterator_trash, sizeof(iterator_trash), 8);
|
||||
return eina_spinlock_new(&iterator_trash_lock);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eina_rbtree_shutdown(void)
|
||||
{
|
||||
Eina_Iterator_Rbtree *it;
|
||||
|
||||
while ((it = eina_array_pop(&iterator_trash)))
|
||||
_eina_rbtree_iterator_forced_free(it);
|
||||
eina_array_flush(&iterator_trash);
|
||||
eina_spinlock_free(&iterator_trash_lock);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue