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]));
|
||||
domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN;
|
||||
tdata = _eo_table_data_table_get(data, domain);
|
||||
EINA_PREFETCH(&(tdata->cache.id));
|
||||
if (EINA_UNLIKELY(!tdata)) goto err;
|
||||
|
||||
_eo_cache_prefetch(tdata);
|
||||
|
||||
if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED))
|
||||
{
|
||||
if (obj_id == tdata->cache.id)
|
||||
return tdata->cache.object;
|
||||
_Eo_Object *obj;
|
||||
|
||||
obj = _eo_cache_find(tdata, obj_id);
|
||||
if (obj) return obj;
|
||||
|
||||
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;
|
||||
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;
|
||||
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))
|
||||
{
|
||||
// Cache the result of that lookup
|
||||
tdata->cache.object = entry->ptr;
|
||||
tdata->cache.id = obj_id;
|
||||
_eo_cache_store(tdata, obj_id, 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
|
||||
{
|
||||
_Eo_Object *obj;
|
||||
|
||||
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
|
||||
// you must call _eo_obj_pointer_done() wrapped
|
||||
// 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;
|
||||
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;
|
||||
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;
|
||||
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))
|
||||
{
|
||||
// Cache the result of that lookup
|
||||
tdata->cache.object = entry->ptr;
|
||||
tdata->cache.id = obj_id;
|
||||
_eo_cache_store(tdata, obj_id, entry->ptr);
|
||||
// yes we return keeping the lock locked. that's why
|
||||
// you must call _eo_obj_pointer_done() wrapped
|
||||
// by EO_OBJ_DONE() to release
|
||||
|
|
|
@ -305,13 +305,19 @@ typedef struct
|
|||
typedef struct _Eo_Id_Data Eo_Id_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
|
||||
{
|
||||
/* Cached eoid lookups */
|
||||
#if CACHENUM > 0
|
||||
Eo_Id cache_id[CACHENUM];
|
||||
_Eo_Object *cache_object[CACHENUM];
|
||||
#endif
|
||||
struct
|
||||
{
|
||||
Eo_Id id;
|
||||
_Eo_Object *object;
|
||||
const Eo *isa_id;
|
||||
const Efl_Class *klass;
|
||||
Eina_Bool isa;
|
||||
|
@ -343,6 +349,100 @@ extern Eina_TLS _eo_table_data;
|
|||
extern Eo_Id_Data *_eo_table_data_shared;
|
||||
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 *
|
||||
_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;
|
||||
}
|
||||
// In case an object is destroyed, wipe out the cache
|
||||
if (tdata->cache.id == obj_id)
|
||||
{
|
||||
tdata->cache.id = 0;
|
||||
tdata->cache.object = NULL;
|
||||
}
|
||||
_eo_cache_invalidate(tdata, obj_id);
|
||||
if ((Eo_Id)tdata->cache.isa_id == obj_id)
|
||||
{
|
||||
tdata->cache.isa_id = NULL;
|
||||
|
@ -722,11 +818,7 @@ _eo_id_release(const Eo_Id obj_id)
|
|||
tdata->current_table = NULL;
|
||||
}
|
||||
// In case an object is destroyed, wipe out the cache
|
||||
if (tdata->cache.id == obj_id)
|
||||
{
|
||||
tdata->cache.id = 0;
|
||||
tdata->cache.object = NULL;
|
||||
}
|
||||
_eo_cache_invalidate(tdata, obj_id);
|
||||
if ((Eo_Id)tdata->cache.isa_id == obj_id)
|
||||
{
|
||||
tdata->cache.isa_id = NULL;
|
||||
|
|
Loading…
Reference in New Issue