@cryptotaxi247 / netdata-1 / commits / 55ca63b54

optimization: saved 84 bytes per dictionary, avl locking removed from tc plugin and apps.plugin (they are single threaded)

Costa Tsaousis committed May 12, 2016 at 21:09 UTC 55ca63b5467a89fad5c7fbf2862c4efb50188b1e
9 files changed +138 -236
src/appconfig.c
+11 -18
@@ -45,7 +45,7 @@ struct config {
45 char *name;
46
47 struct config_value *values;
48 - avl_tree values_index;
48 + avl_tree_lock values_index;
49
50 struct config *next;
51
@@ -64,15 +64,15 @@ static int config_value_compare(void* a, void* b) {
64 else return strcmp(((struct config_value *)a)->name, ((struct config_value *)b)->name);
65 }
66
67 -#define config_value_index_add(co, cv) avl_insert(&((co)->values_index), (avl *)(cv))
68 -#define config_value_index_del(co, cv) avl_remove(&((co)->values_index), (avl *)(cv))
67 +#define config_value_index_add(co, cv) avl_insert_lock(&((co)->values_index), (avl *)(cv))
68 +#define config_value_index_del(co, cv) avl_remove_lock(&((co)->values_index), (avl *)(cv))
69
70 static struct config_value *config_value_index_find(struct config *co, const char *name, uint32_t hash) {
71 struct config_value *result = NULL, tmp;
72 tmp.hash = (hash)?hash:simple_hash(name);
73 tmp.name = (char *)name;
74
75 - avl_search(&(co->values_index), (avl *)&tmp, config_value_iterator, (avl **)&result);
75 + avl_search_lock(&(co->values_index), (avl *) &tmp, config_value_iterator, (avl **) &result);
76 return result;
77 }
78
@@ -87,27 +87,20 @@ static int config_compare(void* a, void* b) {
87 else return strcmp(((struct config *)a)->name, ((struct config *)b)->name);
88 }
89
90 -avl_tree config_root_index = {
91 - NULL,
92 - config_compare,
93 -#ifndef AVL_WITHOUT_PTHREADS
94 -#ifdef AVL_LOCK_WITH_MUTEX
95 - PTHREAD_MUTEX_INITIALIZER
96 -#else
97 - PTHREAD_RWLOCK_INITIALIZER
98 -#endif
99 -#endif
90 +avl_tree_lock config_root_index = {
91 + { NULL, config_compare },
92 + AVL_LOCK_INITIALIZER
93 };
94
102 -#define config_index_add(cfg) avl_insert(&config_root_index, (avl *)(cfg))
103 -#define config_index_del(cfg) avl_remove(&config_root_index, (avl *)(cfg))
95 +#define config_index_add(cfg) avl_insert_lock(&config_root_index, (avl *)(cfg))
96 +#define config_index_del(cfg) avl_remove_lock(&config_root_index, (avl *)(cfg))
97
98 static struct config *config_index_find(const char *name, uint32_t hash) {
99 struct config *result = NULL, tmp;
100 tmp.hash = (hash)?hash:simple_hash(name);
101 tmp.name = (char *)name;
102
110 - avl_search(&config_root_index, (avl *)&tmp, config_iterator, (avl **)&result);
103 + avl_search_lock(&config_root_index, (avl *) &tmp, config_iterator, (avl **) &result);
104 return result;
105 }
106
@@ -155,7 +148,7 @@ struct config *config_create(const char *section)
148 co->hash = simple_hash(co->name);
149
150 pthread_rwlock_init(&co->rwlock, NULL);
158 - avl_init(&co->values_index, config_value_compare);
151 + avl_init_lock(&co->values_index, config_value_compare);
152
153 config_index_add(co);
154
src/apps_plugin.c
+2 -9
@@ -1000,14 +1000,7 @@ int file_descriptor_iterator(avl *a) { if(a) {}; return 0; }
1000
1001 avl_tree all_files_index = {
1002 NULL,
1003 - file_descriptor_compare,
1004 -#ifndef AVL_WITHOUT_PTHREADS
1005 -#ifdef AVL_LOCK_WITH_MUTEX
1006 - PTHREAD_MUTEX_INITIALIZER
1007 -#else
1008 - PTHREAD_RWLOCK_INITIALIZER
1009 -#endif
1010 -#endif /* AVL_WITHOUT_PTHREADS */
1003 + file_descriptor_compare
1004 };
1005
1006 static struct file_descriptor *file_descriptor_find(const char *name, uint32_t hash) {
@@ -1020,7 +1013,7 @@ static struct file_descriptor *file_descriptor_find(const char *name, uint32_t h
1013 tmp.magic = 0x0BADCAFE;
1014 #endif /* NETDATA_INTERNAL_CHECKS */
1015
1023 - avl_search(&all_files_index, (avl *)&tmp, file_descriptor_iterator, (avl **)&result);
1016 + avl_search(&all_files_index, (avl *) &tmp, file_descriptor_iterator, (avl **) &result);
1017 return result;
1018 }
1019
src/avl.c
+52 -92
@@ -19,9 +19,6 @@
19 #include "avl.h"
20 #include "log.h"
21
22 -/* Private methods */
23 -int _avl_removeroot(avl_tree* t);
24 -
22 /* Swing to the left
23 * Warning: no balance maintainance
24 */
@@ -69,7 +66,7 @@ void avl_nasty(avl* root) {
66 * returns 1 if the depth of the tree has grown
67 * Warning: do not insert elements already present
68 */
72 -int _avl_insert(avl_tree* t, avl* a) {
69 +int avl_insert(avl_tree* t, avl* a) {
70 /* initialize */
71 a->left = 0;
72 a->right = 0;
@@ -86,7 +83,7 @@ int _avl_insert(avl_tree* t, avl* a) {
83 avl_tree left_subtree;
84 left_subtree.root = t->root->left;
85 left_subtree.compar = t->compar;
89 - if (_avl_insert(&left_subtree, a)) {
86 + if (avl_insert(&left_subtree, a)) {
87 switch (t->root->balance--) {
88 case 1:
89 return 0;
@@ -117,7 +114,7 @@ int _avl_insert(avl_tree* t, avl* a) {
114 avl_tree right_subtree;
115 right_subtree.root = t->root->right;
116 right_subtree.compar = t->compar;
120 - if (_avl_insert(&right_subtree, a)) {
117 + if (avl_insert(&right_subtree, a)) {
118 switch (t->root->balance++) {
119 case -1:
120 return 0;
@@ -144,36 +141,16 @@ int _avl_insert(avl_tree* t, avl* a) {
141 }
142 }
143 }
147 -int avl_insert(avl_tree* t, avl* a) {
148 -#ifndef AVL_WITHOUT_PTHREADS
149 -#ifdef AVL_LOCK_WITH_MUTEX
150 - pthread_mutex_lock(&t->mutex);
151 -#else
152 - pthread_rwlock_wrlock(&t->rwlock);
153 -#endif
154 -#endif /* AVL_WITHOUT_PTHREADS */
155 -
156 - int ret = _avl_insert(t, a);
157 -
158 -#ifndef AVL_WITHOUT_PTHREADS
159 -#ifdef AVL_LOCK_WITH_MUTEX
160 - pthread_mutex_unlock(&t->mutex);
161 -#else
162 - pthread_rwlock_unlock(&t->rwlock);
163 -#endif
164 -#endif /* AVL_WITHOUT_PTHREADS */
165 - return ret;
166 -}
144
145 /* Remove an element a from the AVL tree t
146 * returns -1 if the depth of the tree has shrunk
147 * Warning: if the element is not present in the tree,
148 * returns 0 as if it had been removed succesfully.
149 */
173 -int _avl_remove(avl_tree* t, avl* a) {
150 +int avl_remove(avl_tree* t, avl* a) {
151 int b;
152 if (t->root == a)
176 - return _avl_removeroot(t);
153 + return avl_removeroot(t);
154 b = t->compar(t->root, a);
155 if (b >= 0) {
156 /* remove from the left subtree */
@@ -181,7 +158,7 @@ int _avl_remove(avl_tree* t, avl* a) {
158 avl_tree left_subtree;
159 if ((left_subtree.root = t->root->left)) {
160 left_subtree.compar = t->compar;
184 - ch = _avl_remove(&left_subtree, a);
161 + ch = avl_remove(&left_subtree, a);
162 t->root->left = left_subtree.root;
163 if (ch) {
164 switch (t->root->balance++) {
@@ -215,7 +192,7 @@ int _avl_remove(avl_tree* t, avl* a) {
192 avl_tree right_subtree;
193 if ((right_subtree.root = t->root->right)) {
194 right_subtree.compar = t->compar;
218 - ch = _avl_remove(&right_subtree, a);
195 + ch = avl_remove(&right_subtree, a);
196 t->root->right = right_subtree.root;
197 if (ch) {
198 switch (t->root->balance--) {
@@ -246,31 +223,10 @@ int _avl_remove(avl_tree* t, avl* a) {
223 return 0;
224 }
225
249 -int avl_remove(avl_tree* t, avl* a) {
250 -#ifndef AVL_WITHOUT_PTHREADS
251 -#ifdef AVL_LOCK_WITH_MUTEX
252 - pthread_mutex_lock(&t->mutex);
253 -#else
254 - pthread_rwlock_wrlock(&t->rwlock);
255 -#endif
256 -#endif /* AVL_WITHOUT_PTHREADS */
257 -
258 - int ret = _avl_remove(t, a);
259 -
260 -#ifndef AVL_WITHOUT_PTHREADS
261 -#ifdef AVL_LOCK_WITH_MUTEX
262 - pthread_mutex_unlock(&t->mutex);
263 -#else
264 - pthread_rwlock_unlock(&t->rwlock);
265 -#endif
266 -#endif /* AVL_WITHOUT_PTHREADS */
267 - return ret;
268 -}
269 -
226 /* Remove the root of the AVL tree t
227 * Warning: dumps core if t is empty
228 */
273 -int _avl_removeroot(avl_tree* t) {
229 +int avl_removeroot(avl_tree* t) {
230 int ch;
231 avl* a;
232 if (!t->root->left) {
@@ -296,7 +252,7 @@ int _avl_removeroot(avl_tree* t) {
252 while (a->left)
253 a = a->left;
254 }
299 - ch = _avl_remove(t, a);
255 + ch = avl_remove(t, a);
256 a->left = t->root->left;
257 a->right = t->root->right;
258 a->balance = t->root->balance;
@@ -306,33 +262,12 @@ int _avl_removeroot(avl_tree* t) {
262 return 0;
263 }
264
309 -int avl_removeroot(avl_tree* t) {
310 -#ifndef AVL_WITHOUT_PTHREADS
311 -#ifdef AVL_LOCK_WITH_MUTEX
312 - pthread_mutex_lock(&t->mutex);
313 -#else
314 - pthread_rwlock_wrlock(&t->rwlock);
315 -#endif
316 -#endif /* AVL_WITHOUT_PTHREADS */
317 -
318 - int ret = _avl_removeroot(t);
319 -
320 -#ifndef AVL_WITHOUT_PTHREADS
321 -#ifdef AVL_LOCK_WITH_MUTEX
322 - pthread_mutex_unlock(&t->mutex);
323 -#else
324 - pthread_rwlock_unlock(&t->rwlock);
325 -#endif
326 -#endif /* AVL_WITHOUT_PTHREADS */
327 - return ret;
328 -}
329 -
265 /* Iterate through elements in t from a range between a and b (inclusive)
266 * for each element calls iter(a) until it returns 0
267 * returns the last value returned by iterator or 0 if there were no calls
268 * Warning: a<=b must hold
269 */
335 -int _avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
270 +int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
271 int x, c = 0;
272 if (!t->root)
273 return 0;
@@ -349,7 +284,7 @@ int _avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
284 avl_tree left_subtree;
285 if ((left_subtree.root = t->root->left)) {
286 left_subtree.compar = t->compar;
352 - if (!(c = _avl_range(&left_subtree, a, b, iter, ret)))
287 + if (!(c = avl_range(&left_subtree, a, b, iter, ret)))
288 if (x > 0)
289 return 0;
290 }
@@ -366,7 +301,7 @@ int _avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
301 avl_tree right_subtree;
302 if ((right_subtree.root = t->root->right)) {
303 right_subtree.compar = t->compar;
369 - if (!(c = _avl_range(&right_subtree, a, b, iter, ret)))
304 + if (!(c = avl_range(&right_subtree, a, b, iter, ret)))
305 if (x < 0)
306 return 0;
307 }
@@ -374,7 +309,14 @@ int _avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
309 return c;
310 }
311
377 -int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
312 +void avl_init(avl_tree *t, int (*compar)(void *a, void *b)) {
313 + t->root = NULL;
314 + t->compar = compar;
315 +}
316 +
317 +/* ------------------------------------------------------------------------- */
318 +
319 +void avl_lock(avl_tree_lock *t) {
320 #ifndef AVL_WITHOUT_PTHREADS
321 #ifdef AVL_LOCK_WITH_MUTEX
322 pthread_mutex_lock(&t->mutex);
@@ -382,9 +324,9 @@ int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
324 pthread_rwlock_wrlock(&t->rwlock);
325 #endif
326 #endif /* AVL_WITHOUT_PTHREADS */
327 +}
328
386 - int ret2 = _avl_range(t, a, b, iter, ret);
387 -
329 +void avl_unlock(avl_tree_lock *t) {
330 #ifndef AVL_WITHOUT_PTHREADS
331 #ifdef AVL_LOCK_WITH_MUTEX
332 pthread_mutex_unlock(&t->mutex);
@@ -392,21 +334,12 @@ int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
334 pthread_rwlock_unlock(&t->rwlock);
335 #endif
336 #endif /* AVL_WITHOUT_PTHREADS */
395 -
396 - return ret2;
337 }
338
399 -/* Iterate through elements in t equal to a
400 - * for each element calls iter(a) until it returns 0
401 - * returns the last value returned by iterator or 0 if there were no calls
402 - */
403 -int avl_search(avl_tree* t, avl* a, int (*iter)(avl* a), avl** ret) {
404 - return avl_range(t, a, a, iter, ret);
405 -}
339 +/* ------------------------------------------------------------------------- */
340
407 -void avl_init(avl_tree* t, int (*compar)(void* a, void* b)) {
408 - t->root = NULL;
409 - t->compar = compar;
341 +void avl_init_lock(avl_tree_lock *t, int (*compar)(void *a, void *b)) {
342 + avl_init(&t->avl_tree, compar);
343
344 #ifndef AVL_WITHOUT_PTHREADS
345 int lock;
@@ -421,5 +354,32 @@ void avl_init(avl_tree* t, int (*compar)(void* a, void* b)) {
354 fatal("Failed to initialize AVL mutex/rwlock, error: %d", lock);
355
356 #endif /* AVL_WITHOUT_PTHREADS */
357 +}
358 +
359 +int avl_range_lock(avl_tree_lock *t, avl *a, avl *b, int (*iter)(avl *), avl **ret) {
360 + avl_lock(t);
361 + int ret2 = avl_range(&t->avl_tree, a, b, iter, ret);
362 + avl_unlock(t);
363 + return ret2;
364 +}
365
366 +int avl_removeroot_lock(avl_tree_lock *t) {
367 + avl_lock(t);
368 + int ret = avl_removeroot(&t->avl_tree);
369 + avl_unlock(t);
370 + return ret;
371 +}
372 +
373 +int avl_remove_lock(avl_tree_lock *t, avl *a) {
374 + avl_lock(t);
375 + int ret = avl_remove(&t->avl_tree, a);
376 + avl_unlock(t);
377 + return ret;
378 +}
379 +
380 +int avl_insert_lock(avl_tree_lock *t, avl *a) {
381 + avl_lock(t);
382 + int ret = avl_insert(&t->avl_tree, a);
383 + avl_lock(t);
384 + return ret;
385 }
src/avl.h
+31 -11
@@ -17,10 +17,19 @@
17
18 #ifndef AVL_WITHOUT_PTHREADS
19 #include <pthread.h>
20 -#endif /* AVL_WITHOUT_PTHREADS */
20
21 // #define AVL_LOCK_WITH_MUTEX 1
22
23 +#ifdef AVL_LOCK_WITH_MUTEX
24 +#define AVL_LOCK_INITIALIZER PTHREAD_MUTEX_INITIALIZER
25 +#else /* AVL_LOCK_WITH_MUTEX */
26 +#define AVL_LOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
27 +#endif /* AVL_LOCK_WITH_MUTEX */
28 +
29 +#else /* AVL_WITHOUT_PTHREADS */
30 +#define AVL_LOCK_INITIALIZER
31 +#endif /* AVL_WITHOUT_PTHREADS */
32 +
33 /* Data structures */
34
35 /* One element of the AVL tree */
@@ -32,8 +41,13 @@ typedef struct avl {
41
42 /* An AVL tree */
43 typedef struct avl_tree {
35 - avl* root;
36 - int (*compar)(void* a, void* b);
44 + avl *root;
45 +
46 + int (*compar)(void *a, void *b);
47 +} avl_tree;
48 +
49 +typedef struct avl_tree_lock {
50 + avl_tree avl_tree;
51
52 #ifndef AVL_WITHOUT_PTHREADS
53 #ifdef AVL_LOCK_WITH_MUTEX
@@ -42,7 +56,7 @@ typedef struct avl_tree {
56 pthread_rwlock_t rwlock;
57 #endif /* AVL_LOCK_WITH_MUTEX */
58 #endif /* AVL_WITHOUT_PTHREADS */
45 -} avl_tree;
59 +} avl_tree_lock;
60
61 /* Public methods */
62
@@ -50,35 +64,41 @@ typedef struct avl_tree {
64 * returns 1 if the depth of the tree has grown
65 * Warning: do not insert elements already present
66 */
53 -int avl_insert(avl_tree* t, avl* a);
67 +int avl_insert_lock(avl_tree_lock *t, avl *a);
68 +int avl_insert(avl_tree *t, avl *a);
69
70 /* Remove an element a from the AVL tree t
71 * returns -1 if the depth of the tree has shrunk
72 * Warning: if the element is not present in the tree,
73 * returns 0 as if it had been removed succesfully.
74 */
60 -int avl_remove(avl_tree* t, avl* a);
75 +int avl_remove_lock(avl_tree_lock *t, avl *a);
76 +int avl_remove(avl_tree *t, avl *a);
77
78 /* Remove the root of the AVL tree t
79 * Warning: dumps core if t is empty
80 */
65 -int avl_removeroot(avl_tree* t);
81 +int avl_removeroot_lock(avl_tree_lock *t);
82 +int avl_removeroot(avl_tree *t);
83
84 /* Iterate through elements in t from a range between a and b (inclusive)
85 * for each element calls iter(a) until it returns 0
86 * returns the last value returned by iterator or 0 if there were no calls
87 * Warning: a<=b must hold
88 */
72 -int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret);
89 +int avl_range_lock(avl_tree_lock *t, avl *a, avl *b, int (*iter)(avl *), avl **ret);
90 +int avl_range(avl_tree *t, avl *a, avl *b, int (*iter)(avl *), avl **ret);
91
92 /* Iterate through elements in t equal to a
93 * for each element calls iter(a) until it returns 0
94 * returns the last value returned by iterator or 0 if there were no calls
95 */
78 -int avl_search(avl_tree* t, avl* a, int (*iter)(avl*), avl** ret);
96 +#define avl_search_lock(t, a, iter, ret) avl_range_lock(t, a, a, iter, ret)
97 +#define avl_search(t, a, iter, ret) avl_range(t, a, a, iter, ret)
98
80 -/* Initialize the avl_tree
99 +/* Initialize the avl_tree_lock
100 */
82 -void avl_init(avl_tree* t, int (*compar)(void* a, void* b));
101 +void avl_init_lock(avl_tree_lock *t, int (*compar)(void *a, void *b));
102 +void avl_init(avl_tree *t, int (*compar)(void *a, void *b));
103
104 #endif /* avl.h */
src/dictionary.c
+5 -35
@@ -15,20 +15,6 @@
15 // ----------------------------------------------------------------------------
16 // dictionary locks
17
18 -static inline void dictionary_atomic_updates_lock(DICTIONARY *dict) {
19 - if(likely(!(dict->flags & DICTIONARY_FLAG_SINGLE_THREADED))) {
20 - // debug(D_DICTIONARY, "Dictionary ATOMIC lock");
21 - pthread_mutex_lock(&dict->atomic_mutex);
22 - }
23 -}
24 -
25 -static inline void dictionary_atomic_updates_unlock(DICTIONARY *dict) {
26 - if(likely(!(dict->flags & DICTIONARY_FLAG_SINGLE_THREADED))) {
27 - // debug(D_DICTIONARY, "Dictionary ATOMIC unlock");
28 - pthread_mutex_unlock(&dict->atomic_mutex);
29 - }
30 -}
31 -
18 static inline void dictionary_read_lock(DICTIONARY *dict) {
19 if(likely(!(dict->flags & DICTIONARY_FLAG_SINGLE_THREADED))) {
20 // debug(D_DICTIONARY, "Dictionary READ lock");
@@ -71,7 +57,7 @@ static inline NAME_VALUE *dictionary_name_value_index_find_nolock(DICTIONARY *di
57 tmp.name = (char *)name;
58
59 dict->searches++;
74 - avl_search(&(dict->values_index), (avl *)&tmp, name_value_iterator, (avl **)&result);
60 + avl_search(&(dict->values_index), (avl *) &tmp, name_value_iterator, (avl **) &result);
61
62 return result;
63 }
@@ -143,7 +129,6 @@ DICTIONARY *dictionary_create(uint32_t flags) {
129
130 avl_init(&dict->values_index, name_value_compare);
131 pthread_rwlock_init(&dict->rwlock, NULL);
146 - pthread_mutex_init(&dict->atomic_mutex, NULL);
132
133 dict->flags = flags;
134
@@ -153,8 +138,6 @@ DICTIONARY *dictionary_create(uint32_t flags) {
138 void dictionary_destroy(DICTIONARY *dict) {
139 debug(D_DICTIONARY, "Destroying dictionary.");
140
156 - dictionary_atomic_updates_lock(dict);
157 -
141 dictionary_write_lock(dict);
142
143 while(dict->values_index.root)
@@ -162,8 +145,6 @@ void dictionary_destroy(DICTIONARY *dict) {
145
146 dictionary_unlock(dict);
147
165 - dictionary_atomic_updates_unlock(dict);
166 -
148 free(dict);
149 }
150
@@ -174,19 +155,13 @@ void *dictionary_set(DICTIONARY *dict, const char *name, void *value, size_t val
155
156 uint32_t hash = simple_hash(name);
157
177 - dictionary_atomic_updates_lock(dict);
158 + dictionary_write_lock(dict);
159
179 - dictionary_read_lock(dict);
160 NAME_VALUE *nv = dictionary_name_value_index_find_nolock(dict, name, hash);
181 - dictionary_unlock(dict);
182 -
161 if(unlikely(!nv)) {
162 debug(D_DICTIONARY, "Dictionary entry with name '%s' not found. Creating a new one.", name);
163
186 - dictionary_write_lock(dict);
164 nv = dictionary_name_value_create_nolock(dict, name, value, value_len, hash);
188 - dictionary_unlock(dict);
189 -
165 if(unlikely(!nv))
166 fatal("Cannot create name_value.");
167 }
@@ -214,7 +189,7 @@ void *dictionary_set(DICTIONARY *dict, const char *name, void *value, size_t val
189 }
190 }
191
217 - dictionary_atomic_updates_unlock(dict);
192 + dictionary_unlock(dict);
193
194 return nv->value;
195 }
@@ -240,25 +215,20 @@ int dictionary_del(DICTIONARY *dict, const char *name) {
215
216 debug(D_DICTIONARY, "DEL dictionary entry with name '%s'.", name);
217
243 - dictionary_atomic_updates_lock(dict);
218 + dictionary_write_lock(dict);
219
245 - dictionary_read_lock(dict);
220 NAME_VALUE *nv = dictionary_name_value_index_find_nolock(dict, name, 0);
247 - dictionary_unlock(dict);
248 -
221 if(unlikely(!nv)) {
222 debug(D_DICTIONARY, "Not found dictionary entry with name '%s'.", name);
223 ret = -1;
224 }
225 else {
226 debug(D_DICTIONARY, "Found dictionary entry with name '%s'.", name);
255 - dictionary_write_lock(dict);
227 dictionary_name_value_destroy_nolock(dict, nv);
257 - dictionary_unlock(dict);
228 ret = 0;
229 }
230
261 - dictionary_atomic_updates_unlock(dict);
231 + dictionary_unlock(dict);
232
233 return ret;
234 }
src/dictionary.h
+3 -3
@@ -17,16 +17,16 @@ typedef struct name_value {
17 } NAME_VALUE;
18
19 typedef struct dictionary {
20 - uint32_t flags;
20 + avl_tree values_index;
21 +
22 + uint8_t flags;
23
24 unsigned long long inserts;
25 unsigned long long deletes;
26 unsigned long long searches;
27 unsigned long long entries;
28
27 - avl_tree values_index;
29 pthread_rwlock_t rwlock;
29 - pthread_mutex_t atomic_mutex;
30 } DICTIONARY;
31
32 #define DICTIONARY_FLAG_DEFAULT 0x00000000
src/plugin_tc.c
+17 -37
@@ -93,25 +93,18 @@ static int tc_device_compare(void* a, void* b) {
93
94 avl_tree tc_device_root_index = {
95 NULL,
96 - tc_device_compare,
97 -#ifndef AVL_WITHOUT_PTHREADS
98 -#ifdef AVL_LOCK_WITH_MUTEX
99 - PTHREAD_MUTEX_INITIALIZER
100 -#else
101 - PTHREAD_RWLOCK_INITIALIZER
102 -#endif
103 -#endif
96 + tc_device_compare
97 };
98
99 #define tc_device_index_add(st) avl_insert(&tc_device_root_index, (avl *)(st))
100 #define tc_device_index_del(st) avl_remove(&tc_device_root_index, (avl *)(st))
101
109 -static struct tc_device *tc_device_index_find(const char *id, uint32_t hash) {
102 +static inline struct tc_device *tc_device_index_find(const char *id, uint32_t hash) {
103 struct tc_device *result = NULL, tmp;
104 tmp.id = (char *)id;
105 tmp.hash = (hash)?hash:simple_hash(tmp.id);
106
114 - avl_search(&(tc_device_root_index), (avl *)&tmp, tc_device_iterator, (avl **)&result);
107 + avl_search(&(tc_device_root_index), (avl *) &tmp, tc_device_iterator, (avl **) &result);
108 return result;
109 }
110
@@ -130,18 +123,18 @@ static int tc_class_compare(void* a, void* b) {
123 #define tc_class_index_add(st, rd) avl_insert(&((st)->classes_index), (avl *)(rd))
124 #define tc_class_index_del(st, rd) avl_remove(&((st)->classes_index), (avl *)(rd))
125
133 -static struct tc_class *tc_class_index_find(struct tc_device *st, const char *id, uint32_t hash) {
126 +static inline struct tc_class *tc_class_index_find(struct tc_device *st, const char *id, uint32_t hash) {
127 struct tc_class *result = NULL, tmp;
128 tmp.id = (char *)id;
129 tmp.hash = (hash)?hash:simple_hash(tmp.id);
130
138 - avl_search(&(st->classes_index), (avl *)&tmp, tc_class_iterator, (avl **)&result);
131 + avl_search(&(st->classes_index), (avl *) &tmp, tc_class_iterator, (avl **) &result);
132 return result;
133 }
134
135 // ----------------------------------------------------------------------------
136
144 -static void tc_class_free(struct tc_device *n, struct tc_class *c) {
137 +static inline void tc_class_free(struct tc_device *n, struct tc_class *c) {
138 debug(D_TC_LOOP, "Removing from device '%s' class '%s', parentid '%s', leafid '%s', seen=%d", n->id, c->id, c->parentid?c->parentid:"", c->leafid?c->leafid:"", c->seen);
139
140 if(c->next) c->next->prev = c->prev;
@@ -161,7 +154,7 @@ static void tc_class_free(struct tc_device *n, struct tc_class *c) {
154 free(c);
155 }
156
164 -static void tc_device_classes_cleanup(struct tc_device *d) {
157 +static inline void tc_device_classes_cleanup(struct tc_device *d) {
158 static int cleanup_every = 999;
159
160 if(cleanup_every > 0) {
@@ -186,7 +179,7 @@ static void tc_device_classes_cleanup(struct tc_device *d) {
179 }
180 }
181
189 -static void tc_device_commit(struct tc_device *d)
182 +static inline void tc_device_commit(struct tc_device *d)
183 {
184 static int enable_new_interfaces = -1;
185
@@ -296,7 +289,7 @@ static void tc_device_commit(struct tc_device *d)
289 tc_device_classes_cleanup(d);
290 }
291
299 -static void tc_device_set_class_name(struct tc_device *d, char *id, char *name)
292 +static inline void tc_device_set_class_name(struct tc_device *d, char *id, char *name)
293 {
294 struct tc_class *c = tc_class_index_find(d, id, 0);
295 if(c) {
@@ -310,7 +303,7 @@ static void tc_device_set_class_name(struct tc_device *d, char *id, char *name)
303 }
304 }
305
313 -static void tc_device_set_device_name(struct tc_device *d, char *name) {
306 +static inline void tc_device_set_device_name(struct tc_device *d, char *name) {
307 if(d->name) free(d->name);
308 d->name = NULL;
309
@@ -320,7 +313,7 @@ static void tc_device_set_device_name(struct tc_device *d, char *name) {
313 }
314 }
315
323 -static void tc_device_set_device_family(struct tc_device *d, char *family) {
316 +static inline void tc_device_set_device_family(struct tc_device *d, char *family) {
317 if(d->family) free(d->family);
318 d->family = NULL;
319
@@ -331,7 +324,7 @@ static void tc_device_set_device_family(struct tc_device *d, char *family) {
324 // no need for null termination - it is already null
325 }
326
334 -static struct tc_device *tc_device_create(char *id)
327 +static inline struct tc_device *tc_device_create(char *id)
328 {
329 struct tc_device *d = tc_device_index_find(id, 0);
330
@@ -347,20 +340,7 @@ static struct tc_device *tc_device_create(char *id)
340 d->id = strdup(id);
341 d->hash = simple_hash(d->id);
342
350 - d->classes_index.root = NULL;
351 - d->classes_index.compar = tc_class_compare;
352 -
353 - int lock;
354 -#ifndef AVL_WITHOUT_PTHREADS
355 -#ifdef AVL_LOCK_WITH_MUTEX
356 - lock = pthread_mutex_init(&d->classes_index.mutex, NULL);
357 -#else
358 - lock = pthread_rwlock_init(&d->classes_index.rwlock, NULL);
359 -#endif
360 -#endif
361 - if(lock != 0)
362 - fatal("Failed to initialize plugin_tc mutex/rwlock, return code %d.", lock);
363 -
343 + avl_init(&d->classes_index, tc_class_compare);
344 tc_device_index_add(d);
345
346 if(!tc_device_root) {
@@ -376,7 +356,7 @@ static struct tc_device *tc_device_create(char *id)
356 return(d);
357 }
358
379 -static struct tc_class *tc_class_add(struct tc_device *n, char *id, char *parentid, char *leafid)
359 +static inline struct tc_class *tc_class_add(struct tc_device *n, char *id, char *parentid, char *leafid)
360 {
361 struct tc_class *c = tc_class_index_find(n, id, 0);
362
@@ -418,7 +398,7 @@ static struct tc_class *tc_class_add(struct tc_device *n, char *id, char *parent
398 return(c);
399 }
400
421 -static void tc_device_free(struct tc_device *n)
401 +static inline void tc_device_free(struct tc_device *n)
402 {
403 if(n->next) n->next->prev = n->prev;
404 if(n->prev) n->prev->next = n->next;
@@ -438,7 +418,7 @@ static void tc_device_free(struct tc_device *n)
418 free(n);
419 }
420
441 -static void tc_device_free_all()
421 +static inline void tc_device_free_all()
422 {
423 while(tc_device_root)
424 tc_device_free(tc_device_root);
@@ -459,7 +439,7 @@ static inline int tc_space(char c) {
439 }
440 }
441
462 -static void tc_split_words(char *str, char **words, int max_words) {
442 +static inline void tc_split_words(char *str, char **words, int max_words) {
443 char *s = str;
444 int i = 0;
445
src/rrd.c
+16 -30
@@ -50,20 +50,13 @@ static int rrdset_compare(void* a, void* b) {
50 else return strcmp(((RRDSET *)a)->id, ((RRDSET *)b)->id);
51 }
52
53 -avl_tree rrdset_root_index = {
54 - NULL,
55 - rrdset_compare,
56 -#ifndef AVL_WITHOUT_PTHREADS
57 -#ifdef AVL_LOCK_WITH_MUTEX
58 - PTHREAD_MUTEX_INITIALIZER
59 -#else
60 - PTHREAD_RWLOCK_INITIALIZER
61 -#endif
62 -#endif
53 +avl_tree_lock rrdset_root_index = {
54 + { NULL, rrdset_compare },
55 + AVL_LOCK_INITIALIZER
56 };
57
65 -#define rrdset_index_add(st) avl_insert(&rrdset_root_index, (avl *)(st))
66 -#define rrdset_index_del(st) avl_remove(&rrdset_root_index, (avl *)(st))
58 +#define rrdset_index_add(st) avl_insert_lock(&rrdset_root_index, (avl *)(st))
59 +#define rrdset_index_del(st) avl_remove_lock(&rrdset_root_index, (avl *)(st))
60
61 static RRDSET *rrdset_index_find(const char *id, uint32_t hash) {
62 RRDSET *result = NULL, tmp;
@@ -71,7 +64,7 @@ static RRDSET *rrdset_index_find(const char *id, uint32_t hash) {
64 tmp.id[RRD_ID_LENGTH_MAX] = '\0';
65 tmp.hash = (hash)?hash:simple_hash(tmp.id);
66
74 - avl_search(&(rrdset_root_index), (avl *)&tmp, rrdset_iterator, (avl **)&result);
67 + avl_search_lock(&(rrdset_root_index), (avl *) &tmp, rrdset_iterator, (avl **) &result);
68 return result;
69 }
70
@@ -93,24 +86,17 @@ static int rrdset_compare_name(void* a, void* b) {
86 else return strcmp(A->name, B->name);
87 }
88
96 -avl_tree rrdset_root_index_name = {
97 - NULL,
98 - rrdset_compare_name,
99 -#ifndef AVL_WITHOUT_PTHREADS
100 -#ifdef AVL_LOCK_WITH_MUTEX
101 - PTHREAD_MUTEX_INITIALIZER
102 -#else
103 - PTHREAD_RWLOCK_INITIALIZER
104 -#endif
105 -#endif
89 +avl_tree_lock rrdset_root_index_name = {
90 + { NULL, rrdset_compare_name },
91 + AVL_LOCK_INITIALIZER
92 };
93
94 int rrdset_index_add_name(RRDSET *st) {
95 // fprintf(stderr, "ADDING: %s (name: %s)\n", st->id, st->name);
110 - return avl_insert(&rrdset_root_index_name, (avl *)(&st->avlname));
96 + return avl_insert_lock(&rrdset_root_index_name, (avl *) (&st->avlname));
97 }
98
113 -#define rrdset_index_del_name(st) avl_remove(&rrdset_root_index_name, (avl *)(&st->avlname))
99 +#define rrdset_index_del_name(st) avl_remove_lock(&rrdset_root_index_name, (avl *)(&st->avlname))
100
101 static RRDSET *rrdset_index_find_name(const char *name, uint32_t hash) {
102 void *result = NULL;
@@ -119,7 +105,7 @@ static RRDSET *rrdset_index_find_name(const char *name, uint32_t hash) {
105 tmp.hash_name = (hash)?hash:simple_hash(tmp.name);
106
107 // fprintf(stderr, "SEARCHING: %s\n", name);
122 - avl_search(&(rrdset_root_index_name), (avl *)(&(tmp.avlname)), rrdset_iterator_name, (avl **)&result);
108 + avl_search_lock(&(rrdset_root_index_name), (avl *) (&(tmp.avlname)), rrdset_iterator_name, (avl **) &result);
109 if(result) {
110 RRDSET *st = rrdset_from_avlname(result);
111 if(strcmp(st->magic, RRDSET_MAGIC))
@@ -144,8 +130,8 @@ static int rrddim_compare(void* a, void* b) {
130 else return strcmp(((RRDDIM *)a)->id, ((RRDDIM *)b)->id);
131 }
132
147 -#define rrddim_index_add(st, rd) avl_insert(&((st)->dimensions_index), (avl *)(rd))
148 -#define rrddim_index_del(st,rd ) avl_remove(&((st)->dimensions_index), (avl *)(rd))
133 +#define rrddim_index_add(st, rd) avl_insert_lock(&((st)->dimensions_index), (avl *)(rd))
134 +#define rrddim_index_del(st,rd ) avl_remove_lock(&((st)->dimensions_index), (avl *)(rd))
135
136 static RRDDIM *rrddim_index_find(RRDSET *st, const char *id, uint32_t hash) {
137 RRDDIM *result = NULL, tmp;
@@ -153,7 +139,7 @@ static RRDDIM *rrddim_index_find(RRDSET *st, const char *id, uint32_t hash) {
139 tmp.id[RRD_ID_LENGTH_MAX] = '\0';
140 tmp.hash = (hash)?hash:simple_hash(tmp.id);
141
156 - avl_search(&(st->dimensions_index), (avl *)&tmp, rrddim_iterator, (avl **)&result);
142 + avl_search_lock(&(st->dimensions_index), (avl *) &tmp, rrddim_iterator, (avl **) &result);
143 return result;
144 }
145
@@ -457,7 +443,7 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
443 st->gap_when_lost_iterations_above = (int) (
444 config_get_number(st->id, "gap when lost iterations above", RRD_DEFAULT_GAP_INTERPOLATIONS) + 2);
445
460 - avl_init(&st->dimensions_index, rrddim_compare);
446 + avl_init_lock(&st->dimensions_index, rrddim_compare);
447
448 pthread_rwlock_init(&st->rwlock, NULL);
449 pthread_rwlock_wrlock(&rrdset_root_rwlock);
src/rrd.h
+1 -1
@@ -246,7 +246,7 @@ struct rrdset {
246 // ------------------------------------------------------------------------
247 // the dimensions
248
249 - avl_tree dimensions_index; // the root of the dimensions index
249 + avl_tree_lock dimensions_index; // the root of the dimensions index
250 RRDDIM *dimensions; // the actual data for every dimension
251 };
252 typedef struct rrdset RRDSET;