On 01/04/16 18:13, Davide Andreoli wrote: > 2016-03-29 17:04 GMT+02:00 Tom Hacohen <[email protected]>: > >> There you go. In, and fully tested (eo_suite_add_fallback suite) as >> promised. Please let me know if the tests fail on your box, though it's >> very unlikely because it's almost a direct copy from the previous eo_do >> implementation. >> > > hmmm, I have a problem with this change > EAPI Eo * > -_eo_add_internal_start(const char *file, int line, const Eo_Class > *klass_id, Eo *parent_id, Eina_Bool ref) > +_eo_add_internal_start(const char *file, int line, const Eo_Class > *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback) > > in bindings (both python and lua) we are directly using the > _eo_add_internal_start() > function instead of eo_add() because it's impossible (please prove I'm > wrong) to bind > so complex macros in cffi. > So the question is: what should I pass to the "is_fallback" param?
You should pass false. We need this because of a limitation in C that prevents us from having a context variable in macros that return a value. Since you are reimplementing this macro you are able to have a such a context variable, so you don't need the fallback support. See the non-fallback implementation for how it should be in python/lua. > > >> >> -- >> Tom. >> >> On 29/03/16 16:02, Tom Hacohen wrote: >>> tasn pushed a commit to branch master. >>> >>> >> http://git.enlightenment.org/core/efl.git/commit/?id=4a75116cb44ef10a93925d2505bcce337d663b6e >>> >>> commit 4a75116cb44ef10a93925d2505bcce337d663b6e >>> Author: Tom Hacohen <[email protected]> >>> Date: Tue Mar 29 14:47:22 2016 +0100 >>> >>> Eo: Implement the fallback eo_add implementation. >>> >>> The current eo_add uses a (very useful) gcc extension that is only >>> available in gcc compatible compilers (e.g clang). Until this >> commit we >>> just temporarily ignored this fact. This adds a fallback >> implementation that >>> can be used interchangeably with the non portable one. This means >> that the >>> same binary can call either at any point in time and the code will >> work. >>> >>> Breaks ABI. >>> --- >>> src/Makefile_Eo.am | 15 +++- >>> src/lib/eo/Eo.h | 30 +++++-- >>> src/lib/eo/eo.c | 25 +++++- >>> src/lib/eo/eo_add_fallback.c | 188 >> +++++++++++++++++++++++++++++++++++++++++++ >>> src/lib/eo/eo_add_fallback.h | 18 +++++ >>> 5 files changed, 267 insertions(+), 9 deletions(-) >>> >>> diff --git a/src/Makefile_Eo.am b/src/Makefile_Eo.am >>> index e388318..c8fbd52 100644 >>> --- a/src/Makefile_Eo.am >>> +++ b/src/Makefile_Eo.am >>> @@ -31,6 +31,8 @@ lib/eo/eo_ptr_indirection.c \ >>> lib/eo/eo_ptr_indirection.h \ >>> lib/eo/eo_base_class.c \ >>> lib/eo/eo_class_class.c \ >>> +lib/eo/eo_add_fallback.c \ >>> +lib/eo/eo_add_fallback.h \ >>> lib/eo/eo_private.h >>> >>> lib_eo_libeo_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EO_CFLAGS@ >>> @@ -58,6 +60,7 @@ tests/eo/test_interface \ >>> tests/eo/test_mixin \ >>> tests/eo/test_signals \ >>> tests/eo/test_children \ >>> +tests/eo/eo_suite_add_fallback \ >>> tests/eo/eo_suite >>> >>> tests_eo_test_children_SOURCES = \ >>> @@ -129,15 +132,25 @@ tests/eo/suite/eo_test_general.c \ >>> tests/eo/suite/eo_test_value.c \ >>> tests/eo/suite/eo_test_threaded_calls.c \ >>> tests/eo/suite/eo_test_init.c >>> + >>> tests_eo_eo_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ >>> -DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eo\" \ >>> @CHECK_CFLAGS@ \ >>> @EO_CFLAGS@ >>> -TESTS += tests/eo/eo_suite >>> >>> tests_eo_eo_suite_LDADD = @CHECK_LIBS@ @USE_EO_LIBS@ >>> tests_eo_eo_suite_DEPENDENCIES = @USE_EO_INTERNAL_LIBS@ >>> >>> +TESTS += tests/eo/eo_suite >>> + >>> +tests_eo_eo_suite_add_fallback_SOURCES = $(tests_eo_eo_suite_SOURCES) >>> +tests_eo_eo_suite_add_fallback_CPPFLAGS = $(tests_eo_eo_suite_CPPFLAGS) >> \ >>> + -D_EO_ADD_FALLBACK_FORCE=1 >>> +tests_eo_eo_suite_add_fallback_LDADD = $(tests_eo_eo_suite_LDADD) >>> +tests_eo_eo_suite_add_fallback_DEPENDENCIES = >> $(tests_eo_eo_suite_DEPENDENCIES) >>> + >>> +TESTS += tests/eo/eo_suite_add_fallback >>> + >>> tests_eo_test_function_overrides_SOURCES = \ >>> tests/eo/function_overrides/function_overrides_inherit.c \ >>> tests/eo/function_overrides/function_overrides_inherit.h \ >>> diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h >>> index 13d8283..dc6aa0e 100644 >>> --- a/src/lib/eo/Eo.h >>> +++ b/src/lib/eo/Eo.h >>> @@ -582,7 +582,7 @@ EAPI Eina_Bool _eo_call_resolve(Eo *obj, const char >> *func_name, Eo_Op_Call_Data >>> EAPI void _eo_call_end(Eo_Op_Call_Data *call); >>> >>> // end of the eo_add. Calls finalize among others >>> -EAPI Eo * _eo_add_end(Eo *obj); >>> +EAPI Eo * _eo_add_end(Eo *obj, Eina_Bool is_fallback); >>> >>> EAPI Eo *eo_super(const Eo *obj, const Eo_Class *cur_klass); >>> >>> @@ -597,15 +597,33 @@ EAPI Eo *eo_super(const Eo *obj, const Eo_Class >> *cur_klass); >>> */ >>> EAPI const Eo_Class *eo_class_get(const Eo *obj); >>> >>> -#define eo_self __eo_self >>> +EAPI Eo *_eo_self_get(void); >>> >>> -#define _eo_add_common(klass, parent, is_ref, ...) \ >>> +/* Check if GCC compatible (both GCC and clang define this) */ >>> +#if defined(__GNUC__) && !defined(_EO_ADD_FALLBACK_FORCE) >>> + >>> +# define eo_self __eo_self >>> + >>> +# define _eo_add_common(klass, parent, is_ref, ...) \ >>> ({ \ >>> - Eo * const __eo_self = _eo_add_internal_start(__FILE__, __LINE__, >> klass, parent, is_ref); \ >>> + Eo * const __eo_self = _eo_add_internal_start(__FILE__, __LINE__, >> klass, parent, is_ref, EINA_FALSE); \ >>> __VA_ARGS__; \ >>> - (Eo *) _eo_add_end(eo_self); \ >>> + (Eo *) _eo_add_end(eo_self, EINA_FALSE); \ >>> }) >>> >>> +#else >>> + >>> +# define eo_self _eo_self_get() >>> + >>> +# define _eo_add_common(klass, parent, is_ref, ...) \ >>> + ( \ >>> + _eo_add_internal_start(__FILE__, __LINE__, klass, parent, is_ref, >> EINA_TRUE), \ >>> + ##__VA_ARGS__, \ >>> + (Eo *) _eo_add_end(eo_self, EINA_TRUE) \ >>> + ) >>> + >>> +#endif >>> + >>> /** >>> * @def eo_add >>> * @brief Create a new object and call its constructor(If it exits). >>> @@ -644,7 +662,7 @@ EAPI const Eo_Class *eo_class_get(const Eo *obj); >>> */ >>> #define eo_add_ref(klass, parent, ...) _eo_add_common(klass, parent, >> EINA_TRUE, ##__VA_ARGS__) >>> >>> -EAPI Eo * _eo_add_internal_start(const char *file, int line, const >> Eo_Class *klass_id, Eo *parent, Eina_Bool ref); >>> +EAPI Eo * _eo_add_internal_start(const char *file, int line, const >> Eo_Class *klass_id, Eo *parent, Eina_Bool ref, Eina_Bool is_fallback); >>> >>> /** >>> * @brief Get a pointer to the data of an object for a specific class. >>> diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c >>> index ba12fbd..434ab3e 100644 >>> --- a/src/lib/eo/eo.c >>> +++ b/src/lib/eo/eo.c >>> @@ -13,6 +13,7 @@ >>> #include "Eo.h" >>> #include "eo_ptr_indirection.h" >>> #include "eo_private.h" >>> +#include "eo_add_fallback.h" >>> >>> #define EO_CLASS_IDS_FIRST 1 >>> #define EO_OP_IDS_FIRST 1 >>> @@ -615,9 +616,15 @@ _eo_class_funcs_set(_Eo_Class *klass) >>> } >>> >>> EAPI Eo * >>> -_eo_add_internal_start(const char *file, int line, const Eo_Class >> *klass_id, Eo *parent_id, Eina_Bool ref) >>> +_eo_add_internal_start(const char *file, int line, const Eo_Class >> *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback) >>> { >>> _Eo_Object *obj; >>> + Eo_Stack_Frame *fptr = NULL; >>> + >>> + if (is_fallback) >>> + { >>> + fptr = _eo_add_fallback_stack_push(NULL); >>> + } >>> >>> EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, NULL); >>> >>> @@ -680,6 +687,11 @@ _eo_add_internal_start(const char *file, int line, >> const Eo_Class *klass_id, Eo >>> return NULL; >>> } >>> >>> + if (is_fallback) >>> + { >>> + fptr->obj = eo_id; >>> + } >>> + >>> return eo_id; >>> } >>> >>> @@ -726,11 +738,16 @@ cleanup: >>> } >>> >>> EAPI Eo * >>> -_eo_add_end(Eo *eo_id) >>> +_eo_add_end(Eo *eo_id, Eina_Bool is_fallback) >>> { >>> Eo *ret = eo_finalize(eo_id); >>> ret = _eo_add_internal_end(eo_id, ret); >>> >>> + if (is_fallback) >>> + { >>> + _eo_add_fallback_stack_pop(); >>> + } >>> + >>> return ret; >>> } >>> >>> @@ -1595,6 +1612,8 @@ eo_init(void) >>> _eo_class_isa_func(NULL, NULL, NULL); >>> #endif >>> >>> + _eo_add_fallback_init(); >>> + >>> eina_log_timing(_eo_log_dom, >>> EINA_LOG_STATE_STOP, >>> EINA_LOG_STATE_INIT); >>> @@ -1618,6 +1637,8 @@ eo_shutdown(void) >>> EINA_LOG_STATE_START, >>> EINA_LOG_STATE_SHUTDOWN); >>> >>> + _eo_add_fallback_shutdown(); >>> + >>> for (i = 0 ; i < _eo_classes_last_id ; i++, cls_itr++) >>> { >>> if (*cls_itr) >>> diff --git a/src/lib/eo/eo_add_fallback.c b/src/lib/eo/eo_add_fallback.c >>> new file mode 100644 >>> index 0000000..6d714d6 >>> --- /dev/null >>> +++ b/src/lib/eo/eo_add_fallback.c >>> @@ -0,0 +1,188 @@ >>> +#ifdef HAVE_CONFIG_H >>> +# include <config.h> >>> +#endif >>> + >>> +#if defined HAVE_DLADDR && ! defined _WIN32 >>> +# include <dlfcn.h> >>> +#endif >>> + >>> +#include <Eina.h> >>> + >>> +#include "eo_ptr_indirection.h" >>> +#include "eo_private.h" >>> + >>> +#include "eo_add_fallback.h" >>> + >>> +// 1024 entries == 16k or 32k (32 or 64bit) for eo call stack. that's >> 1023 >>> +// imbricated/recursive calls it can handle before barfing. i'd say >> that's ok >>> +#define EO_CALL_STACK_DEPTH_MIN 1024 >>> + >>> +typedef struct _Eo_Call_Stack { >>> + Eo_Stack_Frame *frames; >>> + Eo_Stack_Frame *frame_ptr; >>> +} Eo_Call_Stack; >>> + >>> +#define EO_CALL_STACK_SIZE (EO_CALL_STACK_DEPTH_MIN * >> sizeof(Eo_Stack_Frame)) >>> + >>> +static Eina_TLS _eo_call_stack_key = 0; >>> + >>> +#define MEM_PAGE_SIZE 4096 >>> + >>> +static void * >>> +_eo_call_stack_mem_alloc(size_t size) >>> +{ >>> +#ifdef HAVE_MMAP >>> + // allocate eo call stack via mmped anon segment if on linux - more >>> + // secure and safe. also gives page aligned memory allowing madvise >>> + void *ptr; >>> + size_t newsize; >>> + newsize = MEM_PAGE_SIZE * ((size + MEM_PAGE_SIZE - 1) / >>> + MEM_PAGE_SIZE); >>> + ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE, >>> + MAP_PRIVATE | MAP_ANON, -1, 0); >>> + if (ptr == MAP_FAILED) >>> + { >>> + ERR("eo call stack mmap failed."); >>> + return NULL; >>> + } >>> + return ptr; >>> +#else >>> + //in regular cases just use malloc >>> + return calloc(1, size); >>> +#endif >>> +} >>> + >>> +static void >>> +_eo_call_stack_mem_free(void *ptr, size_t size) >>> +{ >>> +#ifdef HAVE_MMAP >>> + munmap(ptr, size); >>> +#else >>> + (void) size; >>> + free(ptr); >>> +#endif >>> +} >>> + >>> +static Eo_Call_Stack * >>> +_eo_call_stack_create() >>> +{ >>> + Eo_Call_Stack *stack; >>> + >>> + stack = calloc(1, sizeof(Eo_Call_Stack)); >>> + if (!stack) >>> + return NULL; >>> + >>> + stack->frames = _eo_call_stack_mem_alloc(EO_CALL_STACK_SIZE); >>> + if (!stack->frames) >>> + { >>> + free(stack); >>> + return NULL; >>> + } >>> + >>> + // first frame is never used >>> + stack->frame_ptr = stack->frames; >>> + >>> + return stack; >>> +} >>> + >>> +static void >>> +_eo_call_stack_free(void *ptr) >>> +{ >>> + Eo_Call_Stack *stack = (Eo_Call_Stack *) ptr; >>> + >>> + if (!stack) return; >>> + >>> + if (stack->frames) >>> + _eo_call_stack_mem_free(stack->frames, EO_CALL_STACK_SIZE); >>> + >>> + free(stack); >>> +} >>> + >>> +static Eo_Call_Stack *main_loop_stack = NULL; >>> + >>> +#define _EO_CALL_STACK_GET() ((EINA_LIKELY(eina_main_loop_is())) ? >> main_loop_stack : _eo_call_stack_get_thread()) >>> + >>> +static inline Eo_Call_Stack * >>> +_eo_call_stack_get_thread(void) >>> +{ >>> + Eo_Call_Stack *stack = eina_tls_get(_eo_call_stack_key); >>> + >>> + if (stack) return stack; >>> + >>> + stack = _eo_call_stack_create(); >>> + eina_tls_set(_eo_call_stack_key, stack); >>> + >>> + return stack; >>> +} >>> + >>> +EAPI Eo * >>> +_eo_self_get(void) >>> +{ >>> + return _EO_CALL_STACK_GET()->frame_ptr->obj; >>> +} >>> + >>> +Eo_Stack_Frame * >>> +_eo_add_fallback_stack_push(Eo *obj) >>> +{ >>> + Eo_Call_Stack *stack = _EO_CALL_STACK_GET(); >>> + if (stack->frame_ptr == (stack->frames + EO_CALL_STACK_DEPTH_MIN)) >>> + { >>> + CRI("eo_add fallback stack overflow."); >>> + } >>> + >>> + stack->frame_ptr++; >>> + stack->frame_ptr->obj = obj; >>> + >>> + return stack->frame_ptr; >>> +} >>> + >>> +Eo_Stack_Frame * >>> +_eo_add_fallback_stack_pop(void) >>> +{ >>> + Eo_Call_Stack *stack = _EO_CALL_STACK_GET(); >>> + if (stack->frame_ptr == stack->frames) >>> + { >>> + CRI("eo_add fallback stack underflow."); >>> + } >>> + >>> + stack->frame_ptr--; >>> + >>> + return stack->frame_ptr; >>> +} >>> + >>> +Eina_Bool >>> +_eo_add_fallback_init(void) >>> +{ >>> + if (_eo_call_stack_key != 0) >>> + WRN("_eo_call_stack_key already set, this should not happen."); >>> + else >>> + { >>> + if (!eina_tls_cb_new(&_eo_call_stack_key, _eo_call_stack_free)) >>> + { >>> + EINA_LOG_ERR("Could not create TLS key for call stack."); >>> + return EINA_FALSE; >>> + >>> + } >>> + } >>> + >>> + main_loop_stack = _eo_call_stack_create(); >>> + if (!main_loop_stack) >>> + { >>> + EINA_LOG_ERR("Could not alloc eo call stack."); >>> + return EINA_FALSE; >>> + } >>> + >>> + return EINA_TRUE; >>> +} >>> + >>> +Eina_Bool >>> +_eo_add_fallback_shutdown(void) >>> +{ >>> + if (_eo_call_stack_key != 0) >>> + { >>> + eina_tls_free(_eo_call_stack_key); >>> + _eo_call_stack_key = 0; >>> + } >>> + >>> + return EINA_TRUE; >>> +} >>> diff --git a/src/lib/eo/eo_add_fallback.h b/src/lib/eo/eo_add_fallback.h >>> new file mode 100644 >>> index 0000000..4b5e4a5 >>> --- /dev/null >>> +++ b/src/lib/eo/eo_add_fallback.h >>> @@ -0,0 +1,18 @@ >>> +#ifndef _EO_ADD_FALLBACK_H >>> +#define _EO_ADD_FALLBACK_H >>> + >>> +#include <Eina.h> >>> +#include <Eo.h> >>> + >>> +typedef struct _Eo_Stack_Frame >>> +{ >>> + Eo *obj; >>> +} Eo_Stack_Frame; >>> + >>> +Eina_Bool _eo_add_fallback_init(void); >>> +Eina_Bool _eo_add_fallback_shutdown(void); >>> + >>> +Eo_Stack_Frame *_eo_add_fallback_stack_push(Eo *obj); >>> +Eo_Stack_Frame *_eo_add_fallback_stack_pop(void); >>> + >>> +#endif >>> >> >> >> >> ------------------------------------------------------------------------------ >> Transform Data into Opportunity. >> Accelerate data analysis in your applications with >> Intel Data Analytics Acceleration Library. >> Click to learn more. >> http://pubads.g.doubleclick.net/gampad/clk?id=278785471&iu=/4140 >> _______________________________________________ >> enlightenment-devel mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel >> > ------------------------------------------------------------------------------ > Transform Data into Opportunity. > Accelerate data analysis in your applications with > Intel Data Analytics Acceleration Library. > Click to learn more. > http://pubads.g.doubleclick.net/gampad/clk?id=278785471&iu=/4140 > _______________________________________________ > enlightenment-devel mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > ------------------------------------------------------------------------------ _______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
