eo - move eoid lookup to ptr indir file and clean up some code

this improves the readability of some of the new domain related and
ptr indir code..
This commit is contained in:
Carsten Haitzler 2016-09-09 18:44:21 +09:00
parent fe81fff89b
commit 8b159aab68
3 changed files with 118 additions and 115 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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));