summaryrefslogtreecommitdiff
path: root/src/lib/eet
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2018-11-20 16:55:45 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2018-11-21 13:37:16 +0000
commitc0d6cbab97a1fac072aa1a7101165d9db25903a7 (patch)
tree6f4914441aac3b72728c9e59b3b6cee417b7ce72 /src/lib/eet
parentbb455f3490e3ce76d01a34f27ebc97c0fa812168 (diff)
eet - dictionary - use rwlocks instead of spinlocks - better contention
if the dict is contended on by lots of threads then a spinlock really makes it slow. a rwlock gets about 1.5-2x speedup depending on arch/thread count. @optimize
Diffstat (limited to 'src/lib/eet')
-rw-r--r--src/lib/eet/Eet_private.h4
-rw-r--r--src/lib/eet/eet_dictionary.c64
2 files changed, 35 insertions, 33 deletions
diff --git a/src/lib/eet/Eet_private.h b/src/lib/eet/Eet_private.h
index ca552277c1..43b4c141a4 100644
--- a/src/lib/eet/Eet_private.h
+++ b/src/lib/eet/Eet_private.h
@@ -40,8 +40,8 @@ struct _Eet_Dictionary
40 unsigned char *all_hash; 40 unsigned char *all_hash;
41 unsigned char *all_allocated; 41 unsigned char *all_allocated;
42 42
43 Eina_Hash *converts; 43 Eina_Hash *converts;
44 Eina_Spinlock mutex; 44 Eina_RWLock rwlock;
45 45
46 int size; 46 int size;
47 int offset; 47 int offset;
diff --git a/src/lib/eet/eet_dictionary.c b/src/lib/eet/eet_dictionary.c
index 779eb216aa..c8ea01642b 100644
--- a/src/lib/eet/eet_dictionary.c
+++ b/src/lib/eet/eet_dictionary.c
@@ -21,7 +21,7 @@ eet_dictionary_add(void)
21 return NULL; 21 return NULL;
22 22
23 memset(new->hash, -1, sizeof (int) * 256); 23 memset(new->hash, -1, sizeof (int) * 256);
24 eina_spinlock_new(&new->mutex); 24 eina_rwlock_new(&new->rwlock);
25 25
26 return new; 26 return new;
27} 27}
@@ -33,7 +33,7 @@ eet_dictionary_free(Eet_Dictionary *ed)
33 33
34 if (!ed) return; 34 if (!ed) return;
35 35
36 eina_spinlock_free(&ed->mutex); 36 eina_rwlock_free(&ed->rwlock);
37 37
38 for (i = 0; i < ed->count; ++i) 38 for (i = 0; i < ed->count; ++i)
39 if (ed->all_allocated[i >> 3] & (1 << (i & 0x7))) 39 if (ed->all_allocated[i >> 3] & (1 << (i & 0x7)))
@@ -98,7 +98,7 @@ eet_dictionary_string_add(Eet_Dictionary *ed,
98 hash = _eet_hash_gen(string, 8); 98 hash = _eet_hash_gen(string, 8);
99 len = strlen(string) + 1; 99 len = strlen(string) + 1;
100 100
101 eina_spinlock_take(&ed->mutex); 101 eina_rwlock_take_read(&ed->rwlock);
102 102
103 idx = _eet_dictionary_lookup(ed, string, len, hash, &pidx); 103 idx = _eet_dictionary_lookup(ed, string, len, hash, &pidx);
104 104
@@ -108,11 +108,16 @@ eet_dictionary_string_add(Eet_Dictionary *ed,
108 ((ed->all[idx].str == string) || 108 ((ed->all[idx].str == string) ||
109 (!strcmp(ed->all[idx].str, string)))) 109 (!strcmp(ed->all[idx].str, string))))
110 { 110 {
111 eina_spinlock_release(&ed->mutex); 111 eina_rwlock_release(&ed->rwlock);
112 return idx; 112 return idx;
113 } 113 }
114 } 114 }
115 115
116 str = eina_stringshare_add(string);
117 if (!str) goto on_error;
118
119 eina_rwlock_release(&ed->rwlock);
120 eina_rwlock_take_write(&ed->rwlock);
116 if (ed->total == ed->count) 121 if (ed->total == ed->count)
117 { 122 {
118 Eet_String *new; 123 Eet_String *new;
@@ -120,7 +125,7 @@ eet_dictionary_string_add(Eet_Dictionary *ed,
120 unsigned char *new_allocated; 125 unsigned char *new_allocated;
121 int total; 126 int total;
122 127
123 total = ed->total + 8; 128 total = ed->total + 64;
124 129
125 new = realloc(ed->all, total * sizeof(Eet_String)); 130 new = realloc(ed->all, total * sizeof(Eet_String));
126 if (!new) goto on_error; 131 if (!new) goto on_error;
@@ -137,9 +142,6 @@ eet_dictionary_string_add(Eet_Dictionary *ed,
137 ed->total = total; 142 ed->total = total;
138 } 143 }
139 144
140 str = eina_stringshare_add(string);
141 if (!str) goto on_error;
142
143 current = ed->all + ed->count; 145 current = ed->all + ed->count;
144 146
145 ed->all_allocated[ed->count >> 3] |= (1 << (ed->count & 0x7)); 147 ed->all_allocated[ed->count >> 3] |= (1 << (ed->count & 0x7));
@@ -164,11 +166,11 @@ eet_dictionary_string_add(Eet_Dictionary *ed,
164 } 166 }
165 167
166 cnt = ed->count++; 168 cnt = ed->count++;
167 eina_spinlock_release(&ed->mutex); 169 eina_rwlock_release(&ed->rwlock);
168 return cnt; 170 return cnt;
169 171
170 on_error: 172 on_error:
171 eina_spinlock_release(&ed->mutex); 173 eina_rwlock_release(&ed->rwlock);
172 return -1; 174 return -1;
173} 175}
174 176
@@ -182,12 +184,12 @@ eet_dictionary_string_get_size(const Eet_Dictionary *ed,
182 184
183 if (idx < 0) goto done; 185 if (idx < 0) goto done;
184 186
185 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 187 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
186 188
187 if (idx < ed->count) 189 if (idx < ed->count)
188 length = ed->all[idx].len; 190 length = ed->all[idx].len;
189 191
190 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 192 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
191 193
192 done: 194 done:
193 return length; 195 return length;
@@ -209,12 +211,12 @@ eet_dictionary_string_get_hash(const Eet_Dictionary *ed,
209 211
210 if (idx < 0) goto done; 212 if (idx < 0) goto done;
211 213
212 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 214 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
213 215
214 if (idx < ed->count) 216 if (idx < ed->count)
215 hash = ed->all_hash[idx]; 217 hash = ed->all_hash[idx];
216 218
217 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 219 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
218 220
219 done: 221 done:
220 return hash; 222 return hash;
@@ -230,7 +232,7 @@ eet_dictionary_string_get_char(const Eet_Dictionary *ed,
230 232
231 if (idx < 0) goto done; 233 if (idx < 0) goto done;
232 234
233 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 235 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
234 236
235 if (idx < ed->count) 237 if (idx < ed->count)
236 { 238 {
@@ -245,7 +247,7 @@ eet_dictionary_string_get_char(const Eet_Dictionary *ed,
245 s = ed->all[idx].str; 247 s = ed->all[idx].str;
246 } 248 }
247 249
248 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 250 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
249 251
250 done: 252 done:
251 return s; 253 return s;
@@ -323,14 +325,14 @@ _eet_dictionary_test(const Eet_Dictionary *ed,
323 325
324 if (idx < 0) goto done; 326 if (idx < 0) goto done;
325 327
326 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 328 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
327 329
328 if (!(idx < ed->count)) goto unlock_done; 330 if (!(idx < ed->count)) goto unlock_done;
329 331
330 limit = EINA_TRUE; 332 limit = EINA_TRUE;
331 333
332 unlock_done: 334 unlock_done:
333 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 335 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
334 336
335 done: 337 done:
336 return limit; 338 return limit;
@@ -343,7 +345,7 @@ eet_dictionary_convert_get(const Eet_Dictionary *ed,
343{ 345{
344 Eet_Convert *result; 346 Eet_Convert *result;
345 347
346 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 348 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
347 349
348 *str = ed->all[idx].str; 350 *str = ed->all[idx].str;
349 351
@@ -363,7 +365,7 @@ eet_dictionary_convert_get(const Eet_Dictionary *ed,
363 eina_hash_add(ed->converts, &idx, result); 365 eina_hash_add(ed->converts, &idx, result);
364 366
365 done: 367 done:
366 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 368 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
367 369
368 return result; 370 return result;
369} 371}
@@ -384,7 +386,7 @@ eet_dictionary_string_get_float(const Eet_Dictionary *ed,
384 386
385 if (!(convert->type & EET_D_FLOAT)) 387 if (!(convert->type & EET_D_FLOAT))
386 { 388 {
387 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 389 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
388 if (!_eet_dictionary_string_get_float_cache(str, ed->all[idx].len, 390 if (!_eet_dictionary_string_get_float_cache(str, ed->all[idx].len,
389 &convert->f)) 391 &convert->f))
390 { 392 {
@@ -394,13 +396,13 @@ eet_dictionary_string_get_float(const Eet_Dictionary *ed,
394 if (eina_convert_atod(str, ed->all[idx].len, &mantisse, 396 if (eina_convert_atod(str, ed->all[idx].len, &mantisse,
395 &exponent) == EINA_FALSE) 397 &exponent) == EINA_FALSE)
396 { 398 {
397 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 399 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
398 return EINA_FALSE; 400 return EINA_FALSE;
399 } 401 }
400 402
401 convert->f = ldexpf((float)mantisse, exponent); 403 convert->f = ldexpf((float)mantisse, exponent);
402 } 404 }
403 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 405 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
404 406
405 convert->type |= EET_D_FLOAT; 407 convert->type |= EET_D_FLOAT;
406 } 408 }
@@ -425,7 +427,7 @@ eet_dictionary_string_get_double(const Eet_Dictionary *ed,
425 427
426 if (!(convert->type & EET_D_DOUBLE)) 428 if (!(convert->type & EET_D_DOUBLE))
427 { 429 {
428 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 430 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
429 431
430 if (!_eet_dictionary_string_get_double_cache(str, ed->all[idx].len, 432 if (!_eet_dictionary_string_get_double_cache(str, ed->all[idx].len,
431 &convert->d)) 433 &convert->d))
@@ -436,13 +438,13 @@ eet_dictionary_string_get_double(const Eet_Dictionary *ed,
436 if (eina_convert_atod(str, ed->all[idx].len, &mantisse, 438 if (eina_convert_atod(str, ed->all[idx].len, &mantisse,
437 &exponent) == EINA_FALSE) 439 &exponent) == EINA_FALSE)
438 { 440 {
439 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 441 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
440 return EINA_FALSE; 442 return EINA_FALSE;
441 } 443 }
442 444
443 convert->d = ldexp((double)mantisse, exponent); 445 convert->d = ldexp((double)mantisse, exponent);
444 } 446 }
445 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 447 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
446 448
447 convert->type |= EET_D_DOUBLE; 449 convert->type |= EET_D_DOUBLE;
448 } 450 }
@@ -469,13 +471,13 @@ eet_dictionary_string_get_fp(const Eet_Dictionary *ed,
469 { 471 {
470 Eina_F32p32 fp; 472 Eina_F32p32 fp;
471 473
472 eina_spinlock_take((Eina_Spinlock*) &ed->mutex); 474 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
473 if (!eina_convert_atofp(str, ed->all[idx].len, &fp)) 475 if (!eina_convert_atofp(str, ed->all[idx].len, &fp))
474 { 476 {
475 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 477 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
476 return EINA_FALSE; 478 return EINA_FALSE;
477 } 479 }
478 eina_spinlock_release((Eina_Spinlock*) &ed->mutex); 480 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
479 481
480 convert->fp = fp; 482 convert->fp = fp;
481 convert->type |= EET_D_FIXED_POINT; 483 convert->type |= EET_D_FIXED_POINT;
@@ -495,7 +497,7 @@ eet_dictionary_string_check(Eet_Dictionary *ed,
495 if ((!ed) || (!string)) 497 if ((!ed) || (!string))
496 return 0; 498 return 0;
497 499
498 eina_spinlock_take(&ed->mutex); 500 eina_rwlock_take_read((Eina_RWLock *)&ed->rwlock);
499 501
500 if ((ed->start <= string) && (string < ed->end)) 502 if ((ed->start <= string) && (string < ed->end))
501 res = 1; 503 res = 1;
@@ -510,7 +512,7 @@ eet_dictionary_string_check(Eet_Dictionary *ed,
510 } 512 }
511 } 513 }
512 514
513 eina_spinlock_release(&ed->mutex); 515 eina_rwlock_release((Eina_RWLock *)&ed->rwlock);
514 516
515 return res; 517 return res;
516} 518}