raster pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=ce8e085d6d0a3338aeac7c3e458cb44b5e18b332
commit ce8e085d6d0a3338aeac7c3e458cb44b5e18b332 Author: Carsten Haitzler (Rasterman) <[email protected]> Date: Thu Nov 17 18:32:18 2016 +0900 efl object events - track del, cb add and cb del callback counts so hunting another callback issue i noticed some of THE most popular callbacks are: 1411 tick 1961 move 4157 pointer,move 7524 dirty 8090 damage 13052 render,flush,post 13052 render,flush,pre 13205 render,post 13205 render,pre 21706 recalc 21875 idle 27224 resize 27779 del 31011 idle,enter 31011 idle,exit 60461 callback,del 104546 callback,add 126400 animator,tick as you can see callback del, add and the general obj del cb's are right up there... so it is very likely a good idea to CHECK to see if anyone is listening before calling the callback for these very very very common calls. this is ifdef'd and turned on for now. it can be turned off. it shouldnt use more memory due to the way memory alignment works (likely all allocations will be multiples of 8 bytes anyway) so we're using spare unused space. the only q is - is management of the counts AND checking them worth it in general? it's really hard to tell given we dont have a lot of benchmarks that cover a lot of use cases... it doesnt seem to slow or speed anything up much in the genlist bounce test... so i think i need something more specific. @optimize --- src/lib/eo/eo_base_class.c | 69 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index 0e94434..5dbaf9a 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -9,6 +9,8 @@ #include "eo_ptr_indirection.h" #include "eo_private.h" +#define EFL_EVENT_SPECIAL_SKIP 1 + static int event_freeze_count = 0; typedef struct _Eo_Callback_Description Eo_Callback_Description; @@ -37,6 +39,11 @@ typedef struct unsigned short walking_list; unsigned short event_freeze_count; +#ifdef EFL_EVENT_SPECIAL_SKIP + unsigned short event_cb_efl_event_callback_add_count; + unsigned short event_cb_efl_event_callback_del_count; + unsigned short event_cb_efl_event_del_count; +#endif Eina_Bool deletions_waiting : 1; Eina_Bool callback_stopped : 1; Eina_Bool parent_sunk : 1; // If parent ref has already been settled (parent has been set, or we are in add_ref mode @@ -949,11 +956,49 @@ init_mempool: goto init_mempool_back; } +#ifdef EFL_EVENT_SPECIAL_SKIP + +#define CB_COUNT_INC(cnt) do { if ((cnt) != 0xffff) (cnt)++; } while(0) +#define CB_COUNT_DEC(cnt) do { if ((cnt) != 0xffff) (cnt)--; } while(0) + +static inline void +_special_event_count_inc(Efl_Object_Data *pd, const Efl_Callback_Array_Item *it) +{ + if (it->desc == EFL_EVENT_CALLBACK_ADD) + CB_COUNT_INC(pd->event_cb_efl_event_callback_add_count); + else if (it->desc == EFL_EVENT_CALLBACK_DEL) + CB_COUNT_INC(pd->event_cb_efl_event_callback_del_count); + else if (it->desc == EFL_EVENT_DEL) + CB_COUNT_INC(pd->event_cb_efl_event_del_count); +} + +static inline void +_special_event_count_dec(Efl_Object_Data *pd, const Efl_Callback_Array_Item *it) +{ + if (it->desc == EFL_EVENT_CALLBACK_ADD) + CB_COUNT_DEC(pd->event_cb_efl_event_callback_add_count); + else if (it->desc == EFL_EVENT_CALLBACK_DEL) + CB_COUNT_DEC(pd->event_cb_efl_event_callback_del_count); + else if (it->desc == EFL_EVENT_DEL) + CB_COUNT_DEC(pd->event_cb_efl_event_del_count); +} +#endif + /* Actually remove, doesn't care about walking list, or delete_me */ static void _eo_callback_remove(Efl_Object_Data *pd, Eo_Callback_Description **cb) { unsigned int length; +#ifdef EFL_EVENT_SPECIAL_SKIP + const Efl_Callback_Array_Item *it; + + if ((*cb)->func_array) + { + for (it = (*cb)->items.item_array; it->func; it++) + _special_event_count_dec(pd, it); + } + else _special_event_count_dec(pd, &((*cb)->items.item)); +#endif _eo_callback_free(*cb); @@ -974,6 +1019,11 @@ _eo_callback_remove_all(Efl_Object_Data *pd) eina_freeq_ptr_main_add(pd->callbacks, free, 0); pd->callbacks = NULL; pd->callbacks_count = 0; +#ifdef EFL_EVENT_SPECIAL_SKIP + pd->event_cb_efl_event_callback_add_count = 0; + pd->event_cb_efl_event_callback_del_count = 0; + pd->event_cb_efl_event_del_count = 0; +#endif } static void @@ -1082,6 +1132,9 @@ _efl_object_event_callback_priority_add(Eo *obj, Efl_Object_Data *pd, cb->func_data = (void *) user_data; cb->priority = priority; _eo_callbacks_sorted_insert(pd, cb); +#ifdef EFL_EVENT_SPECIAL_SKIP + _special_event_count_inc(pd, &(cb->items.item)); +#endif efl_event_callback_call(obj, EFL_EVENT_CALLBACK_ADD, (void *)arr); @@ -1135,8 +1188,10 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd, const void *user_data) { Eo_Callback_Description *cb = _eo_callback_new(); -#ifdef EO_DEBUG +#if defined(EFL_EVENT_SPECIAL_SKIP) || defined(EO_DEBUG) const Efl_Callback_Array_Item *it; +#endif +#ifdef EO_DEBUG const Efl_Callback_Array_Item *prev; #endif @@ -1160,6 +1215,10 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd, cb->items.item_array = array; cb->func_array = EINA_TRUE; _eo_callbacks_sorted_insert(pd, cb); +#ifdef EFL_EVENT_SPECIAL_SKIP + for (it = cb->items.item_array; it->func; it++) + _special_event_count_dec(pd, it); +#endif efl_event_callback_call(obj, EFL_EVENT_CALLBACK_ADD, (void *)array); @@ -1224,6 +1283,14 @@ _event_callback_call(Eo *obj_id, Efl_Object_Data *pd, Eina_Bool callback_already_stopped, ret; if (pd->callbacks_count == 0) return EINA_FALSE; +#ifdef EFL_EVENT_SPECIAL_SKIP + else if ((desc == EFL_EVENT_CALLBACK_ADD) && + (pd->event_cb_efl_event_callback_add_count == 0)) return EINA_FALSE; + else if ((desc == EFL_EVENT_CALLBACK_DEL) && + (pd->event_cb_efl_event_callback_del_count == 0)) return EINA_FALSE; + else if ((desc == EFL_EVENT_DEL) && + (pd->event_cb_efl_event_del_count == 0)) return EINA_FALSE; +#endif lookup = NULL; callback_already_stopped = pd->callback_stopped; --
