diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index e75e36c574..12d429076a 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1997,6 +1997,8 @@ efl_domain_switch(Efl_Id_Domain domain) _eo_free_ids_tables(data); } data = _eo_table_data_new(domain); + data->local_domain = domain; + data->domain_stack[data->stack_top] = domain; eina_tls_set(_eo_table_data, data); return EINA_TRUE; } @@ -2156,114 +2158,3 @@ efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_Array_Ite { return (const unsigned char *) a->desc - (const unsigned char *) b->desc; } - -_Eo_Object * -_eo_obj_pointer_get(const Eo_Id obj_id) -{ -#ifdef HAVE_EO_ID - _Eo_Id_Entry *entry; - _Eo_Object *ptr; - Generation_Counter generation; - Table_Index mid_table_id, table_id, entry_id; - Eo_Id tag_bit; - Eo_Id_Data *data; - Eo_Id_Table_Data *tdata; - unsigned char domain; - - // NULL objects will just be sensibly ignored. not worth complaining - // every single time. - - domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN; - data = _eo_table_data_get(); - tdata = _eo_table_data_table_get(data, domain); - if (!tdata) goto err_invalid; - - if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED)) - { - if (obj_id == tdata->cache.id) - { - ptr = tdata->cache.object; - return ptr; - } - - // get tag bit to check later down below - pipelining - tag_bit = (obj_id) & MASK_OBJ_TAG; - if (!obj_id) goto err_null; - else if (!tag_bit) goto err_invalid; - - EO_DECOMPOSE_ID(obj_id, mid_table_id, table_id, entry_id, generation); - - // Check the validity of the entry - if (tdata->eo_ids_tables[mid_table_id]) - { - _Eo_Ids_Table *tab = TABLE_FROM_IDS; - - if (tab) - { - entry = &(tab->entries[entry_id]); - if (entry->active && (entry->generation == generation)) - { - // Cache the result of that lookup - tdata->cache.object = entry->ptr; - tdata->cache.id = obj_id; - ptr = entry->ptr; - return ptr; - } - } - } - goto err; - } - else - { - eina_spinlock_take(&(tdata->lock)); - if (obj_id == tdata->cache.id) - { - ptr = tdata->cache.object; - goto shared_ok; - } - - // get tag bit to check later down below - pipelining - tag_bit = (obj_id) & MASK_OBJ_TAG; - if (!obj_id) goto err_null; - else if (!tag_bit) goto err_invalid; - - EO_DECOMPOSE_ID(obj_id, mid_table_id, table_id, entry_id, generation); - - // Check the validity of the entry - if (tdata->eo_ids_tables[mid_table_id]) - { - _Eo_Ids_Table *tab = TABLE_FROM_IDS; - - if (tab) - { - entry = &(tab->entries[entry_id]); - if (entry->active && (entry->generation == generation)) - { - // Cache the result of that lookup - tdata->cache.object = entry->ptr; - tdata->cache.id = obj_id; - ptr = entry->ptr; - goto shared_ok; - } - } - } - eina_spinlock_release(&(tdata->lock)); - goto err; -shared_ok: - eina_spinlock_release(&(tdata->lock)); - return ptr; - } -err_null: - DBG("obj_id is NULL. Possibly unintended access?"); - return NULL; -err_invalid: - DBG("obj_id is not a valid object id."); - return NULL; -err: - ERR("obj_id %p is not a valid object. Maybe it has been freed or does not belong to your thread?", - (void *)obj_id); - return NULL; -#else - return (_Eo_Object *) obj_id; -#endif -} diff --git a/src/lib/eo/eo_ptr_indirection.c b/src/lib/eo/eo_ptr_indirection.c index bc85eb7fe6..96ee0de3c0 100644 --- a/src/lib/eo/eo_ptr_indirection.c +++ b/src/lib/eo/eo_ptr_indirection.c @@ -16,3 +16,113 @@ _eo_pointer_error(const char *msg) { ERR("%s", msg); } + +_Eo_Object * +_eo_obj_pointer_get(const Eo_Id obj_id) +{ +#ifdef HAVE_EO_ID + _Eo_Id_Entry *entry; + _Eo_Object *ptr; + Generation_Counter generation; + Table_Index mid_table_id, table_id, entry_id; + Eo_Id tag_bit; + Eo_Id_Data *data; + Eo_Id_Table_Data *tdata; + unsigned char domain; + + // NULL objects will just be sensibly ignored. not worth complaining + // every single time. + + domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN; + data = _eo_table_data_get(); + tdata = _eo_table_data_table_get(data, domain); + if (!tdata) goto err_invalid; + + + if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED)) + { + if (obj_id == tdata->cache.id) + { + ptr = tdata->cache.object; + return ptr; + } + + // get tag bit to check later down below - pipelining + tag_bit = (obj_id) & MASK_OBJ_TAG; + if (!obj_id) goto err_null; + else if (!tag_bit) goto err_invalid; + + EO_DECOMPOSE_ID(obj_id, mid_table_id, table_id, entry_id, generation); + + // Check the validity of the entry + if (tdata->eo_ids_tables[mid_table_id]) + { + _Eo_Ids_Table *tab = TABLE_FROM_IDS; + + if (tab) + { + entry = &(tab->entries[entry_id]); + if (entry->active && (entry->generation == generation)) + { + // Cache the result of that lookup + tdata->cache.object = entry->ptr; + tdata->cache.id = obj_id; + ptr = entry->ptr; + return ptr; + } + } + } + goto err; + } + else + { + eina_spinlock_take(&(tdata->lock)); + if (obj_id == tdata->cache.id) + { + ptr = tdata->cache.object; + goto shared_ok; + } + + // get tag bit to check later down below - pipelining + tag_bit = (obj_id) & MASK_OBJ_TAG; + if (!obj_id) goto err_null; + else if (!tag_bit) goto err_invalid; + + EO_DECOMPOSE_ID(obj_id, mid_table_id, table_id, entry_id, generation); + + // Check the validity of the entry + if (tdata->eo_ids_tables[mid_table_id]) + { + _Eo_Ids_Table *tab = TABLE_FROM_IDS; + + if (tab) + { + entry = &(tab->entries[entry_id]); + if (entry->active && (entry->generation == generation)) + { + // Cache the result of that lookup + tdata->cache.object = entry->ptr; + tdata->cache.id = obj_id; + ptr = entry->ptr; + goto shared_ok; + } + } + } + eina_spinlock_release(&(tdata->lock)); + goto err; +shared_ok: + eina_spinlock_release(&(tdata->lock)); + return ptr; + } +err_null: + DBG("obj_id is NULL. Possibly unintended access?"); + return NULL; +err_invalid: +err: + ERR("obj_id %p is not a valid object. Maybe it has been freed or does not belong to your thread?", + (void *)obj_id); + return NULL; +#else + return (_Eo_Object *) obj_id; +#endif +} diff --git a/src/lib/eo/eo_ptr_indirection.x b/src/lib/eo/eo_ptr_indirection.x index 04ddb7cd51..7529ba2926 100644 --- a/src/lib/eo/eo_ptr_indirection.x +++ b/src/lib/eo/eo_ptr_indirection.x @@ -64,6 +64,7 @@ # define BITS_ENTRY_ID 11 # define BITS_GENERATION_COUNTER 6 # define BITS_DOMAIN 2 +# define BITS_CLASS 1 # define REF_TAG_SHIFT 30 # define SUPER_TAG_SHIFT 31 # define DROPPED_TABLES 0 @@ -77,6 +78,7 @@ typedef uint16_t Generation_Counter; # define BITS_ENTRY_ID 11 # define BITS_GENERATION_COUNTER 26 # define BITS_DOMAIN 2 +# define BITS_CLASS 1 # define REF_TAG_SHIFT 62 # define SUPER_TAG_SHIFT 63 # define DROPPED_TABLES 2 @@ -308,7 +310,7 @@ _eo_table_data_table_new(Efl_Id_Domain domain) } tdata->shared = EINA_TRUE; } - // XXX: randomize generation count and allocation methods + tdata->generation = rand() % MAX_GENERATIONS; return tdata; } @@ -389,7 +391,7 @@ _eo_id_domain_compatible(const Eo *o1, const Eo *o2) (PARTIAL_ID | \ (((Eo_Id)DOMAIN & MASK_DOMAIN) << SHIFT_DOMAIN) | \ ((ENTRY & MASK_ENTRY_ID) << SHIFT_ENTRY_ID) | \ - (GENERATION & MASK_GENERATIONS )) + (GENERATION & MASK_GENERATIONS)) /* Macro to extract from an Eo id the indexes of the tables */ #define EO_DECOMPOSE_ID(ID, MID_TABLE, TABLE, ENTRY, GENERATION) \ @@ -523,7 +525,7 @@ _eo_id_allocate(const _Eo_Object *obj, const Eo *parent_id) UNPROTECT(tdata->current_table); /* [1;max-1] thus we never generate an Eo_Id equal to 0 */ tdata->generation++; - if (tdata->generation == MAX_GENERATIONS) tdata->generation = 1; + if (tdata->generation >= MAX_GENERATIONS) tdata->generation = 1; /* Fill the entry and return it's Eo Id */ entry->ptr = (_Eo_Object *)obj; entry->active = 1; @@ -559,7 +561,7 @@ _eo_id_allocate(const _Eo_Object *obj, const Eo *parent_id) PROTECT(tdata->current_table); id = EO_COMPOSE_FINAL_ID(tdata->current_table->partial_id, (entry - tdata->current_table->entries), - data->domain_stack[data->stack_top], + EFL_ID_DOMAIN_SHARED, entry->generation); shared_err: eina_spinlock_release(&(tdata->lock));