move majority of allocations to mempool allocators similar to ecore-con
authordiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 2 Dec 2011 16:10:41 +0000 (16:10 +0000)
committerdiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 2 Dec 2011 16:10:41 +0000 (16:10 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eet@65825 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
NEWS
src/lib/Eet_private.h
src/lib/Makefile.am
src/lib/eet_alloc.c [new file with mode: 0644]
src/lib/eet_dictionary.c
src/lib/eet_lib.c

index ed90848..9db34e0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
         * added eet_file_get to return the filename of an Eet_File
         * Eet_File filenames are now stringshared
+        * added mempool allocators
diff --git a/NEWS b/NEWS
index 3e11314..cccda15 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ Changes since Eet 1.5.0:
 Additions:
     * eet_file_get to return filenames of Eet_Files
 
+Improvements:
+
+    * most allocations moved to mempools
 
 Eet 1.5.0
 
index 83f4c18..0234221 100644 (file)
@@ -66,6 +66,126 @@ struct _Eet_Node
    Eet_Node_Data data;
 };
 
+typedef struct _Eet_File_Header    Eet_File_Header;
+typedef struct _Eet_File_Node      Eet_File_Node;
+typedef struct _Eet_File_Directory Eet_File_Directory;
+
+struct _Eet_File
+{
+   const char          *path;
+   Eina_File           *readfp;
+   Eet_File_Header     *header;
+   Eet_Dictionary      *ed;
+   Eet_Key             *key;
+   const unsigned char *data;
+   const void          *x509_der;
+   const void          *signature;
+   void                *sha1;
+
+   Eet_File_Mode        mode;
+
+   int                  magic;
+   int                  references;
+
+   unsigned long int    data_size;
+   int                  x509_length;
+   unsigned int         signature_length;
+   int                  sha1_length;
+
+   Eina_Lock            file_lock;
+
+   unsigned char        writes_pending : 1;
+   unsigned char        delete_me_now : 1;
+};
+
+struct _Eet_File_Header
+{
+   int                 magic;
+   Eet_File_Directory *directory;
+};
+
+struct _Eet_File_Directory
+{
+   int             size;
+   Eet_File_Node **nodes;
+};
+
+struct _Eet_File_Node
+{
+   char             *name;
+   void             *data;
+   Eet_File_Node    *next; /* FIXME: make buckets linked lists */
+
+   unsigned long int offset;
+   unsigned long int dictionary_offset;
+   unsigned long int name_offset;
+
+   unsigned int      name_size;
+   unsigned int      size;
+   unsigned int      data_size;
+
+   unsigned char     free_name : 1;
+   unsigned char     compression : 1;
+   unsigned char     ciphered : 1;
+   unsigned char     alias : 1;
+};
+
+#if 0
+/* Version 2 */
+/* NB: all int's are stored in network byte order on disk */
+/* file format: */
+int magic; /* magic number ie 0x1ee7ff00 */
+int num_directory_entries; /* number of directory entries to follow */
+int bytes_directory_entries; /* bytes of directory entries to follow */
+struct
+{
+   int  offset; /* bytes offset into file for data chunk */
+   int  flags; /* flags - for now 0 = uncompressed and clear, 1 = compressed and clear, 2 = uncompressed and ciphered, 3 = compressed and ciphered */
+   int  size; /* size of the data chunk */
+   int  data_size; /* size of the (uncompressed) data chunk */
+   int  name_size; /* length in bytes of the name field */
+   char name[name_size]; /* name string (variable length) and \0 terminated */
+} directory[num_directory_entries];
+/* and now startes the data stream... */
+#endif /* if 0 */
+
+#if 0
+/* Version 3 */
+/* NB: all int's are stored in network byte order on disk */
+/* file format: */
+int magic; /* magic number ie 0x1ee70f42 */
+int num_directory_entries; /* number of directory entries to follow */
+int num_dictionary_entries; /* number of dictionary entries to follow */
+struct
+{
+   int data_offset; /* bytes offset into file for data chunk */
+   int size; /* size of the data chunk */
+   int data_size; /* size of the (uncompressed) data chunk */
+   int name_offset; /* bytes offset into file for name string */
+   int name_size; /* length in bytes of the name field */
+   int flags; /* bit flags - for now:
+                 bit 0 => compresion on/off
+                 bit 1 => ciphered on/off
+                 bit 2 => alias
+               */
+} directory[num_directory_entries];
+struct
+{
+   int hash;
+   int offset;
+   int size;
+   int prev;
+   int next;
+} dictionary[num_dictionary_entries];
+/* now start the string stream. */
+/* and right after them the data stream. */
+int magic_sign; /* Optional, only if the eet file is signed. */
+int signature_length; /* Signature length. */
+int x509_length; /* Public certificate that signed the file. */
+char signature[signature_length]; /* The signature. */
+char x509[x509_length]; /* The public certificate. */
+#endif /* if 0 */
+
 /*
  * variable and macros used for the eina_log module
  */
