forked from enlightenment/efl
eo: make eo ptr indirection caches flexible
This commit is contained in:
parent
49976ca388
commit
cdd3c35bb3
|
@ -94,19 +94,20 @@ _eo_obj_pointer_get(const Eo_Id obj_id, const char *func_name, const char *file,
|
||||||
EINA_PREFETCH(&(data->tables[0]));
|
EINA_PREFETCH(&(data->tables[0]));
|
||||||
domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN;
|
domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN;
|
||||||
tdata = _eo_table_data_table_get(data, domain);
|
tdata = _eo_table_data_table_get(data, domain);
|
||||||
EINA_PREFETCH(&(tdata->cache.id));
|
|
||||||
if (EINA_UNLIKELY(!tdata)) goto err;
|
if (EINA_UNLIKELY(!tdata)) goto err;
|
||||||
|
_eo_cache_prefetch(tdata);
|
||||||
|
|
||||||
if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED))
|
if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED))
|
||||||
{
|
{
|
||||||
if (obj_id == tdata->cache.id)
|
_Eo_Object *obj;
|
||||||
return tdata->cache.object;
|
|
||||||
|
obj = _eo_cache_find(tdata, obj_id);
|
||||||
|
if (obj) return obj;
|
||||||
|
|
||||||
mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID;
|
mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID;
|
||||||
EINA_PREFETCH_NOCACHE(&(tdata->eo_ids_tables[mid_table_id])); //prefetch for line 119
|
EINA_PREFETCH(&(tdata->eo_ids_tables[mid_table_id])); //prefetch for line 119
|
||||||
table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID;
|
table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID;
|
||||||
EINA_PREFETCH_NOCACHE((tdata->eo_ids_tables[mid_table_id] + table_id)); //prefetch for line 121
|
EINA_PREFETCH((tdata->eo_ids_tables[mid_table_id] + table_id)); //prefetch for line 121
|
||||||
entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID;
|
entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID;
|
||||||
generation = obj_id & MASK_GENERATIONS;
|
generation = obj_id & MASK_GENERATIONS;
|
||||||
|
|
||||||
|
@ -126,8 +127,7 @@ _eo_obj_pointer_get(const Eo_Id obj_id, const char *func_name, const char *file,
|
||||||
if (entry->active && (entry->generation == generation))
|
if (entry->active && (entry->generation == generation))
|
||||||
{
|
{
|
||||||
// Cache the result of that lookup
|
// Cache the result of that lookup
|
||||||
tdata->cache.object = entry->ptr;
|
_eo_cache_store(tdata, obj_id, entry->ptr);
|
||||||
tdata->cache.id = obj_id;
|
|
||||||
return entry->ptr;
|
return entry->ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,17 +136,19 @@ _eo_obj_pointer_get(const Eo_Id obj_id, const char *func_name, const char *file,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_Eo_Object *obj;
|
||||||
|
|
||||||
eina_lock_take(&(_eo_table_data_shared_data->obj_lock));
|
eina_lock_take(&(_eo_table_data_shared_data->obj_lock));
|
||||||
if (obj_id == tdata->cache.id)
|
|
||||||
// yes we return keeping the lock locked. that's why
|
// yes we return keeping the lock locked. that's why
|
||||||
// you must call _eo_obj_pointer_done() wrapped
|
// you must call _eo_obj_pointer_done() wrapped
|
||||||
// by EO_OBJ_DONE() to release
|
// by EO_OBJ_DONE() to release
|
||||||
return tdata->cache.object;
|
obj = _eo_cache_find(tdata, obj_id);
|
||||||
|
if (obj) return obj;
|
||||||
|
|
||||||
mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID;
|
mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID;
|
||||||
EINA_PREFETCH_NOCACHE(&(tdata->eo_ids_tables[mid_table_id]));
|
EINA_PREFETCH(&(tdata->eo_ids_tables[mid_table_id]));
|
||||||
table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID;
|
table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID;
|
||||||
EINA_PREFETCH_NOCACHE((tdata->eo_ids_tables[mid_table_id] + table_id));
|
EINA_PREFETCH((tdata->eo_ids_tables[mid_table_id] + table_id));
|
||||||
entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID;
|
entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID;
|
||||||
generation = obj_id & MASK_GENERATIONS;
|
generation = obj_id & MASK_GENERATIONS;
|
||||||
|
|
||||||
|
@ -167,8 +169,7 @@ _eo_obj_pointer_get(const Eo_Id obj_id, const char *func_name, const char *file,
|
||||||
if (entry->active && (entry->generation == generation))
|
if (entry->active && (entry->generation == generation))
|
||||||
{
|
{
|
||||||
// Cache the result of that lookup
|
// Cache the result of that lookup
|
||||||
tdata->cache.object = entry->ptr;
|
_eo_cache_store(tdata, obj_id, entry->ptr);
|
||||||
tdata->cache.id = obj_id;
|
|
||||||
// yes we return keeping the lock locked. that's why
|
// yes we return keeping the lock locked. that's why
|
||||||
// you must call _eo_obj_pointer_done() wrapped
|
// you must call _eo_obj_pointer_done() wrapped
|
||||||
// by EO_OBJ_DONE() to release
|
// by EO_OBJ_DONE() to release
|
||||||
|
|
|
@ -305,13 +305,19 @@ typedef struct
|
||||||
typedef struct _Eo_Id_Data Eo_Id_Data;
|
typedef struct _Eo_Id_Data Eo_Id_Data;
|
||||||
typedef struct _Eo_Id_Table_Data Eo_Id_Table_Data;
|
typedef struct _Eo_Id_Table_Data Eo_Id_Table_Data;
|
||||||
|
|
||||||
|
#define CACHENUM 2
|
||||||
|
#define CACHELINE 64
|
||||||
|
#define CACHELRU 1
|
||||||
|
|
||||||
struct _Eo_Id_Table_Data
|
struct _Eo_Id_Table_Data
|
||||||
{
|
{
|
||||||
/* Cached eoid lookups */
|
/* Cached eoid lookups */
|
||||||
|
#if CACHENUM > 0
|
||||||
|
Eo_Id cache_id[CACHENUM];
|
||||||
|
_Eo_Object *cache_object[CACHENUM];
|
||||||
|
#endif
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
Eo_Id id;
|
|
||||||
_Eo_Object *object;
|
|
||||||
const Eo *isa_id;
|
const Eo *isa_id;
|
||||||
const Efl_Class *klass;
|
const Efl_Class *klass;
|
||||||
Eina_Bool isa;
|
Eina_Bool isa;
|
||||||
|
@ -343,6 +349,100 @@ extern Eina_TLS _eo_table_data;
|
||||||
extern Eo_Id_Data *_eo_table_data_shared;
|
extern Eo_Id_Data *_eo_table_data_shared;
|
||||||
extern Eo_Id_Table_Data *_eo_table_data_shared_data;
|
extern Eo_Id_Table_Data *_eo_table_data_shared_data;
|
||||||
|
|
||||||
|
#ifndef CACHELRU
|
||||||
|
static inline unsigned int
|
||||||
|
_eo_cache_slot_get(void)
|
||||||
|
{
|
||||||
|
# if CACHENUM > 0
|
||||||
|
static unsigned int num = 0;
|
||||||
|
|
||||||
|
return (++num) % CACHENUM;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_eo_cache_prefetch(Eo_Id_Table_Data *tdata EINA_UNUSED)
|
||||||
|
{
|
||||||
|
#if CACHENUM > 0
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < CACHENUM; i += (CACHELINE / sizeof(void *)))
|
||||||
|
{
|
||||||
|
EINA_PREFETCH(&(tdata->cache_id[i]));
|
||||||
|
if ((sizeof(void *) * CACHENUM) >= CACHELINE)
|
||||||
|
{
|
||||||
|
EINA_PREFETCH(&(tdata->cache_object[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline _Eo_Object *
|
||||||
|
_eo_cache_find(Eo_Id_Table_Data *tdata EINA_UNUSED, Eo_Id obj_id EINA_UNUSED)
|
||||||
|
{
|
||||||
|
#if CACHENUM > 0
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < CACHENUM; i++)
|
||||||
|
{
|
||||||
|
if (obj_id == tdata->cache_id[i]) return tdata->cache_object[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_eo_cache_store(Eo_Id_Table_Data *tdata EINA_UNUSED, Eo_Id obj_id EINA_UNUSED, _Eo_Object *obj EINA_UNUSED)
|
||||||
|
{
|
||||||
|
#if CACHENUM > 0
|
||||||
|
# ifdef CACHELRU
|
||||||
|
# if CACHENUM > 1
|
||||||
|
memmove(&tdata->cache_id[1], &tdata->cache_id[0],
|
||||||
|
(CACHENUM - 1) * sizeof(tdata->cache_id[0]));
|
||||||
|
memmove(&tdata->cache_object[1], &tdata->cache_object[0],
|
||||||
|
(CACHENUM - 1) * sizeof(tdata->cache_object[0]));
|
||||||
|
# endif
|
||||||
|
tdata->cache_id[0] = obj_id;
|
||||||
|
tdata->cache_object[0] = obj;
|
||||||
|
# else
|
||||||
|
int slot = _eo_cache_slot_get();
|
||||||
|
tdata->cache_id[slot] = obj_id;
|
||||||
|
tdata->cache_object[slot] = obj;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_eo_cache_invalidate(Eo_Id_Table_Data *tdata EINA_UNUSED, Eo_Id obj_id EINA_UNUSED)
|
||||||
|
{
|
||||||
|
#if CACHENUM > 0
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < CACHENUM; i++)
|
||||||
|
{
|
||||||
|
if (obj_id == tdata->cache_id[i])
|
||||||
|
{
|
||||||
|
# ifdef CACHELRU
|
||||||
|
if (EINA_LIKELY((CACHENUM - 1 - i) > 0))
|
||||||
|
{
|
||||||
|
memmove(&tdata->cache_id[i], &tdata->cache_id[i + 1],
|
||||||
|
(CACHENUM - 1 - i) * sizeof(tdata->cache_id[0]));
|
||||||
|
memmove(&tdata->cache_object[i], &tdata->cache_object[i + 1],
|
||||||
|
(CACHENUM - 1 - i) * sizeof(tdata->cache_object[0]));
|
||||||
|
}
|
||||||
|
tdata->cache_id[CACHENUM - 1] = 0;
|
||||||
|
tdata->cache_object[CACHENUM - 1] = NULL;
|
||||||
|
# else
|
||||||
|
tdata->cache_id[i] = 0;
|
||||||
|
tdata->cache_object[i] = NULL;
|
||||||
|
# endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline Eo_Id_Table_Data *
|
static inline Eo_Id_Table_Data *
|
||||||
_eo_table_data_table_new(Efl_Id_Domain domain)
|
_eo_table_data_table_new(Efl_Id_Domain domain)
|
||||||
{
|
{
|
||||||
|
@ -672,11 +772,7 @@ _eo_id_release(const Eo_Id obj_id)
|
||||||
tdata->current_table = NULL;
|
tdata->current_table = NULL;
|
||||||
}
|
}
|
||||||
// In case an object is destroyed, wipe out the cache
|
// In case an object is destroyed, wipe out the cache
|
||||||
if (tdata->cache.id == obj_id)
|
_eo_cache_invalidate(tdata, obj_id);
|
||||||
{
|
|
||||||
tdata->cache.id = 0;
|
|
||||||
tdata->cache.object = NULL;
|
|
||||||
}
|
|
||||||
if ((Eo_Id)tdata->cache.isa_id == obj_id)
|
if ((Eo_Id)tdata->cache.isa_id == obj_id)
|
||||||
{
|
{
|
||||||
tdata->cache.isa_id = NULL;
|
tdata->cache.isa_id = NULL;
|
||||||
|
@ -722,11 +818,7 @@ _eo_id_release(const Eo_Id obj_id)
|
||||||
tdata->current_table = NULL;
|
tdata->current_table = NULL;
|
||||||
}
|
}
|
||||||
// In case an object is destroyed, wipe out the cache
|
// In case an object is destroyed, wipe out the cache
|
||||||
if (tdata->cache.id == obj_id)
|
_eo_cache_invalidate(tdata, obj_id);
|
||||||
{
|
|
||||||
tdata->cache.id = 0;
|
|
||||||
tdata->cache.object = NULL;
|
|
||||||
}
|
|
||||||
if ((Eo_Id)tdata->cache.isa_id == obj_id)
|
if ((Eo_Id)tdata->cache.isa_id == obj_id)
|
||||||
{
|
{
|
||||||
tdata->cache.isa_id = NULL;
|
tdata->cache.isa_id = NULL;
|
||||||
|
|
Loading…
Reference in New Issue