summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-29 15:36:48 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-29 16:48:08 +0900
commita9fbe6cb8f35e00bb9ab4bca2873c13501a60697 (patch)
tree42997c025be8a690d4c5d7048817edcbdaf16b45
parent300003805136e709fffb50552e06fdc7a8d3d2d2 (diff)
eo callbacks - move to mempools for callback data for more speed
also help reduce fragmentation. also remove callbacks immediately if callbacks are not being walked at the time (as opposed to just marking them to need deletion then call a clean that if not being walked will walk all cb's when we already know what to remove). @optimize
-rw-r--r--src/lib/eo/eo_base_class.c121
1 files changed, 78 insertions, 43 deletions
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index 35c7a9c960..8ba4d700bc 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -878,35 +878,67 @@ struct _Eo_Callback_Description
878 Eina_Bool func_array : 1; 878 Eina_Bool func_array : 1;
879}; 879};
880 880
881static int _eo_callbacks = 0;
882static Eina_Mempool *_eo_callback_mempool = NULL;
883
884static void
885_eo_callback_free(Eo_Callback_Description *cb)
886{
887 if (!cb) return;
888 eina_mempool_free(_eo_callback_mempool, cb);
889 _eo_callbacks--;
890 if (_eo_callbacks == 0)
891 {
892 eina_mempool_del(_eo_callback_mempool);
893 _eo_callback_mempool = NULL;
894 }
895}
896
897static Eo_Callback_Description *
898_eo_callback_new(void)
899{
900 Eo_Callback_Description *cb;
901 if (!_eo_callback_mempool)
902 {
903 _eo_callback_mempool = eina_mempool_add
904 ("chained_mempool",
905 NULL, NULL,
906 sizeof(Eo_Callback_Description), 256);
907 if (!_eo_callback_mempool) return NULL;
908 }
909 cb = eina_mempool_calloc(_eo_callback_mempool,
910 sizeof(Eo_Callback_Description));
911 if (!cb)
912 {
913 if (_eo_callbacks == 0)
914 {
915 eina_mempool_del(_eo_callback_mempool);
916 _eo_callback_mempool = NULL;
917 }
918 return NULL;
919 }
920 _eo_callbacks++;
921 return cb;
922}
923
881/* Actually remove, doesn't care about walking list, or delete_me */ 924/* Actually remove, doesn't care about walking list, or delete_me */
882static void 925static void
883_eo_callback_remove(Efl_Object_Data *pd, Eo_Callback_Description *cb) 926_eo_callback_remove(Efl_Object_Data *pd, Eo_Callback_Description *cb)
884{ 927{
885 Eo_Callback_Description *itr, *pitr = NULL; 928 Eo_Callback_Description *itr, *pitr = NULL;
886 929
887 itr = pd->callbacks; 930 for (itr = pd->callbacks; itr; )
888
889 for ( ; itr; )
890 { 931 {
891 Eo_Callback_Description *titr = itr; 932 Eo_Callback_Description *titr = itr;
892 itr = itr->next; 933 itr = itr->next;
893 934
894 if (titr == cb) 935 if (titr == cb)
895 { 936 {
896 if (pitr) 937 if (pitr) pitr->next = titr->next;
897 { 938 else pd->callbacks = titr->next;
898 pitr->next = titr->next; 939 _eo_callback_free(titr);
899 }
900 else
901 {
902 pd->callbacks = titr->next;
903 }
904 free(titr);
905 }
906 else
907 {
908 pitr = titr;
909 } 940 }
941 else pitr = titr;
910 } 942 }
911} 943}
912 944
@@ -917,7 +949,7 @@ _eo_callback_remove_all(Efl_Object_Data *pd)
917 while (pd->callbacks) 949 while (pd->callbacks)
918 { 950 {
919 Eo_Callback_Description *next = pd->callbacks->next; 951 Eo_Callback_Description *next = pd->callbacks->next;
920 free(pd->callbacks); 952 _eo_callback_free(pd->callbacks);
921 pd->callbacks = next; 953 pd->callbacks = next;
922 } 954 }
923} 955}
@@ -928,12 +960,10 @@ _eo_callbacks_clear(Efl_Object_Data *pd)
928 Eo_Callback_Description *cb = NULL; 960 Eo_Callback_Description *cb = NULL;
929 961
930 /* If there are no deletions waiting. */ 962 /* If there are no deletions waiting. */
931 if (!pd->deletions_waiting) 963 if (!pd->deletions_waiting) return;
932 return;
933 964
934 /* Abort if we are currently walking the list. */ 965 /* Abort if we are currently walking the list. */
935 if (pd->walking_list > 0) 966 if (pd->walking_list > 0) return;
936 return;
937 967
938 pd->deletions_waiting = EINA_FALSE; 968 pd->deletions_waiting = EINA_FALSE;
939 969
@@ -942,10 +972,7 @@ _eo_callbacks_clear(Efl_Object_Data *pd)
942 Eo_Callback_Description *titr = cb; 972 Eo_Callback_Description *titr = cb;
943 cb = cb->next; 973 cb = cb->next;
944 974
945 if (titr->delete_me) 975 if (titr->delete_me) _eo_callback_remove(pd, titr);
946 {
947 _eo_callback_remove(pd, titr);
948 }
949 } 976 }
950} 977}
951 978
@@ -953,11 +980,10 @@ static void
953_eo_callbacks_sorted_insert(Efl_Object_Data *pd, Eo_Callback_Description *cb) 980_eo_callbacks_sorted_insert(Efl_Object_Data *pd, Eo_Callback_Description *cb)
954{ 981{
955 Eo_Callback_Description *itr, *itrp = NULL; 982 Eo_Callback_Description *itr, *itrp = NULL;
983
956 for (itr = pd->callbacks; itr && (itr->priority < cb->priority); 984 for (itr = pd->callbacks; itr && (itr->priority < cb->priority);
957 itr = itr->next) 985 itr = itr->next)
958 { 986 itrp = itr;
959 itrp = itr;
960 }
961 987
962 if (itrp) 988 if (itrp)
963 { 989 {
@@ -979,13 +1005,12 @@ _efl_object_event_callback_priority_add(Eo *obj, Efl_Object_Data *pd,
979 const void *user_data) 1005 const void *user_data)
980{ 1006{
981 const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}}; 1007 const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}};
982 Eo_Callback_Description *cb; 1008 Eo_Callback_Description *cb = _eo_callback_new();
983 1009
984 cb = calloc(1, sizeof(*cb));
985 if (!cb || !desc || !func) 1010 if (!cb || !desc || !func)
986 { 1011 {
987 ERR("Tried adding callback with invalid values: cb: %p desc: %p func: %p\n", cb, desc, func); 1012 ERR("Tried adding callback with invalid values: cb: %p desc: %p func: %p\n", cb, desc, func);
988 free(cb); 1013 _eo_callback_free(cb);
989 return EINA_FALSE; 1014 return EINA_FALSE;
990 } 1015 }
991 cb->items.item.desc = desc; 1016 cb->items.item.desc = desc;
@@ -1005,9 +1030,9 @@ _efl_object_event_callback_del(Eo *obj, Efl_Object_Data *pd,
1005 Efl_Event_Cb func, 1030 Efl_Event_Cb func,
1006 const void *user_data) 1031 const void *user_data)
1007{ 1032{
1008 Eo_Callback_Description *cb; 1033 Eo_Callback_Description *cb, *pcb;
1009 1034
1010 for (cb = pd->callbacks; cb; cb = cb->next) 1035 for (pcb = NULL, cb = pd->callbacks; cb; pcb = cb, cb = cb->next)
1011 { 1036 {
1012 if (!cb->delete_me && (cb->items.item.desc == desc) && 1037 if (!cb->delete_me && (cb->items.item.desc == desc) &&
1013 (cb->items.item.func == func) && (cb->func_data == user_data)) 1038 (cb->items.item.func == func) && (cb->func_data == user_data))
@@ -1015,8 +1040,14 @@ _efl_object_event_callback_del(Eo *obj, Efl_Object_Data *pd,
1015 const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}}; 1040 const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}};
1016 1041
1017 cb->delete_me = EINA_TRUE; 1042 cb->delete_me = EINA_TRUE;
1018 pd->deletions_waiting = EINA_TRUE; 1043 if (pd->walking_list > 0)
1019 _eo_callbacks_clear(pd); 1044 pd->deletions_waiting = EINA_FALSE;
1045 else
1046 {
1047 if (pcb) pcb->next = cb->next;
1048 else pd->callbacks = cb->next;
1049 _eo_callback_free(cb);
1050 }
1020 efl_event_callback_call(obj, EFL_EVENT_CALLBACK_DEL, (void *)arr); 1051 efl_event_callback_call(obj, EFL_EVENT_CALLBACK_DEL, (void *)arr);
1021 return EINA_TRUE; 1052 return EINA_TRUE;
1022 } 1053 }
@@ -1032,13 +1063,12 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd,
1032 Efl_Callback_Priority priority, 1063 Efl_Callback_Priority priority,
1033 const void *user_data) 1064 const void *user_data)
1034{ 1065{
1035 Eo_Callback_Description *cb; 1066 Eo_Callback_Description *cb = _eo_callback_new();
1036 1067
1037 cb = calloc(1, sizeof(*cb));
1038 if (!cb || !array) 1068 if (!cb || !array)
1039 { 1069 {
1040 ERR("Tried adding array of callbacks with invalid values: cb: %p array: %p\n", cb, array); 1070 ERR("Tried adding array of callbacks with invalid values: cb: %p array: %p\n", cb, array);
1041 free(cb); 1071 _eo_callback_free(cb);
1042 return EINA_FALSE; 1072 return EINA_FALSE;
1043 } 1073 }
1044 cb->func_data = (void *) user_data; 1074 cb->func_data = (void *) user_data;
@@ -1057,17 +1087,22 @@ _efl_object_event_callback_array_del(Eo *obj, Efl_Object_Data *pd,
1057 const Efl_Callback_Array_Item *array, 1087 const Efl_Callback_Array_Item *array,
1058 const void *user_data) 1088 const void *user_data)
1059{ 1089{
1060 Eo_Callback_Description *cb; 1090 Eo_Callback_Description *cb, *pcb;
1061 1091
1062 for (cb = pd->callbacks; cb; cb = cb->next) 1092 for (pcb = NULL, cb = pd->callbacks; cb; pcb = cb, cb = cb->next)
1063 { 1093 {
1064 if (!cb->delete_me && 1094 if (!cb->delete_me &&
1065 (cb->items.item_array == array) && (cb->func_data == user_data)) 1095 (cb->items.item_array == array) && (cb->func_data == user_data))
1066 { 1096 {
1067 cb->delete_me = EINA_TRUE; 1097 cb->delete_me = EINA_TRUE;
1068 pd->deletions_waiting = EINA_TRUE; 1098 if (pd->walking_list > 0)
1069 _eo_callbacks_clear(pd); 1099 pd->deletions_waiting = EINA_FALSE;
1070 1100 else
1101 {
1102 if (pcb) pcb->next = cb->next;
1103 else pd->callbacks = cb->next;
1104 _eo_callback_free(cb);
1105 }
1071 efl_event_callback_call(obj, EFL_EVENT_CALLBACK_DEL, (void *)array); 1106 efl_event_callback_call(obj, EFL_EVENT_CALLBACK_DEL, (void *)array);
1072 return EINA_TRUE; 1107 return EINA_TRUE;
1073 } 1108 }