@@ -178,6 +298,22 @@ Eet_Node *
 void
  eet_node_free(Eet_Node *node);
 
+
+#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
+  TYPE *Type##_malloc(unsigned int);                 \
+  TYPE *Type##_calloc(unsigned int);                 \
+  void Type##_mp_free(TYPE *e);
+
+GENERIC_ALLOC_FREE_HEADER(Eet_File_Directory, eet_file_directory);
+GENERIC_ALLOC_FREE_HEADER(Eet_File_Node, eet_file_node);
+GENERIC_ALLOC_FREE_HEADER(Eet_File_Header, eet_file_header);
+GENERIC_ALLOC_FREE_HEADER(Eet_Dictionary, eet_dictionary);
+GENERIC_ALLOC_FREE_HEADER(Eet_File, eet_file);
+GENERIC_ALLOC_FREE_HEADER(Eet_String, eet_string);
+
+Eina_Bool eet_mempool_init(void);
+void eet_mempool_shutdown(void);
+
 #ifndef PATH_MAX
 # define PATH_MAX 4096
 #endif /* ifndef PATH_MAX */
index 4633749..ae60168 100644 (file)
@@ -22,6 +22,7 @@ includesdir = $(includedir)/eet-@VMAJ@
 lib_LTLIBRARIES = libeet.la
 
 base_sources = \
+eet_alloc.c \
 eet_lib.c \
 eet_data.c \
 eet_image.c \
