This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch reproducible-widget-previews
in repository efl.

View the commit online.

commit cc703efb0ac6824acc499d0a18707e28c454c135
Author: Carsten Haitzler <[email protected]>
AuthorDate: Sun Apr 19 11:12:18 2026 +0100

    eina file - minimize lock contention mutex holds
    
    like with 11601ef2fbf637bbf163665ee2ae64cbd50c9e92 - given a slow
    enough filesystem the length of time a mutex is held on the shared
    eina file cache really matters. this reduces the mutex hold times and
    thus contention opportunities. can really be seen with a slow enough
    filesystem
    
    @opt
---
 src/lib/eina/eina_file_posix.c | 124 ++++++++++++++++++++++++++++++++---------
 1 file changed, 98 insertions(+), 26 deletions(-)

diff --git a/src/lib/eina/eina_file_posix.c b/src/lib/eina/eina_file_posix.c
index 351f6d0e59..8656c93536 100644
--- a/src/lib/eina/eina_file_posix.c
+++ b/src/lib/eina/eina_file_posix.c
@@ -457,20 +457,52 @@ _eina_file_mmap_faulty_one(void *addr, long page_size,
    return EINA_FALSE;
 }
 
+static void
+_eina_file_cache_file_ref(Eina_File *file)
+{
+   eina_lock_take(&file->lock);
+   file->refcount++;
+   eina_lock_release(&file->lock);
+}
+
+static void
+_eina_file_cache_file_del(Eina_File *file)
+{
+   file->delete_me = EINA_TRUE;
+   eina_hash_del(_eina_file_cache, file->filename, file);
+}
+
 Eina_Bool
 eina_file_mmap_faulty(void *addr, long page_size)
 {
    Eina_File_Map *m;
    Eina_File *f;
+   Eina_File **files = NULL;
    Eina_Iterator *itf;
    Eina_Iterator *itm;
    Eina_Bool faulty = EINA_FALSE;
+   int count = 0;
+   int i = 0;
 
    eina_lock_take(&_eina_file_lock_cache);
 
+   count = eina_hash_population(_eina_file_cache);
+   if (count > 0)
+     files = alloca(sizeof(Eina_File *) * count);
+
    itf = eina_hash_iterator_data_new(_eina_file_cache);
    EINA_ITERATOR_FOREACH(itf, f)
      {
+        _eina_file_cache_file_ref(f);
+        if (files) files[i++] = f;
+     }
+   eina_iterator_free(itf);
+
+   eina_lock_release(&_eina_file_lock_cache);
+
+   for (i = 0; i < count; i++)
+     {
+        f = files[i];
         eina_lock_take(&f->lock);
 
         if (f->global_map != MAP_FAILED)
@@ -478,7 +510,7 @@ eina_file_mmap_faulty(void *addr, long page_size)
              if ((unsigned char *)addr <
                  (((unsigned char *)f->global_map) + f->length) &&
                  (((unsigned char *)addr) + page_size) >=
-                  (unsigned char *)f->global_map)
+                 (unsigned char *)f->global_map)
                {
                   f->global_faulty = EINA_TRUE;
                   faulty = EINA_TRUE;
@@ -508,12 +540,12 @@ eina_file_mmap_faulty(void *addr, long page_size)
           }
 
         eina_lock_release(&f->lock);
-
         if (faulty) break;
      }
-   eina_iterator_free(itf);
 
-   eina_lock_release(&_eina_file_lock_cache);
+   for (i = 0; i < count; i++)
+     eina_file_close(files[i]);
+
    return faulty;
 }
 
@@ -813,11 +845,22 @@ eina_file_open(const char *path, Eina_Bool shared)
    if (!filename) return NULL;
 
    statgen = eina_file_statgen_get();
