raster pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=61be4f02bf92c9a0e9eeff9be40b40196471f044
commit 61be4f02bf92c9a0e9eeff9be40b40196471f044 Author: Carsten Haitzler (Rasterman) <[email protected]> Date: Sat Aug 10 12:16:58 2019 +0100 eet dict+ data read - move rw lock to ourside decode for speed read on read/decode we can avoid lots of little locks and unlocked by having the rwlock go to the outside and a single lock+unlock (read) on the dictionary. it blocks for longer by has less atomics/fence points as a result and thus decodes faster where changes that we are writing while decoding is insanely low so no point worrying here. --- src/lib/eet/Eet_private.h | 27 +++++++ src/lib/eet/eet_data.c | 26 +++++-- src/lib/eet/eet_dictionary.c | 170 ++++++++++++++++++++++++++++++------------- 3 files changed, 168 insertions(+), 55 deletions(-) diff --git a/src/lib/eet/Eet_private.h b/src/lib/eet/Eet_private.h index becfabb638..ef274a07ad 100644 --- a/src/lib/eet/Eet_private.h +++ b/src/lib/eet/Eet_private.h @@ -227,16 +227,32 @@ Eet_Dictionary * eet_dictionary_add(void); void eet_dictionary_free(Eet_Dictionary *ed); +void + eet_dictionary_lock_read(const Eet_Dictionary *ed); +void + eet_dictionary_lock_write(Eet_Dictionary *ed); +void + eet_dictionary_unlock(const Eet_Dictionary *ed); int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string); int +eet_dictionary_string_get_size_unlocked(const Eet_Dictionary *ed, + int index); +int eet_dictionary_string_get_size(const Eet_Dictionary *ed, int index); const char * +eet_dictionary_string_get_char_unlocked(const Eet_Dictionary *ed, + int index); +const char * eet_dictionary_string_get_char(const Eet_Dictionary *ed, int index); Eina_Bool +eet_dictionary_string_get_float_unlocked(const Eet_Dictionary *ed, + int index, + float *result); +Eina_Bool eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result); @@ -245,9 +261,20 @@ eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result); Eina_Bool +eet_dictionary_string_get_double_unlocked(const Eet_Dictionary *ed, + int index, + double *result); +Eina_Bool eet_dictionary_string_get_fp(const Eet_Dictionary *ed, int index, Eina_F32p32 *result); +Eina_Bool +eet_dictionary_string_get_fp_unlocked(const Eet_Dictionary *ed, + int index, + Eina_F32p32 *result); +int +eet_dictionary_string_get_hash_unlocked(const Eet_Dictionary *ed, + int index); int eet_dictionary_string_get_hash(const Eet_Dictionary *ed, int index); diff --git a/src/lib/eet/eet_data.c b/src/lib/eet/eet_data.c index 2cda26def6..f8293ed896 100644 --- a/src/lib/eet/eet_data.c +++ b/src/lib/eet/eet_data.c @@ -786,7 +786,7 @@ eet_data_get_string_hash(const Eet_Dictionary *ed, if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1; - return eet_dictionary_string_get_hash(ed, idx); + return eet_dictionary_string_get_hash_unlocked(ed, idx); } return -1; @@ -810,12 +810,12 @@ eet_data_get_string(const Eet_Dictionary *ed, if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1; - str = eet_dictionary_string_get_char(ed, idx); + str = eet_dictionary_string_get_char_unlocked(ed, idx); if (!str) return -1; *d = (char *)str; - return eet_dictionary_string_get_size(ed, idx); + return eet_dictionary_string_get_size_unlocked(ed, idx); } s = (char *)src; @@ -996,7 +996,7 @@ eet_data_get_float(const Eet_Dictionary *ed, if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1; - if (!eet_dictionary_string_get_float(ed, idx, d)) + if (!eet_dictionary_string_get_float_unlocked(ed, idx, d)) return -1; return 1; @@ -1073,7 +1073,7 @@ eet_data_get_double(const Eet_Dictionary *ed, if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1; - if (!eet_dictionary_string_get_double(ed, idx, d)) + if (!eet_dictionary_string_get_double_unlocked(ed, idx, d)) return -1; return 1; @@ -1143,7 +1143,7 @@ eet_data_get_f32p32(const Eet_Dictionary *ed, if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1; - if (!eet_dictionary_string_get_fp(ed, idx, fp)) + if (!eet_dictionary_string_get_fp_unlocked(ed, idx, fp)) return -1; return 1; @@ -2283,9 +2283,11 @@ eet_data_read_cipher(Eet_File *ef, return NULL; } + eet_dictionary_lock_read(ed); // XXX: get manual eet_dictionary lock eet_free_context_init(&context); data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0); eet_free_context_shutdown(&context); + eet_dictionary_unlock(ed); // XXX: release manual eet_dictionary lock if (required_free) free((void *)data); @@ -2322,9 +2324,11 @@ eet_data_read_cipher_buffer(Eet_File *ef, return NULL; } + eet_dictionary_lock_read(ed); // XXX: get manual eet_dictionary lock eet_free_context_init(&context); data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, buffer, buffer_size); eet_free_context_shutdown(&context); + eet_dictionary_unlock(ed); // XXX: release manual eet_dictionary lock if (required_free) free((void *)data); @@ -2357,9 +2361,11 @@ eet_data_node_read_cipher(Eet_File *ef, return NULL; } + eet_dictionary_lock_read(ed); // XXX: get manual eet_dictionary lock eet_free_context_init(&context); result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0); eet_free_context_shutdown(&context); + eet_dictionary_unlock(ed); // XXX: release manual eet_dictionary lock if (required_free) free((void *)data); @@ -2393,7 +2399,9 @@ eet_data_write_cipher(Eet_File *ef, ed = eet_dictionary_get(ef); + // XXX: future manual lock? data_enc = _eet_data_descriptor_encode(ed, edd, data, &size); + // XXX: release manual eet_dictionary lock if (!data_enc) return 0; @@ -4831,9 +4839,11 @@ eet_data_dump_cipher(Eet_File *ef, return 0; } + eet_dictionary_lock_read(ed); // XXX: get manual eet_dictionary lock eet_free_context_init(&context); result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0); eet_free_context_shutdown(&context); + eet_dictionary_unlock(ed); // XXX: release manual eet_dictionary lock eet_node_dump(result, 0, dumpfunc, dumpdata); @@ -4964,7 +4974,9 @@ eet_data_undump_cipher(Eet_File *ef, ed = eet_dictionary_get(ef); + // XXX: in future put lock outside here - rare to dump data_enc = _eet_data_dump_parse(ed, &size, text, textlen); + // XXX: release manual eet_dictionary lock if (!data_enc) return 0; @@ -5140,7 +5152,9 @@ eet_data_node_write_cipher(Eet_File *ef, ed = eet_dictionary_get(ef); + // XXX: in future put lock outside here? data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size); + // XXX: release manual eet_dictionary lock if (!data_enc) return 0; diff --git a/src/lib/eet/eet_dictionary.c b/src/lib/eet/eet_dictionary.c index 7a80463bd6..c8756f7b00 100644 --- a/src/lib/eet/eet_dictionary.c +++ b/src/lib/eet/eet_dictionary.c @@ -72,6 +72,24 @@ _eet_dictionary_lookup(Eet_Dictionary *ed, return current; } +void +eet_dictionary_lock_read(const Eet_Dictionary *ed) +{ + eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); +} + +void +eet_dictionary_lock_write(Eet_Dictionary *ed) +{ + eina_rwlock_take_write((Eina_RWLock *)&ed->rwlock); +} + +void +eet_dictionary_unlock(const Eet_Dictionary *ed) +{ + eina_rwlock_release((Eina_RWLock *)&ed->rwlock); +} + int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string) @@ -143,21 +161,31 @@ on_error: } int -eet_dictionary_string_get_size(const Eet_Dictionary *ed, - int idx) +eet_dictionary_string_get_size_unlocked(const Eet_Dictionary *ed, + int idx) { int length = 0; if (!ed) goto done; if (idx < 0) goto done; - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); if (idx < ed->count) length = ed->all[idx].len; - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); done: return length; } +int +eet_dictionary_string_get_size(const Eet_Dictionary *ed, + int idx) +{ + int length; + + eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); + length = eet_dictionary_string_get_size_unlocked(ed, idx); + eina_rwlock_release((Eina_RWLock *)&ed->rwlock); + return length; +} + EAPI int eet_dictionary_count(const Eet_Dictionary *ed) { @@ -172,31 +200,40 @@ eet_dictionary_count(const Eet_Dictionary *ed) } int -eet_dictionary_string_get_hash(const Eet_Dictionary *ed, - int idx) +eet_dictionary_string_get_hash_unlocked(const Eet_Dictionary *ed, + int idx) { int hash = -1; if (!ed) goto done; if (idx < 0) goto done; - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); if (idx < ed->count) hash = ed->all_hash[idx]; - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); done: return hash; } -const char * -eet_dictionary_string_get_char(const Eet_Dictionary *ed, +int +eet_dictionary_string_get_hash(const Eet_Dictionary *ed, int idx) +{ + int hash; + + eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); + hash = eet_dictionary_string_get_hash_unlocked(ed, idx); + eina_rwlock_release((Eina_RWLock *)&ed->rwlock); + return hash; +} + +const char * +eet_dictionary_string_get_char_unlocked(const Eet_Dictionary *ed, + int idx) { const char *s = NULL; if (!ed) goto done; if (idx < 0) goto done; - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); if (idx < ed->count) { #ifdef _WIN32 @@ -209,11 +246,22 @@ eet_dictionary_string_get_char(const Eet_Dictionary *ed, #endif /* ifdef _WIN32 */ s = ed->all[idx].str; } - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); done: return s; } +const char * +eet_dictionary_string_get_char(const Eet_Dictionary *ed, + int idx) +{ + const char *s = NULL; + + eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); + s = eet_dictionary_string_get_char_unlocked(ed, idx); + eina_rwlock_release((Eina_RWLock *)&ed->rwlock); + return s; +} + static inline Eina_Bool _eet_dictionary_string_get_me_cache(const char *s, int len, @@ -262,9 +310,9 @@ _eet_dictionary_string_get_double_cache(const char *s, } static inline Eina_Bool -_eet_dictionary_test(const Eet_Dictionary *ed, - int idx, - void *result) +_eet_dictionary_test_unlocked(const Eet_Dictionary *ed, + int idx, + void *result) { Eina_Bool limit = EINA_FALSE; @@ -272,23 +320,19 @@ _eet_dictionary_test(const Eet_Dictionary *ed, if (!ed) goto done; if (idx < 0) goto done; - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); - if (!(idx < ed->count)) goto unlock_done; + if (!(idx < ed->count)) goto done; limit = EINA_TRUE; -unlock_done: - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); done: return limit; } static Eet_Convert * -eet_dictionary_convert_get(const Eet_Dictionary *ed, - int idx, - const char **str) +eet_dictionary_convert_get_unlocked(const Eet_Dictionary *ed, + int idx, + const char **str) { Eet_Convert *result; - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); *str = ed->all[idx].str; if (!ed->converts) @@ -304,26 +348,24 @@ add_convert: result = calloc(1, sizeof (Eet_Convert)); eina_hash_add(ed->converts, &idx, result); done: - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); return result; } Eina_Bool -eet_dictionary_string_get_float(const Eet_Dictionary *ed, - int idx, - float *result) +eet_dictionary_string_get_float_unlocked(const Eet_Dictionary *ed, + int idx, + float *result) { Eet_Convert *convert; const char *str; - if (!_eet_dictionary_test(ed, idx, result)) return EINA_FALSE; + if (!_eet_dictionary_test_unlocked(ed, idx, result)) return EINA_FALSE; - convert = eet_dictionary_convert_get(ed, idx, &str); + convert = eet_dictionary_convert_get_unlocked(ed, idx, &str); if (!convert) return EINA_FALSE; if (!(convert->type & EET_D_FLOAT)) { - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); if (!_eet_dictionary_string_get_float_cache(str, ed->all[idx].len, &convert->f)) { @@ -333,12 +375,10 @@ eet_dictionary_string_get_float(const Eet_Dictionary *ed, if (eina_convert_atod(str, ed->all[idx].len, &mantisse, &exponent) == EINA_FALSE) { - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); return EINA_FALSE; } convert->f = ldexpf((float)mantisse, exponent); } - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); convert->type |= EET_D_FLOAT; } *result = convert->f; @@ -346,22 +386,33 @@ eet_dictionary_string_get_float(const Eet_Dictionary *ed, } Eina_Bool -eet_dictionary_string_get_double(const Eet_Dictionary *ed, - int idx, - double *result) +eet_dictionary_string_get_float(const Eet_Dictionary *ed, + int idx, + float *result) +{ + Eina_Bool ret; + + eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); + ret = eet_dictionary_string_get_float_unlocked(ed, idx, result); + eina_rwlock_release((Eina_RWLock *)&ed->rwlock); + return ret; +} + +Eina_Bool +eet_dictionary_string_get_double_unlocked(const Eet_Dictionary *ed, + int idx, + double *result) { Eet_Convert *convert; const char *str; - if (!_eet_dictionary_test(ed, idx, result)) return EINA_FALSE; + if (!_eet_dictionary_test_unlocked(ed, idx, result)) return EINA_FALSE; - convert = eet_dictionary_convert_get(ed, idx, &str); + convert = eet_dictionary_convert_get_unlocked(ed, idx, &str); if (!convert) return EINA_FALSE; if (!(convert->type & EET_D_DOUBLE)) { - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); - if (!_eet_dictionary_string_get_double_cache(str, ed->all[idx].len, &convert->d)) { @@ -371,12 +422,10 @@ eet_dictionary_string_get_double(const Eet_Dictionary *ed, if (eina_convert_atod(str, ed->all[idx].len, &mantisse, &exponent) == EINA_FALSE) { - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); return EINA_FALSE; } convert->d = ldexp((double)mantisse, exponent); } - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); convert->type |= EET_D_DOUBLE; } @@ -385,29 +434,39 @@ eet_dictionary_string_get_double(const Eet_Dictionary *ed, } Eina_Bool -eet_dictionary_string_get_fp(const Eet_Dictionary *ed, - int idx, - Eina_F32p32 *result) +eet_dictionary_string_get_double(const Eet_Dictionary *ed, + int idx, + double *result) +{ + Eina_Bool ret; + + eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); + ret = eet_dictionary_string_get_double_unlocked(ed, idx, result); + eina_rwlock_release((Eina_RWLock *)&ed->rwlock); + return ret; +} + +Eina_Bool +eet_dictionary_string_get_fp_unlocked(const Eet_Dictionary *ed, + int idx, + Eina_F32p32 *result) { Eet_Convert *convert; const char *str; - if (!_eet_dictionary_test(ed, idx, result)) return EINA_FALSE; + if (!_eet_dictionary_test_unlocked(ed, idx, result)) return EINA_FALSE; - convert = eet_dictionary_convert_get(ed, idx, &str); + convert = eet_dictionary_convert_get_unlocked(ed, idx, &str); if (!convert) return EINA_FALSE; if (!(convert->type & EET_D_FIXED_POINT)) { Eina_F32p32 fp; - eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); if (!eina_convert_atofp(str, ed->all[idx].len, &fp)) { - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); return EINA_FALSE; } - eina_rwlock_release((Eina_RWLock *)&ed->rwlock); convert->fp = fp; convert->type |= EET_D_FIXED_POINT; @@ -417,6 +476,19 @@ eet_dictionary_string_get_fp(const Eet_Dictionary *ed, return EINA_TRUE; } +Eina_Bool +eet_dictionary_string_get_fp(const Eet_Dictionary *ed, + int idx, + Eina_F32p32 *result) +{ + Eina_Bool ret; + + eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock); + ret = eet_dictionary_string_get_fp_unlocked(ed, idx, result); + eina_rwlock_release((Eina_RWLock *)&ed->rwlock); + return ret; +} + EAPI int eet_dictionary_string_check(Eet_Dictionary *ed, const char *string) --