diff --git a/src/lib/eet_alloc.c b/src/lib/eet_alloc.c
new file mode 100644 (file)
index 0000000..2f62b1b
--- /dev/null
@@ -0,0 +1,95 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include "Eet.h"
+#include "Eet_private.h"
+
+typedef struct _Eet_Mempool Eet_Mempool;
+struct _Eet_Mempool
+{
+   const char *name;
+   Eina_Mempool *mp;
+   size_t size;
+};
+
+#define GENERIC_ALLOC_FREE(TYPE, Type)                                  \
+  Eet_Mempool Type##_mp = { #TYPE,  NULL, sizeof (TYPE) };              \
+                                                                        \
+  TYPE *                                                                \
+  Type##_malloc(unsigned int num)                                       \
+  {                                                                     \
+     return eina_mempool_malloc(Type##_mp.mp, num * sizeof (TYPE));     \
+  }                                                                     \
+  TYPE *                                                                \
+  Type##_calloc(unsigned int num)                                       \
+  {                                                                     \
+     return eina_mempool_calloc(Type##_mp.mp, num * sizeof (TYPE));     \
+  }                                                                     \
+  void                                                                  \
+  Type##_mp_free(TYPE *e)                                               \
+  {                                                                     \
+     eina_mempool_free(Type##_mp.mp, e);                                \
+  }
+
+GENERIC_ALLOC_FREE(Eet_File_Directory, eet_file_directory);
+GENERIC_ALLOC_FREE(Eet_File_Node, eet_file_node);
+GENERIC_ALLOC_FREE(Eet_File_Header, eet_file_header);
+GENERIC_ALLOC_FREE(Eet_Dictionary, eet_dictionary);
+GENERIC_ALLOC_FREE(Eet_File, eet_file);
+GENERIC_ALLOC_FREE(Eet_String, eet_string);
+
+static Eet_Mempool *mempool_array[] = {
+  &eet_file_directory_mp,
+  &eet_file_node_mp,
+  &eet_file_header_mp,
+  &eet_dictionary_mp,
+  &eet_file_mp,
+  &eet_string_mp
+};
+
+Eina_Bool
+eet_mempool_init(void)
+{
+   const char *choice;
+   unsigned int i;
+
+   choice = getenv("EINA_MEMPOOL");
+   if ((!choice) || (!choice[0]))
+     choice = "chained_mempool";
+
+   for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
+     {
+     retry:
+        mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 64);
+        if (!mempool_array[i]->mp)
+          {
+             if (!strcmp(choice, "pass_through"))
+               {
+                  ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice);
+                  choice = "pass_through";
+                  goto retry;
+               }
+             else
+               {
+                  ERR("Impossible to allocate mempool '%s' !", choice);
+                  return EINA_FALSE;
+               }
+          }
+     }
+   return EINA_TRUE;
+}
+
+void
+eet_mempool_shutdown(void)
+{
+   unsigned int i;
+
+   for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
+     {
+        eina_mempool_del(mempool_array[i]->mp);
+        mempool_array[i]->mp = NULL;
+     }
+}
+
index 3f35066..d551d5f 100644 (file)
@@ -28,21 +28,20 @@ eet_dictionary_add(void)
 void
 eet_dictionary_free(Eet_Dictionary *ed)
 {
-   if (ed)
-     {
-        int i;
+   int i;
 
-        for (i = 0; i < ed->count; ++i)
-          if (ed->all[i].allocated)
-            eina_stringshare_del(ed->all[i].str);
+   if (!ed) return;
 
-        if (ed->all)
-          free(ed->all);
+   for (i = 0; i < ed->count; ++i)
+     if (ed->all[i].allocated)
+       eina_stringshare_del(ed->all[i].str);
 
-        if (ed->converts) eina_hash_free(ed->converts);
+   if (ed->all)
+     eet_string_mp_free(ed->all);
 
-        free(ed);
-     }
+   if (ed->converts) eina_hash_free(ed->converts);
+
+   eet_dictionary_mp_free(ed);
 }
 
 static int
index 089f9d3..dc15290 100644 (file)
@@ -82,126 +82,6 @@ EAPI Eet_Version *eet_version = &_version;
 
 #define EET_MAGIC_FILE2       0x1ee70f42
 
-typedef struct _Eet_File_Header    Eet_File_Header;
-typedef struct _Eet_File_Node      Eet_File_Node;
-typedef struct _Eet_File_Directory Eet_File_Directory;
-
-struct _Eet_File
-{
-   const char          *path;
-   Eina_File           *readfp;
-   Eet_File_Header     *header;
-   Eet_Dictionary      *ed;
-   Eet_Key             *key;
-   const unsigned char *data;
-   const void          *x509_der;
-   const void          *signature;
-   void                *sha1;
-
-   Eet_File_Mode        mode;
-
-   int                  magic;
-   int                  references;
-
-   unsigned long int    data_size;
-   int                  x509_length;
-   unsigned int         signature_length;
-   int                  sha1_length;
-
-   Eina_Lock            file_lock;
-
-   unsigned char        writes_pending : 1;
-   unsigned char        delete_me_now : 1;
-};
-
-struct _Eet_File_Header
-{
-   int                 magic;
-   Eet_File_Directory *directory;
-};
-
-struct _Eet_File_Directory
-{
-   int             size;
-   Eet_File_Node **nodes;
-};
-
-struct _Eet_File_Node
-{
-   char             *name;
-   void             *data;
-   Eet_File_Node    *next; /* FIXME: make buckets linked lists */
-
-   unsigned long int offset;
-   unsigned long int dictionary_offset;
-   unsigned long int name_offset;
-
-   unsigned int      name_size;
-   unsigned int      size;
-   unsigned int      data_size;
-
-   unsigned char     free_name : 1;
-   unsigned char     compression : 1;
-   unsigned char     ciphered : 1;
-   unsigned char     alias : 1;
-};
-
-#if 0
-/* Version 2 */
-/* NB: all int's are stored in network byte order on disk */
-/* file format: */
-int magic; /* magic number ie 0x1ee7ff00 */
-int num_directory_entries; /* number of directory entries to follow */
-int bytes_directory_entries; /* bytes of directory entries to follow */
-struct
-{
-   int  offset; /* bytes offset into file for data chunk */
-   int  flags; /* flags - for now 0 = uncompressed and clear, 1 = compressed and clear, 2 = uncompressed and ciphered, 3 = compressed and ciphered */
-   int  size; /* size of the data chunk */
-   int  data_size; /* size of the (uncompressed) data chunk */
-   int  name_size; /* length in bytes of the name field */
-   char name[name_size]; /* name string (variable length) and \0 terminated */
-} directory[num_directory_entries];
-/* and now startes the data stream... */
-#endif /* if 0 */
-
-#if 0
-/* Version 3 */
-/* NB: all int's are stored in network byte order on disk */
-/* file format: */
-int magic; /* magic number ie 0x1ee70f42 */
-int num_directory_entries; /* number of directory entries to follow */
-int num_dictionary_entries; /* number of dictionary entries to follow */
-struct
-{
-   int data_offset; /* bytes offset into file for data chunk */
-   int size; /* size of the data chunk */
-   int data_size; /* size of the (uncompressed) data chunk */
-   int name_offset; /* bytes offset into file for name string */
-   int name_size; /* length in bytes of the name field */
-   int flags; /* bit flags - for now:
-                 bit 0 => compresion on/off
-                 bit 1 => ciphered on/off
-                 bit 2 => alias
-               */
-} directory[num_directory_entries];
-struct
-{
-   int hash;
-   int offset;
-   int size;
-   int prev;
-   int next;
-} dictionary[num_dictionary_entries];
-/* now start the string stream. */
-/* and right after them the data stream. */
-int magic_sign; /* Optional, only if the eet file is signed. */
-int signature_length; /* Signature length. */
-int x509_length; /* Public certificate that signed the file. */
-char signature[signature_length]; /* The signature. */
-char x509[x509_length]; /* The public certificate. */
-#endif /* if 0 */
-
 #define EET_FILE2_HEADER_COUNT           3
 #define EET_FILE2_DIRECTORY_ENTRY_COUNT  6
 #define EET_FILE2_DICTIONARY_ENTRY_COUNT 5
@@ -694,12 +574,18 @@ eet_init(void)
 
    eina_lock_new(&eet_cache_lock);
 
-   if (!eet_node_init())
+   if (!eet_mempool_init())
      {
         EINA_LOG_ERR("Eet: Eet_Node mempool creation failed");
         goto unregister_log_domain;
      }
 
+   if (!eet_node_init())
+     {
+        EINA_LOG_ERR("Eet: Eet_Node mempool creation failed");
+        goto shutdown_mempool;
+     }
+
 #ifdef HAVE_GNUTLS
    /* Before the library can be used, it must initialize itself if needed. */
    if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
@@ -741,6 +627,8 @@ eet_init(void)
 shutdown_eet:
 #endif
    eet_node_shutdown();
+shutdown_mempool:
+   eet_mempool_shutdown();
 unregister_log_domain:
    eina_log_domain_unregister(_eet_log_dom_global);
    _eet_log_dom_global = -1;
@@ -757,6 +645,7 @@ eet_shutdown(void)
 
    eet_clearcache();
    eet_node_shutdown();
+   eet_mempool_shutdown();
 
    eina_lock_free(&eet_cache_lock);
 
@@ -902,14 +791,14 @@ eet_internal_read2(Eet_File *ef)
      return NULL;
 
    /* allocate header */
-   ef->header = calloc(1, sizeof(Eet_File_Header));
+   ef->header = eet_file_header_calloc(1);
    if (eet_test_close(!ef->header, ef))
      return NULL;
 
    ef->header->magic = EET_MAGIC_FILE_HEADER;
 
    /* allocate directory block in ram */
-   ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
+   ef->header->directory = eet_file_directory_calloc(1);
    if (eet_test_close(!ef->header->directory, ef))
      return NULL;
 
@@ -939,10 +828,10 @@ eet_internal_read2(Eet_File *ef)
 
         /* out directory block is inconsistent - we have overrun our */
         /* dynamic block buffer before we finished scanning dir entries */
-        efn = malloc(sizeof(Eet_File_Node));
+        efn = eet_file_node_malloc(1);
         if (eet_test_close(!efn, ef))
           {
-             if (efn) free(efn);  /* yes i know - we only get here if
+             if (efn) eet_file_node_mp_free(efn);  /* yes i know - we only get here if
                                    * efn is null/0 -> trying to shut up
                                    * warning tools like cppcheck */
              return NULL;
@@ -1022,11 +911,11 @@ eet_internal_read2(Eet_File *ef)
                            ef))
           return NULL;
 
