From d86f094d6732a6b522a32e373faee45345d7b19e Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 1 Aug 2014 12:21:40 +0200 Subject: [PATCH] eo: do not call eina_tls_get as often when in the main loop. eina_tls_get is really slow, having a fast path for the main loop does really help us right now. It is also unlikely that slowing down a little bit the use of eo in thread is going to have any impact on application speed any time soon. I win a +10% on expedite benchmark compared to without. Signed-off-by: Cedric BAIL --- src/lib/eo/Eo.h | 26 ++++++++++++++------------ src/lib/eo/eo.c | 28 +++++++++++++++++----------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 30ae45ea50..14e85f1c38 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -493,12 +493,13 @@ EAPI extern Eo_Hook_Call eo_hook_call_post; Hook(call.klass, call.obj, call.func, __VA_ARGS__); // cache OP id, get real fct and object data then do the call -#define EO_FUNC_COMMON_OP(Name, DefRet) \ - Eo_Op_Call_Data call; \ +#define EO_FUNC_COMMON_OP(Name, DefRet) \ + Eo_Op_Call_Data call; \ + Eina_Bool is_main_loop = eina_main_loop_is(); \ static Eo_Op op = EO_NOOP; \ if (op == EO_NOOP) \ - op = _eo_api_op_id_get((void*) Name, __FILE__, __LINE__); \ - if (!_eo_call_resolve(#Name, op, &call, __FILE__, __LINE__)) return DefRet; \ + op = _eo_api_op_id_get((void*) Name, is_main_loop, __FILE__, __LINE__); \ + if (!_eo_call_resolve(#Name, op, &call, is_main_loop, __FILE__, __LINE__)) return DefRet; \ _Eo_##Name##_func _func_ = (_Eo_##Name##_func) call.func; \ // to define an EAPI function @@ -566,13 +567,13 @@ EAPI extern Eo_Hook_Call eo_hook_call_post; #define EO_OP_SENTINEL { _EO_OP_API_ENTRY(NULL), NULL, 0, EO_OP_TYPE_INVALID, NULL } // returns the OP id corresponding to the given api_func -EAPI Eo_Op _eo_api_op_id_get(const void *api_func, const char *file, int line); +EAPI Eo_Op _eo_api_op_id_get(const void *api_func, Eina_Bool is_main_loop, const char *file, int line); // gets the real function pointer and the object data -EAPI Eina_Bool _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, const char *file, int line); +EAPI Eina_Bool _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, Eina_Bool is_main_loop, const char *file, int line); // start of eo_do barrier, gets the object pointer and ref it, put it on the stask -EAPI Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass, Eina_Bool is_super, const char *file, const char *func, int line); + EAPI Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass, Eina_Bool is_super, Eina_Bool is_main_loop, const char *file, const char *func, int line); // end of the eo_do barrier, unref the obj, move the stack pointer EAPI void _eo_do_end(const Eo **ojb); @@ -581,11 +582,12 @@ EAPI void _eo_do_end(const Eo **ojb); // eo object method calls batch, -#define _eo_do_common(eoid, clsid, is_super, ...) \ - ({ \ - const Eo *_eoid_ EO_DO_CLEANUP = eoid; \ - _eo_do_start(_eoid_, clsid, is_super, __FILE__, __FUNCTION__, __LINE__); \ - __VA_ARGS__; \ +#define _eo_do_common(eoid, clsid, is_super, ...) \ + ({ \ + Eina_Bool is_main_loop = eina_main_loop_is(); \ + const Eo *_eoid_ EO_DO_CLEANUP = eoid; \ + _eo_do_start(_eoid_, clsid, is_super, is_main_loop, __FILE__, __FUNCTION__, __LINE__); \ + __VA_ARGS__; \ }) diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index 261c2a96db..b5df088f82 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -390,9 +390,11 @@ _eo_call_stack_free(void *ptr) } static inline Eo_Call_Stack * -_eo_call_stack_get() +_eo_call_stack_get(Eina_Bool is_main_loop) { - Eo_Call_Stack *stack = eina_tls_get(_eo_call_stack_key); + static Eo_Call_Stack *main_loop_stack = NULL; + Eo_Call_Stack *stack = is_main_loop ? + main_loop_stack : eina_tls_get(_eo_call_stack_key); if (stack) return stack; @@ -403,7 +405,11 @@ _eo_call_stack_get() return NULL; } - if (!eina_tls_set(_eo_call_stack_key, stack)) + if (is_main_loop) + { + main_loop_stack = stack; + } + else if (!eina_tls_set(_eo_call_stack_key, stack)) { EINA_LOG_ERR("Could not set eo call stack in TLS key."); _eo_call_stack_free(stack); @@ -511,11 +517,11 @@ _eo_do_internal(const Eo *eo_id, const Eo_Class *cur_klass_id, } EAPI Eina_Bool -_eo_do_start(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool is_super, const char *file EINA_UNUSED, const char *func EINA_UNUSED, int line EINA_UNUSED) +_eo_do_start(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool is_super, Eina_Bool is_main_loop, const char *file EINA_UNUSED, const char *func EINA_UNUSED, int line EINA_UNUSED) { Eina_Bool ret = EINA_TRUE; Eo_Stack_Frame *fptr, *pfptr; - Eo_Call_Stack *stack = _eo_call_stack_get(); + Eo_Call_Stack *stack = _eo_call_stack_get(is_main_loop); if (stack->frame_ptr == stack->last_frame) _eo_call_stack_resize(stack, EINA_TRUE); @@ -542,7 +548,7 @@ EAPI void _eo_do_end(const Eo **eo_id EINA_UNUSED) { Eo_Stack_Frame *fptr; - Eo_Call_Stack *stack = _eo_call_stack_get(); + Eo_Call_Stack *stack = _eo_call_stack_get(eina_main_loop_is()); // Is it possible to extract information from the scope ? fptr = stack->frame_ptr; @@ -564,7 +570,7 @@ _eo_do_end(const Eo **eo_id EINA_UNUSED) } EAPI Eina_Bool -_eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, const char *file, int line) + _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, Eina_Bool is_main_loop, const char *file, int line) { Eo_Stack_Frame *fptr; const _Eo_Class *klass; @@ -573,7 +579,7 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, c if (op == EO_NOOP) return EINA_FALSE; - fptr = _eo_call_stack_get()->frame_ptr; + fptr = _eo_call_stack_get(is_main_loop)->frame_ptr; if (EINA_UNLIKELY(!fptr->o.obj)) return EINA_FALSE; @@ -755,11 +761,11 @@ _eo_api_desc_get(const void *api_func, const _Eo_Class *klass, const _Eo_Class * } EAPI Eo_Op -_eo_api_op_id_get(const void *api_func, const char *file, int line) +_eo_api_op_id_get(const void *api_func, Eina_Bool is_main_loop, const char *file, int line) { const Eo_Op_Description *desc; const _Eo_Class *klass; - Eo_Call_Stack *stack = _eo_call_stack_get(); + Eo_Call_Stack *stack = _eo_call_stack_get(is_main_loop); Eina_Bool class_ref = _eo_is_a_class(stack->frame_ptr->eo_id); @@ -926,7 +932,7 @@ Eo * _eo_add_internal_end(Eo *eo_id) { Eo_Stack_Frame *fptr; - Eo_Call_Stack *stack = _eo_call_stack_get(); + Eo_Call_Stack *stack = _eo_call_stack_get(eina_main_loop_is()); fptr = stack->frame_ptr;