This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository efl.
View the commit online.
commit cdd3c35bb30ffbeb7fb6543ad6e7b45d6a5cccd5
Author: Carsten Haitzler <ras...@rasterman.com>
AuthorDate: Tue Apr 9 10:30:47 2024 +0100
eo: make eo ptr indirection caches flexible
---
src/lib/eo/eo_ptr_indirection.c | 29 +++++-----
src/lib/eo/eo_ptr_indirection.x | 116 +++++++++++++++++++++++++++++++++++-----
2 files changed, 119 insertions(+), 26 deletions(-)
diff --git a/src/lib/eo/eo_ptr_indirection.c b/src/lib/eo/eo_ptr_indirection.c
index cd578a5a2a..e3d6f62b6f 100644
--- a/src/lib/eo/eo_ptr_indirection.c
+++ b/src/lib/eo/eo_ptr_indirection.c
@@ -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
diff --git a/src/lib/eo/eo_ptr_indirection.x b/src/lib/eo/eo_ptr_indirection.x
index 64bad07a06..33043b36e6 100644
--- a/src/lib/eo/eo_ptr_indirection.x
+++ b/src/lib/eo/eo_ptr_indirection.x
@@ -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;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.