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;

-- 


Reply via email to