diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2016-08-29 15:36:48 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2016-08-29 16:48:08 +0900 |
commit | a9fbe6cb8f35e00bb9ab4bca2873c13501a60697 (patch) | |
tree | 42997c025be8a690d4c5d7048817edcbdaf16b45 | |
parent | 300003805136e709fffb50552e06fdc7a8d3d2d2 (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.c | 121 |
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 | ||
881 | static int _eo_callbacks = 0; | ||
882 | static Eina_Mempool *_eo_callback_mempool = NULL; | ||
883 | |||
884 | static 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 | |||
897 | static 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 */ |
882 | static void | 925 | static 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 | } |