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.

Reply via email to