From: discomfitor Date: Fri, 2 Dec 2011 16:10:41 +0000 (+0000) Subject: move majority of allocations to mempool allocators similar to ecore-con X-Git-Tag: submit/2.0alpha-wayland/20121127.222001~120 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=72546a31228b51d5b8782c43ecc3b5f1ea172635;p=profile%2Fivi%2Feet.git move majority of allocations to mempool allocators similar to ecore-con git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eet@65825 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/ChangeLog b/ChangeLog index ed90848..9db34e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -551,3 +551,4 @@ * 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 --- 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 diff --git a/src/lib/Eet_private.h b/src/lib/Eet_private.h index 83f4c18..0234221 100644 --- a/src/lib/Eet_private.h +++ b/src/lib/Eet_private.h @@ -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 */ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 4633749..ae60168 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -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 index 0000000..2f62b1b --- /dev/null +++ b/src/lib/eet_alloc.c @@ -0,0 +1,95 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#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; + } +} + diff --git a/src/lib/eet_dictionary.c b/src/lib/eet_dictionary.c index 3f35066..d551d5f 100644 --- a/src/lib/eet_dictionary.c +++ b/src/lib/eet_dictionary.c @@ -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 diff --git a/src/lib/eet_lib.c b/src/lib/eet_lib.c index 089f9d3..dc15290 100644 --- a/src/lib/eet_lib.c +++ b/src/lib/eet_lib.c @@ -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; }