-   eina_lock_take(&_eina_file_lock_cache);
-   file = eina_hash_find(_eina_file_cache, filename);
-   statgen = eina_file_statgen_get();
-   if ((!file) || (file->statgen != statgen) || (statgen == 0))
+   for (;;)
      {
+        eina_lock_take(&_eina_file_lock_cache);
+        file = eina_hash_find(_eina_file_cache, filename);
+        if (file && (file->statgen == statgen) && (statgen != 0))
+          {
+             _eina_file_cache_file_ref(file);
+             eina_lock_release(&_eina_file_lock_cache);
+             eina_stringshare_del(filename);
+             return file;
+          }
+
+        if (file)
+          _eina_file_cache_file_ref(file);
+        eina_lock_release(&_eina_file_lock_cache);
+
         if (shared)
           {
 #ifdef HAVE_SHM_OPEN
@@ -842,14 +885,29 @@ eina_file_open(const char *path, Eina_Bool shared)
 
         if (fstat(fd, &file_stat))
           goto on_error;
-        if (file) file->statgen = statgen;
 
-        if ((file) && !_eina_file_timestamp_compare(file, &file_stat))
+        if (file && _eina_file_timestamp_compare(file, &file_stat))
           {
-             file->delete_me = EINA_TRUE;
-             eina_hash_del(_eina_file_cache, file->filename, file);
+             eina_lock_take(&file->lock);
+             file->statgen = statgen;
+             eina_lock_release(&file->lock);
+
+             close(fd);
+             eina_stringshare_del(filename);
+             return file;
+          }
+
+        if (file)
+          {
+             eina_lock_take(&_eina_file_lock_cache);
+             if (eina_hash_find(_eina_file_cache, filename) == file)
+               _eina_file_cache_file_del(file);
+             eina_lock_release(&_eina_file_lock_cache);
+
+             eina_file_close(file);
              file = NULL;
           }
+        break;
      }
 
    if (!file)
@@ -859,7 +917,7 @@ eina_file_open(const char *path, Eina_Bool shared)
           goto on_error;
 
         memset(n, 0, sizeof(Eina_File));
-        n->filename = filename;
+        n->filename = eina_stringshare_ref(filename);
         n->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
                                EINA_KEY_CMP(eina_file_map_key_cmp),
                                EINA_KEY_HASH(eina_file_map_key_hash),
@@ -875,30 +933,44 @@ eina_file_open(const char *path, Eina_Bool shared)
         n->inode = file_stat.st_ino;
         n->fd = fd;
         n->shared = shared;
+        n->refcount = 1;
+        n->statgen = statgen;
         eina_lock_new(&n->lock);
-        eina_hash_direct_add(_eina_file_cache, n->filename, n);
 
 	EINA_MAGIC_SET(n, EINA_FILE_MAGIC);
-     }
-   else
-     {
-        if (fd >= 0) close(fd);
-        n = file;
-     }
-   eina_lock_take(&n->lock);
-   n->refcount++;
-   eina_lock_release(&n->lock);
 
-   eina_lock_release(&_eina_file_lock_cache);
+        eina_lock_take(&_eina_file_lock_cache);
+        file = eina_hash_find(_eina_file_cache, filename);
+        if (!file)
+          {
+             eina_hash_direct_add(_eina_file_cache, n->filename, n);
+             eina_lock_release(&_eina_file_lock_cache);
+             eina_stringshare_del(filename);
+             return n;
+          }
 
-   return n;
+        _eina_file_cache_file_ref(file);
+        eina_lock_release(&_eina_file_lock_cache);
+
+        eina_lock_free(&n->lock);
+        eina_hash_free(n->rmap);
+        eina_hash_free(n->map);
+        eina_stringshare_del(n->filename);
+        close(n->fd);
+        free(n);
+        eina_stringshare_del(filename);
+        return file;
+     }
+
+   eina_stringshare_del(filename);
+   return file;
 
  on_error:
-   eina_lock_release(&_eina_file_lock_cache);
    INF("Could not open file [%s].", filename);
    eina_stringshare_del(filename);
 
    if (fd >= 0) close(fd);
+   if (file) eina_file_close(file);
    return NULL;
 }
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to