summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2014-01-22 11:18:31 +0100
committerJérémy Zurcher <jeremy@asynk.ch>2014-01-22 11:18:31 +0100
commit237a12da9cc11f7e6027657cc6ed9f7445039b9c (patch)
treed0c2bc7f2fb8c54d124cac3c6b148e07c7b3d24e
parentd07fa27ff8c7309d09f60874c88473321b90784a (diff)
eo2: call stack is now thread safedevs/jeyzu/eo2
create/destroy tls key (_eo2_call_stack_key) at eo_init()/eo_shutdown(). use _eo2_call_stack_get() to allocate the stack when required. register _eo2_call_stack_free() as eina_tls_cb_new() delete callback.
-rw-r--r--src/lib/eo/eo.c130
1 files changed, 89 insertions, 41 deletions
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index df1f8c7152..6b7d7f3a5d 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -323,61 +323,98 @@ typedef struct _Eo2_Stack_Frame
323 void *obj_data; 323 void *obj_data;
324} Eo2_Stack_Frame; 324} Eo2_Stack_Frame;
325 325
326static Eina_TLS _eo2_call_stack_key = 0;
327
326typedef struct _Eo2_Call_Stack { 328typedef struct _Eo2_Call_Stack {
327 Eo2_Stack_Frame *stack; 329 Eo2_Stack_Frame *frames;
328 Eo2_Stack_Frame *frame_ptr; 330 Eo2_Stack_Frame *frame_ptr;
329 Eo2_Stack_Frame *last_frame; 331 Eo2_Stack_Frame *last_frame;
330 Eo2_Stack_Frame *shrink_frame; 332 Eo2_Stack_Frame *shrink_frame;
331} Eo2_Call_Stack; 333} Eo2_Call_Stack;
332 334
333static Eo2_Call_Stack eo2_call_stack = { NULL, NULL, NULL, NULL }; 335static Eo2_Call_Stack *
334 336_eo2_call_stack_create()
335static Eina_Bool
336_eo2_call_stack_init()
337{ 337{
338 eo2_call_stack.stack = calloc(EO2_CALL_STACK_DEPTH, sizeof(Eo2_Stack_Frame)); 338 Eo2_Call_Stack *stack;
339 if (!eo2_call_stack.stack) 339
340 return EINA_FALSE; 340 stack = calloc(1, sizeof(Eo2_Call_Stack));
341 if (!stack)
342 return NULL;
343
344 stack->frames = calloc(EO2_CALL_STACK_DEPTH, sizeof(Eo2_Stack_Frame));
345 if (!stack->frames)
346 {
347 free(stack);
348 return NULL;
349 }
341 350
342 // first frame is never used 351 // first frame is never used
343 eo2_call_stack.frame_ptr = eo2_call_stack.stack; 352 stack->frame_ptr = stack->frames;
344 eo2_call_stack.last_frame = &eo2_call_stack.stack[EO2_CALL_STACK_DEPTH - 1]; 353 stack->last_frame = &stack->frames[EO2_CALL_STACK_DEPTH - 1];
345 eo2_call_stack.shrink_frame = eo2_call_stack.stack; 354 stack->shrink_frame = stack->frames;
346 355
347 return EINA_TRUE; 356 return stack;
348} 357}
349 358
350static void 359static void
351_eo2_call_stack_free() 360_eo2_call_stack_free(void *ptr)
352{ 361{
353 if (eo2_call_stack.stack) 362 Eo2_Call_Stack *stack = (Eo2_Call_Stack *) ptr;
354 free(eo2_call_stack.stack); 363
364 if (!stack) return;
365
366 if (stack->frames)
367 free(stack->frames);
368 free(stack);
355} 369}
356 370
371static inline Eo2_Call_Stack *
372_eo2_call_stack_get()
373{
374 Eo2_Call_Stack *stack = eina_tls_get(_eo2_call_stack_key);
375
376 if (stack) return stack;
377
378 stack = _eo2_call_stack_create();
379 if (!stack)
380 {
381 EINA_LOG_ERR("Could not alloc eo2 call stack.");
382 return NULL;
383 }
384
385 if (!eina_tls_set(_eo2_call_stack_key, stack))
386 {
387 EINA_LOG_ERR("Could not set eo2 call stack in TLS key.");
388 _eo2_call_stack_free(stack);
389 return NULL;
390 }
391
392 return stack;
393}
357 394
358static inline void 395static inline void
359_eo2_call_stack_resize(Eina_Bool grow) 396_eo2_call_stack_resize(Eo2_Call_Stack *stack, Eina_Bool grow)
360{ 397{
361 size_t sz, next_sz; 398 size_t sz, next_sz;
362 int frame_offset; 399 int frame_offset;
363 400
364 frame_offset = eo2_call_stack.frame_ptr - eo2_call_stack.stack; 401 frame_offset = stack->frame_ptr - stack->frames;
365 sz = eo2_call_stack.last_frame - eo2_call_stack.stack + 1; 402 sz = stack->last_frame - stack->frames + 1;
366 if (grow) 403 if (grow)
367 next_sz = sz << 1; 404 next_sz = sz << 1;
368 else 405 else
369 next_sz = sz >> 1; 406 next_sz = sz >> 1;
370 407
371 DBG("resize from %lu to %lu", sz, next_sz); 408 DBG("resize from %lu to %lu", sz, next_sz);
372 eo2_call_stack.stack = realloc(eo2_call_stack.stack, next_sz * sizeof(Eo2_Stack_Frame)); 409 stack->frames = realloc(stack->frames, next_sz * sizeof(Eo2_Stack_Frame));
373 if(!eo2_call_stack.stack) 410 if(!stack->frames)
374 { 411 {
375 CRI("unable to resize call stack, abort."); 412 CRI("unable to resize call stack, abort.");
376 abort(); 413 abort();
377 } 414 }
378 415
379 eo2_call_stack.frame_ptr = &eo2_call_stack.stack[frame_offset]; 416 stack->frame_ptr = &stack->frames[frame_offset];
380 eo2_call_stack.last_frame = &eo2_call_stack.stack[next_sz - 1]; 417 stack->last_frame = &stack->frames[next_sz - 1];
381 418
382 if (grow) 419 if (grow)
383 frame_offset = (sz >> 1); 420 frame_offset = (sz >> 1);
@@ -385,7 +422,7 @@ _eo2_call_stack_resize(Eina_Bool grow)
385 frame_offset = 0; 422 frame_offset = 0;
386 else 423 else
387 frame_offset = (next_sz >> 1); 424 frame_offset = (next_sz >> 1);
388 eo2_call_stack.shrink_frame = &eo2_call_stack.stack[frame_offset]; 425 stack->shrink_frame = &stack->frames[frame_offset];
389} 426}
390 427
391static inline Eina_Bool 428static inline Eina_Bool
@@ -437,11 +474,12 @@ EAPI Eina_Bool
437_eo2_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) 474_eo2_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)
438{ 475{
439 Eo2_Stack_Frame *fptr, *pfptr; 476 Eo2_Stack_Frame *fptr, *pfptr;
477 Eo2_Call_Stack *stack = _eo2_call_stack_get();
440 478
441 if (eo2_call_stack.frame_ptr == eo2_call_stack.last_frame) 479 if (stack->frame_ptr == stack->last_frame)
442 _eo2_call_stack_resize(EINA_TRUE); 480 _eo2_call_stack_resize(stack, EINA_TRUE);
443 481
444 fptr = eo2_call_stack.frame_ptr; 482 fptr = stack->frame_ptr;
445 483
446 pfptr = ((eo_id) && (fptr->eo_id == eo_id) ? fptr : NULL); 484 pfptr = ((eo_id) && (fptr->eo_id == eo_id) ? fptr : NULL);
447 fptr++; 485 fptr++;
@@ -449,7 +487,7 @@ _eo2_do_start(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool is_super,
449 if (!_eo2_do_internal(eo_id, cur_klass_id, is_super, fptr, pfptr)) 487 if (!_eo2_do_internal(eo_id, cur_klass_id, is_super, fptr, pfptr))
450 return EINA_FALSE; 488 return EINA_FALSE;
451 489
452 eo2_call_stack.frame_ptr++; 490 stack->frame_ptr++;
453 491
454 return EINA_TRUE; 492 return EINA_TRUE;
455} 493}
@@ -458,24 +496,25 @@ EAPI void
458_eo2_do_end(const Eo **eo_id EINA_UNUSED) 496_eo2_do_end(const Eo **eo_id EINA_UNUSED)
459{ 497{
460 Eo2_Stack_Frame *fptr; 498 Eo2_Stack_Frame *fptr;
499 Eo2_Call_Stack *stack = _eo2_call_stack_get();
461 500
462 fptr = eo2_call_stack.frame_ptr; 501 fptr = stack->frame_ptr;
463 502
464 if (!_eo_is_a_class(fptr->eo_id) && fptr->o.obj) 503 if (!_eo_is_a_class(fptr->eo_id) && fptr->o.obj)
465 _eo_unref(fptr->o.obj); 504 _eo_unref(fptr->o.obj);
466 505
467 fptr->obj_data = EO2_INVALID_DATA; 506 fptr->obj_data = EO2_INVALID_DATA;
468 507
469 if (fptr == eo2_call_stack.stack) 508 if (fptr == stack->frames)
470 { 509 {
471 CRI("call stack underflow, abort."); 510 CRI("call stack underflow, abort.");
472 abort(); 511 abort();
473 } 512 }
474 513
475 eo2_call_stack.frame_ptr--; 514 stack->frame_ptr--;
476 515
477 if (fptr == eo2_call_stack.shrink_frame) 516 if (fptr == stack->shrink_frame)
478 _eo2_call_stack_resize(EINA_FALSE); 517 _eo2_call_stack_resize(stack, EINA_FALSE);
479} 518}
480 519
481EAPI Eina_Bool 520EAPI Eina_Bool
@@ -488,7 +527,7 @@ _eo2_call_resolve(const char *func_name, const Eo_Op op, Eo2_Op_Call_Data *call,
488 527
489 if (op == EO_NOOP) return EINA_FALSE; 528 if (op == EO_NOOP) return EINA_FALSE;
490 529
491 fptr = eo2_call_stack.frame_ptr; 530 fptr = _eo2_call_stack_get()->frame_ptr;
492 is_obj = !_eo_is_a_class(fptr->eo_id); 531 is_obj = !_eo_is_a_class(fptr->eo_id);
493 532
494 klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls; 533 klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls;
@@ -652,13 +691,14 @@ _eo2_api_op_id_get(const void *api_func, const char *file, int line)
652{ 691{
653 const Eo2_Op_Description *desc; 692 const Eo2_Op_Description *desc;
654 const _Eo_Class *klass; 693 const _Eo_Class *klass;
694 Eo2_Call_Stack *stack = _eo2_call_stack_get();
655 695
656 Eina_Bool class_ref = _eo_is_a_class(eo2_call_stack.frame_ptr->eo_id); 696 Eina_Bool class_ref = _eo_is_a_class(stack->frame_ptr->eo_id);
657 697
658 if (class_ref) 698 if (class_ref)
659 klass = eo2_call_stack.frame_ptr->o.kls; 699 klass = stack->frame_ptr->o.kls;
660 else 700 else
661 klass = eo2_call_stack.frame_ptr->o.obj->klass; 701 klass = stack->frame_ptr->o.obj->klass;
662 702
663 desc = _eo2_api_desc_get(api_func, klass, klass->extensions); 703 desc = _eo2_api_desc_get(api_func, klass, klass->extensions);
664 704
@@ -801,8 +841,9 @@ EAPI Eo *
801_eo2_add_internal_end(const char *file, int line, const Eo *eo_id) 841_eo2_add_internal_end(const char *file, int line, const Eo *eo_id)
802{ 842{
803 Eo2_Stack_Frame *fptr; 843 Eo2_Stack_Frame *fptr;
844 Eo2_Call_Stack *stack = _eo2_call_stack_get();
804 845
805 fptr = eo2_call_stack.frame_ptr; 846 fptr = stack->frame_ptr;
806 847
807 if ((fptr == NULL) || (fptr->eo_id != eo_id)) 848 if ((fptr == NULL) || (fptr->eo_id != eo_id))
808 { 849 {
@@ -2047,10 +2088,16 @@ eo_init(void)
2047 /* bootstrap EO_CLASS_CLASS */ 2088 /* bootstrap EO_CLASS_CLASS */
2048 (void) eo_class_class_get(); 2089 (void) eo_class_class_get();
2049 2090
2050 if (!_eo2_call_stack_init()) 2091 if (_eo2_call_stack_key != 0)
2092 WRN("_eo2_call_stack_key already set, this should not happen.");
2093 else
2051 { 2094 {
2052 EINA_LOG_ERR("Could not init eo2 call stack."); 2095 if (!eina_tls_cb_new(&_eo2_call_stack_key, _eo2_call_stack_free))
2053 return EINA_FALSE; 2096 {
2097 EINA_LOG_ERR("Could not create TLS key for call stack.");
2098 return EINA_FALSE;
2099
2100 }
2054 } 2101 }
2055 2102
2056 return EINA_TRUE; 2103 return EINA_TRUE;
@@ -2080,7 +2127,8 @@ eo_shutdown(void)
2080 2127
2081 eina_spinlock_free(&_eo_class_creation_lock); 2128 eina_spinlock_free(&_eo_class_creation_lock);
2082 2129
2083 _eo2_call_stack_free(); 2130 if (_eo2_call_stack_key != 0)
2131 eina_tls_free(_eo2_call_stack_key);
2084 2132
2085 _eo_free_ids_tables(); 2133 _eo_free_ids_tables();
2086 2134