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;