-        ef->ed = calloc(1, sizeof (Eet_Dictionary));
+        ef->ed = eet_dictionary_calloc(1);
         if (eet_test_close(!ef->ed, ef))
           return NULL;
 
-        ef->ed->all = calloc(num_dictionary_entries, sizeof (Eet_String));
+        ef->ed->all = eet_string_calloc(num_dictionary_entries);
         if (eet_test_close(!ef->ed->all, ef))
           return NULL;
 
@@ -1162,14 +1051,14 @@ eet_internal_read1(Eet_File *ef)
      return NULL;
 
    /* allocate header */
-   ef->header = calloc(1, sizeof(Eet_File_Header));
+   ef->header = eet_file_header_calloc(1);
    if (eet_test_close(!ef->header, ef))
      return NULL;
 
    ef->header->magic = EET_MAGIC_FILE_HEADER;
 
    /* allocate directory block in ram */
-   ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
+   ef->header->directory = eet_file_directory_calloc(1);
    if (eet_test_close(!ef->header->directory, ef))
      return NULL;
 
@@ -1207,7 +1096,7 @@ eet_internal_read1(Eet_File *ef)
         efn = malloc (sizeof(Eet_File_Node));
         if (eet_test_close(!efn, ef))
           {
-             if (efn) free(efn);  /* yes i know - we only get here if
+             if (efn) eet_file_node_mp_free(efn);  /* yes i know - we only get here if
                                    * efn is null/0 -> trying to shut up
                                    * warning tools like cppcheck */
              return NULL;
@@ -1227,21 +1116,21 @@ eet_internal_read1(Eet_File *ef)
         /* invalid size */
         if (eet_test_close(efn->size <= 0, ef))
           {
-             free(efn);
+             eet_file_node_mp_free(efn);
              return NULL;
           }
 
         /* invalid name_size */
         if (eet_test_close(name_size <= 0, ef))
           {
-             free(efn);
+             eet_file_node_mp_free(efn);
              return NULL;
           }
 
         /* reading name would mean falling off end of dyn_buf - invalid */
         if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
           {
-             free(efn);
+             eet_file_node_mp_free(efn);
              return NULL;
           }
 
@@ -1257,7 +1146,7 @@ eet_internal_read1(Eet_File *ef)
              efn->name = malloc(sizeof(char) * name_size + 1);
              if (eet_test_close(!efn->name, ef))
                {
-                  free(efn);
+                  eet_file_node_mp_free(efn);
                   return NULL;
                }
 
@@ -1405,16 +1294,16 @@ eet_internal_close(Eet_File *ef,
                             if (efn->free_name)
                               free(efn->name);
 
-                            free(efn);
+                            eet_file_node_mp_free(efn);
                          }
                     }
                   free(ef->header->directory->nodes);
                }
 
