10
#if defined HAVE_DLADDR && ! defined _WIN32
16
#include "eo_ptr_indirection.h"
17
#include "eo_private.h"
19
#include "eo_add_fallback.h"
23
#define EFL_OBJECT_CALL_STACK_DEPTH_MIN 1024
25
typedef struct _Efl_Object_Call_Stack {
26
Eo_Stack_Frame *frames;
27
Eo_Stack_Frame *frame_ptr;
28
} Efl_Object_Call_Stack;
30
#define EFL_OBJECT_CALL_STACK_SIZE (EFL_OBJECT_CALL_STACK_DEPTH_MIN * sizeof(Eo_Stack_Frame))
32
static Eina_TLS _eo_call_stack_key = 0;
34
#define MEM_PAGE_SIZE 4096
37
_eo_call_stack_mem_alloc(size_t size)
41
if (RUNNING_ON_VALGRIND) return calloc(1, size);
45
if (_eo_no_anon == -1)
47
if (getenv("EFL_NO_MMAP_ANON")) _eo_no_anon = 1;
50
if (_eo_no_anon == 1) return calloc(1, size);
57
newsize = MEM_PAGE_SIZE * ((size + MEM_PAGE_SIZE - 1) /
59
ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE,
60
MAP_PRIVATE | MAP_ANON, -1, 0);
61
if (ptr == MAP_FAILED)
63
ERR("eo call stack mmap failed.");
71
return calloc(1, size);
76
_eo_call_stack_mem_free(void *ptr, size_t size)
80
if (RUNNING_ON_VALGRIND) free(ptr);
84
if (_eo_no_anon == 1) free(ptr);
85
else munmap(ptr, size);
93
static Efl_Object_Call_Stack *
94
_eo_call_stack_create(void)
96
Efl_Object_Call_Stack *stack;
98
stack = calloc(1, sizeof(Efl_Object_Call_Stack));
102
stack->frames = _eo_call_stack_mem_alloc(EFL_OBJECT_CALL_STACK_SIZE);
110
stack->frame_ptr = stack->frames;
116
_eo_call_stack_free(void *ptr)
118
Efl_Object_Call_Stack *stack = (Efl_Object_Call_Stack *) ptr;
123
_eo_call_stack_mem_free(stack->frames, EFL_OBJECT_CALL_STACK_SIZE);
128
static Efl_Object_Call_Stack *main_loop_stack = NULL;
130
#define _EFL_OBJECT_CALL_STACK_GET() ((EINA_LIKELY(eina_main_loop_is())) ? main_loop_stack : _eo_call_stack_get_thread())
132
static inline Efl_Object_Call_Stack *
133
_eo_call_stack_get_thread(void)
135
Efl_Object_Call_Stack *stack = eina_tls_get(_eo_call_stack_key);
137
if (stack) return stack;
139
stack = _eo_call_stack_create();
140
eina_tls_set(_eo_call_stack_key, stack);
148
return _EFL_OBJECT_CALL_STACK_GET()->frame_ptr->obj;
152
_efl_add_fallback_stack_push(Eo *obj)
154
Efl_Object_Call_Stack *stack = _EFL_OBJECT_CALL_STACK_GET();
155
if (stack->frame_ptr == (stack->frames + EFL_OBJECT_CALL_STACK_DEPTH_MIN))
157
CRI("efl_add fallback stack overflow.");
161
stack->frame_ptr->obj = obj;
163
return stack->frame_ptr;
167
_efl_add_fallback_stack_pop(void)
169
Efl_Object_Call_Stack *stack = _EFL_OBJECT_CALL_STACK_GET();
170
if (stack->frame_ptr == stack->frames)
172
CRI("efl_add fallback stack underflow.");
177
return stack->frame_ptr;
181
_efl_add_fallback_init(void)
183
if (_eo_call_stack_key != 0)
184
WRN("_eo_call_stack_key already set, this should not happen.");
187
if (!eina_tls_cb_new(&_eo_call_stack_key, _eo_call_stack_free))
189
EINA_LOG_ERR("Could not create TLS key for call stack.");
195
main_loop_stack = _eo_call_stack_create();
196
if (!main_loop_stack)
198
EINA_LOG_ERR("Could not alloc eo call stack.");
206
_efl_add_fallback_shutdown(void)
208
if (_eo_call_stack_key != 0)
210
eina_tls_free(_eo_call_stack_key);
211
_eo_call_stack_key = 0;
214
_eo_call_stack_free(main_loop_stack);
215
main_loop_stack = NULL;