-             free(ef->header->directory);
+             eet_file_directory_mp_free(ef->header->directory);
           }
 
-        free(ef->header);
+        eet_file_header_mp_free(ef->header);
      }
 
    eet_dictionary_free(ef->ed);
@@ -1435,7 +1324,7 @@ eet_internal_close(Eet_File *ef,
 
    /* free it */
    eina_stringshare_del(ef->path);
-   free(ef);
+   eet_file_mp_free(ef);
    return err;
 
 on_error:
@@ -1586,7 +1475,7 @@ open_error:
    file_len = strlen(file) + 1;
 
    /* Allocate struct for eet file and have it zero'd out */
-   ef = malloc(sizeof(Eet_File));
+   ef = eet_file_malloc(1);
    if (!ef)
      goto on_error;
 
@@ -2118,7 +2007,7 @@ eet_alias(Eet_File   *ef,
          ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
          if (!ef->header->directory)
            {
-              free(ef->header);
+              eet_file_header_mp_free(ef->header);
               ef->header = NULL;
               goto on_error;
            }
@@ -2131,7 +2020,7 @@ eet_alias(Eet_File   *ef,
                   (1 << ef->header->directory->size));
          if (!ef->header->directory->nodes)
            {
-              free(ef->header->directory);
+              eet_file_directory_mp_free(ef->header->directory);
               ef->header = NULL;
               goto on_error;
            }
@@ -2278,7 +2167,7 @@ eet_write_cipher(Eet_File   *ef,
          ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
          if (!ef->header->directory)
            {
-              free(ef->header);
+              eet_file_header_mp_free(ef->header);
               ef->header = NULL;
               goto on_error;
            }
@@ -2291,7 +2180,7 @@ eet_write_cipher(Eet_File   *ef,
                   (1 << ef->header->directory->size));
          if (!ef->header->directory->nodes)
            {
-              free(ef->header->directory);
+              eet_file_directory_mp_free(ef->header->directory);
               ef->header = NULL;
               goto on_error;
            }
@@ -2479,7 +2368,7 @@ eet_delete(Eet_File   *ef,
               if (efn->free_name)
                 free(efn->name);
 
-              free(efn);
+              eet_file_node_mp_free(efn);
               exists_already = 1;
               break;
            }