From: Costa Tsaousis (ktsaou) Date: Sun, 12 Mar 2017 14:54:07 +0000 (+0200) Subject: locks abstraction, error reporting, debugging X-Git-Tag: ab-debian_0.20170316.01-0ab1~1^2~8^2 X-Git-Url: https://arthur.barton.de/gitweb/?a=commitdiff_plain;h=68c6d537788b9c11670903bce2e9806933a3322a;hp=1b9e70dfd788fa42ec69ee254f05c8965fa3612f;p=netdata.git locks abstraction, error reporting, debugging --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 705077f9..d848c5c8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,7 +144,7 @@ set(NETDATA_SOURCE_FILES src/web_client.h src/web_server.c src/web_server.h - ) + src/locks.h) set(APPS_PLUGIN_SOURCE_FILES src/appconfig.c diff --git a/src/Makefile.am b/src/Makefile.am index 5f907893..1c1dd338 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,74 +38,120 @@ plugins_PROGRAMS += freeipmi.plugin endif netdata_SOURCES = \ - appconfig.c appconfig.h \ - adaptive_resortable_list.c adaptive_resortable_list.h \ - avl.c avl.h \ - backends.c backends.h \ - clocks.c clocks.h \ - common.c common.h \ - daemon.c daemon.h \ - dictionary.c dictionary.h \ - eval.c eval.h \ - global_statistics.c global_statistics.h \ - health.c health.h health_log.c health_config.c health_json.c \ + adaptive_resortable_list.c \ + adaptive_resortable_list.h \ + appconfig.c \ + appconfig.h \ + avl.c \ + avl.h \ + backends.c \ + backends.h \ + clocks.c \ + clocks.h \ + common.c \ + common.h \ + daemon.c \ + daemon.h \ + dictionary.c \ + dictionary.h \ + eval.c \ + eval.h \ + global_statistics.c \ + global_statistics.h \ + health.c \ + health.h \ + health_config.c \ + health_json.c \ + health_log.c \ inlined.h \ - log.c log.h \ - main.c main.h \ - plugin_checks.c plugin_checks.h \ - plugin_idlejitter.c plugin_idlejitter.h \ - plugin_nfacct.c plugin_nfacct.h \ - plugin_tc.c plugin_tc.h \ - plugins_d.c plugins_d.h \ - popen.c popen.h \ - socket.c socket.h \ - simple_pattern.c simple_pattern.h \ - sys_fs_cgroup.c \ - sys_devices_system_edac_mc.c \ - sys_devices_system_node.c \ - procfile.c procfile.h \ - proc_self_mountinfo.c proc_self_mountinfo.h \ - registry.c registry.h \ - registry_internals.c registry_internals.h \ - registry_url.c registry_url.h \ - registry_person.c registry_person.h \ - registry_machine.c registry_machine.h \ - registry_init.c \ + locks.h \ + log.c \ + log.h \ + main.c \ + main.h \ + plugin_checks.c \ + plugin_checks.h \ + plugin_idlejitter.c \ + plugin_idlejitter.h \ + plugin_nfacct.c \ + plugin_nfacct.h \ + plugin_tc.c \ + plugin_tc.h \ + plugins_d.c \ + plugins_d.h \ + popen.c \ + popen.h \ + proc_self_mountinfo.c \ + proc_self_mountinfo.h \ + procfile.c \ + procfile.h \ + registry.c \ + registry.h \ registry_db.c \ + registry_init.c \ + registry_internals.c \ + registry_internals.h \ registry_log.c \ - rrd.c rrd.h \ + registry_machine.c \ + registry_machine.h \ + registry_person.c \ + registry_person.h \ + registry_url.c \ + registry_url.h \ + rrd.c \ + rrd.h \ + rrd2json.c \ + rrd2json.h \ + rrd2json_api_old.c \ + rrd2json_api_old.h \ + rrdcalc.c \ + rrdcalctemplate.c \ rrddim.c \ + rrddimvar.c \ rrdfamily.c \ rrdhost.c \ + rrdpush.c \ + rrdpush.h \ rrdset.c \ - rrdcalc.c \ - rrdcalctemplate.c \ - rrdvar.c \ - rrddimvar.c \ rrdsetvar.c \ - rrd2json.c rrd2json.h \ - rrd2json_api_old.c rrd2json_api_old.h \ - rrdpush.c rrdpush.h \ - storage_number.c storage_number.h \ - unit_test.c unit_test.h \ + rrdvar.c \ + simple_pattern.c \ + simple_pattern.h \ + socket.c \ + socket.h \ + storage_number.c \ + storage_number.h \ + sys_devices_system_edac_mc.c \ + sys_devices_system_node.c \ + sys_fs_cgroup.c \ + unit_test.c \ + unit_test.h \ url.c url.h \ - web_api_old.c web_api_old.h \ - web_api_v1.c web_api_v1.h \ - web_buffer.c web_buffer.h \ - web_buffer_svg.c web_buffer_svg.h \ - web_client.c web_client.h \ - web_server.c web_server.h \ + web_api_old.c \ + web_api_old.h \ + web_api_v1.c \ + web_api_v1.h \ + web_buffer.c \ + web_buffer.h \ + web_buffer_svg.c \ + web_buffer_svg.h \ + web_client.c \ + web_client.h \ + web_server.c \ + web_server.h \ $(NULL) if FREEBSD netdata_SOURCES += \ - plugin_freebsd.c plugin_freebsd.h \ + plugin_freebsd.c \ + plugin_freebsd.h \ freebsd_sysctl.c \ $(NULL) else if MACOS netdata_SOURCES += \ - plugin_macos.c plugin_macos.h \ + plugin_macos.c \ + plugin_macos.h \ macos_sysctl.c \ macos_mach_smi.c \ macos_fw.c \ @@ -113,8 +159,10 @@ netdata_SOURCES += \ else netdata_SOURCES += \ ipc.c ipc.h \ - plugin_proc.c plugin_proc.h \ - plugin_proc_diskspace.c plugin_proc_diskspace.h \ + plugin_proc.c \ + plugin_proc.h \ + plugin_proc_diskspace.c \ + plugin_proc_diskspace.h \ proc_diskstats.c \ proc_interrupts.c \ proc_softirqs.c \ diff --git a/src/appconfig.c b/src/appconfig.c index 50e4c31f..71ff4b75 100644 --- a/src/appconfig.c +++ b/src/appconfig.c @@ -36,7 +36,7 @@ struct section { struct config_option *values; avl_tree_lock values_index; - pthread_mutex_t mutex; // this locks only the writers, to ensure atomic updates + netdata_mutex_t mutex; // this locks only the writers, to ensure atomic updates // readers are protected using the rwlock in avl_tree_lock }; @@ -44,7 +44,7 @@ static int appconfig_section_compare(void *a, void *b); struct config netdata_config = { .sections = NULL, - .mutex = PTHREAD_MUTEX_INITIALIZER, + .mutex = NETDATA_MUTEX_INITIALIZER, .index = { { NULL, appconfig_section_compare }, AVL_LOCK_INITIALIZER @@ -53,7 +53,7 @@ struct config netdata_config = { struct config stream_config = { .sections = NULL, - .mutex = PTHREAD_MUTEX_INITIALIZER, + .mutex = NETDATA_MUTEX_INITIALIZER, .index = { { NULL, appconfig_section_compare }, AVL_LOCK_INITIALIZER @@ -64,19 +64,19 @@ struct config stream_config = { // locking static inline void appconfig_wrlock(struct config *root) { - pthread_mutex_lock(&root->mutex); + netdata_mutex_lock(&root->mutex); } static inline void appconfig_unlock(struct config *root) { - pthread_mutex_unlock(&root->mutex); + netdata_mutex_unlock(&root->mutex); } static inline void config_section_wrlock(struct section *co) { - pthread_mutex_lock(&co->mutex); + netdata_mutex_lock(&co->mutex); } static inline void config_section_unlock(struct section *co) { - pthread_mutex_unlock(&co->mutex); + netdata_mutex_unlock(&co->mutex); } diff --git a/src/appconfig.h b/src/appconfig.h index 15bba807..45cc8cfd 100644 --- a/src/appconfig.h +++ b/src/appconfig.h @@ -18,7 +18,7 @@ struct config { struct section *sections; - pthread_mutex_t mutex; + netdata_mutex_t mutex; avl_tree_lock index; }; diff --git a/src/avl.c b/src/avl.c index f6a99788..0ea119a7 100644 --- a/src/avl.c +++ b/src/avl.c @@ -315,11 +315,9 @@ int avl_traverse(avl_tree *t, int (*callback)(void *entry, void *data), void *da void avl_read_lock(avl_tree_lock *t) { #ifndef AVL_WITHOUT_PTHREADS #ifdef AVL_LOCK_WITH_MUTEX - if(unlikely(pthread_mutex_lock(&t->mutex) != 0)) - error("Cannot get mutex of an AVL"); + netdata_mutex_lock(&t->mutex); #else - if(unlikely(pthread_rwlock_rdlock(&t->rwlock) != 0)) - error("Cannot get read lock of an AVL"); + netdata_rwlock_rdlock(&t->rwlock); #endif #endif /* AVL_WITHOUT_PTHREADS */ } @@ -327,11 +325,9 @@ void avl_read_lock(avl_tree_lock *t) { void avl_write_lock(avl_tree_lock *t) { #ifndef AVL_WITHOUT_PTHREADS #ifdef AVL_LOCK_WITH_MUTEX - if(unlikely(pthread_mutex_lock(&t->mutex) != 0) - error("Cannot get mutex of an AVL"); + netdata_mutex_lock(&t->mutex); #else - if(unlikely(pthread_rwlock_wrlock(&t->rwlock) != 0)) - error("Cannot write lock an AVL."); + netdata_rwlock_wrlock(&t->rwlock); #endif #endif /* AVL_WITHOUT_PTHREADS */ } @@ -339,11 +335,9 @@ void avl_write_lock(avl_tree_lock *t) { void avl_unlock(avl_tree_lock *t) { #ifndef AVL_WITHOUT_PTHREADS #ifdef AVL_LOCK_WITH_MUTEX - if(unlikely(pthread_mutex_unlock(&t->mutex) != 0)) - error("Cannot unlock mutex of an AVL"); + netdata_mutex_unlock(&t->mutex); #else - if(unlikely(pthread_rwlock_unlock(&t->rwlock) != 0)) - error("Cannot unlock an AVL"); + netdata_rwlock_unlock(&t->rwlock); #endif #endif /* AVL_WITHOUT_PTHREADS */ } @@ -358,9 +352,9 @@ void avl_init_lock(avl_tree_lock *t, int (*compar)(void *a, void *b)) { int lock; #ifdef AVL_LOCK_WITH_MUTEX - lock = pthread_mutex_init(&t->mutex, NULL); + lock = netdata_mutex_init(&t->mutex, NULL); #else - lock = pthread_rwlock_init(&t->rwlock, NULL); + lock = netdata_rwlock_init(&t->rwlock); #endif if(lock != 0) diff --git a/src/avl.h b/src/avl.h index d30be0dd..19648cd1 100644 --- a/src/avl.h +++ b/src/avl.h @@ -13,9 +13,9 @@ // #define AVL_LOCK_WITH_MUTEX 1 #ifdef AVL_LOCK_WITH_MUTEX -#define AVL_LOCK_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define AVL_LOCK_INITIALIZER NETDATA_MUTEX_INITIALIZER #else /* AVL_LOCK_WITH_MUTEX */ -#define AVL_LOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER +#define AVL_LOCK_INITIALIZER NETDATA_RWLOCK_INITIALIZER #endif /* AVL_LOCK_WITH_MUTEX */ #else /* AVL_WITHOUT_PTHREADS */ @@ -41,9 +41,9 @@ typedef struct avl_tree_lock { #ifndef AVL_WITHOUT_PTHREADS #ifdef AVL_LOCK_WITH_MUTEX - pthread_mutex_t mutex; + netdata_mutex_t mutex; #else /* AVL_LOCK_WITH_MUTEX */ - pthread_rwlock_t rwlock; + netdata_rwlock_t rwlock; #endif /* AVL_LOCK_WITH_MUTEX */ #endif /* AVL_WITHOUT_PTHREADS */ } avl_tree_lock; diff --git a/src/common.h b/src/common.h index f53cc557..f2c764b5 100644 --- a/src/common.h +++ b/src/common.h @@ -168,10 +168,11 @@ // ---------------------------------------------------------------------------- // netdata include files -#include "simple_pattern.h" -#include "avl.h" #include "clocks.h" #include "log.h" +#include "locks.h" +#include "simple_pattern.h" +#include "avl.h" #include "global_statistics.h" #include "storage_number.h" #include "web_buffer.h" diff --git a/src/dictionary.c b/src/dictionary.c index fb9efeed..512b4bbe 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -31,21 +31,21 @@ static inline void NETDATA_DICTIONARY_STATS_ENTRIES_MINUS1(DICTIONARY *dict) { static inline void dictionary_read_lock(DICTIONARY *dict) { if(likely(dict->rwlock)) { // debug(D_DICTIONARY, "Dictionary READ lock"); - pthread_rwlock_rdlock(dict->rwlock); + netdata_rwlock_rdlock(dict->rwlock); } } static inline void dictionary_write_lock(DICTIONARY *dict) { if(likely(dict->rwlock)) { // debug(D_DICTIONARY, "Dictionary WRITE lock"); - pthread_rwlock_wrlock(dict->rwlock); + netdata_rwlock_wrlock(dict->rwlock); } } static inline void dictionary_unlock(DICTIONARY *dict) { if(likely(dict->rwlock)) { // debug(D_DICTIONARY, "Dictionary UNLOCK lock"); - pthread_rwlock_unlock(dict->rwlock); + netdata_rwlock_unlock(dict->rwlock); } } @@ -135,8 +135,8 @@ DICTIONARY *dictionary_create(uint8_t flags) { dict->stats = callocz(1, sizeof(struct dictionary_stats)); if(!(flags & DICTIONARY_FLAG_SINGLE_THREADED)) { - dict->rwlock = callocz(1, sizeof(pthread_rwlock_t)); - pthread_rwlock_init(dict->rwlock, NULL); + dict->rwlock = callocz(1, sizeof(netdata_rwlock_t)); + netdata_rwlock_init(dict->rwlock); } avl_init(&dict->values_index, name_value_compare); @@ -158,8 +158,10 @@ void dictionary_destroy(DICTIONARY *dict) { if(dict->stats) freez(dict->stats); - if(dict->rwlock) + if(dict->rwlock) { + netdata_rwlock_destroy(dict->rwlock); freez(dict->rwlock); + } freez(dict); } diff --git a/src/dictionary.h b/src/dictionary.h index 6bebbfa8..f028dbb3 100644 --- a/src/dictionary.h +++ b/src/dictionary.h @@ -24,7 +24,7 @@ typedef struct dictionary { uint8_t flags; struct dictionary_stats *stats; - pthread_rwlock_t *rwlock; + netdata_rwlock_t *rwlock; } DICTIONARY; #define DICTIONARY_FLAG_DEFAULT 0x00000000 diff --git a/src/global_statistics.c b/src/global_statistics.c index c3d63043..2ccdf680 100644 --- a/src/global_statistics.c +++ b/src/global_statistics.c @@ -10,14 +10,14 @@ volatile struct global_statistics global_statistics = { .compressed_content_size = 0 }; -pthread_mutex_t global_statistics_mutex = PTHREAD_MUTEX_INITIALIZER; +netdata_mutex_t global_statistics_mutex = NETDATA_MUTEX_INITIALIZER; inline void global_statistics_lock(void) { - pthread_mutex_lock(&global_statistics_mutex); + netdata_mutex_lock(&global_statistics_mutex); } inline void global_statistics_unlock(void) { - pthread_mutex_unlock(&global_statistics_mutex); + netdata_mutex_unlock(&global_statistics_mutex); } void finished_web_request_statistics(uint64_t dt, diff --git a/src/health.c b/src/health.c index 57210c77..46b27db6 100644 --- a/src/health.c +++ b/src/health.c @@ -208,7 +208,7 @@ static inline void health_alarm_log_process(RRDHOST *host) { uint32_t first_waiting = (host->health_log.alarms)?host->health_log.alarms->unique_id:0; time_t now = now_realtime_sec(); - pthread_rwlock_rdlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock); ALARM_ENTRY *ae; for(ae = host->health_log.alarms; ae && ae->unique_id >= stop_at_id ; ae = ae->next) { @@ -228,13 +228,13 @@ static inline void health_alarm_log_process(RRDHOST *host) { // remember this for the next iteration stop_at_id = first_waiting; - pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock); if(host->health_log.count <= host->health_log.max) return; // cleanup excess entries in the log - pthread_rwlock_wrlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_wrlock(&host->health_log.alarm_log_rwlock); ALARM_ENTRY *last = NULL; unsigned int count = host->health_log.max * 2 / 3; @@ -256,7 +256,7 @@ static inline void health_alarm_log_process(RRDHOST *host) { host->health_log.count--; } - pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock); } static inline int rrdcalc_isrunnable(RRDCALC *rc, time_t now, time_t *next_run) { diff --git a/src/health.h b/src/health.h index f8e29032..7028a914 100644 --- a/src/health.h +++ b/src/health.h @@ -334,7 +334,7 @@ typedef struct alarm_log { unsigned int count; unsigned int max; ALARM_ENTRY *alarms; - pthread_rwlock_t alarm_log_rwlock; + netdata_rwlock_t alarm_log_rwlock; } ALARM_LOG; #include "rrd.h" diff --git a/src/health_json.c b/src/health_json.c index 4d24d5d1..a9697aaa 100644 --- a/src/health_json.c +++ b/src/health_json.c @@ -85,7 +85,7 @@ static inline void health_alarm_entry2json_nolock(BUFFER *wb, ALARM_ENTRY *ae, R } void health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after) { - pthread_rwlock_rdlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock); buffer_strcat(wb, "["); @@ -101,7 +101,7 @@ void health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after) { buffer_strcat(wb, "\n]\n"); - pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock); } static inline void health_rrdcalc2json_nolock(RRDHOST *host, BUFFER *wb, RRDCALC *rc) { diff --git a/src/health_log.c b/src/health_log.c index 990894ef..95abcfe5 100644 --- a/src/health_log.c +++ b/src/health_log.c @@ -129,7 +129,7 @@ inline ssize_t health_alarm_log_read(RRDHOST *host, FILE *fp, const char *filena size_t line = 0, len = 0; ssize_t loaded = 0, updated = 0, errored = 0, duplicate = 0; - pthread_rwlock_rdlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock); while((s = fgets_trim_len(buf, 65536, fp, &len))) { host->health_log_entries_written++; @@ -297,7 +297,7 @@ inline ssize_t health_alarm_log_read(RRDHOST *host, FILE *fp, const char *filena } } - pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock); freez(buf); @@ -404,14 +404,14 @@ inline void health_alarm_log( ae->non_clear_duration += ae->duration; // link it - pthread_rwlock_wrlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_wrlock(&host->health_log.alarm_log_rwlock); ae->next = host->health_log.alarms; host->health_log.alarms = ae; host->health_log.count++; - pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock); // match previous alarms - pthread_rwlock_rdlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock); ALARM_ENTRY *t; for(t = host->health_log.alarms ; t ; t = t->next) { if(t != ae && t->alarm_id == ae->alarm_id) { @@ -431,7 +431,7 @@ inline void health_alarm_log( break; } } - pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock); health_alarm_log_save(host, ae); } @@ -453,7 +453,7 @@ inline void health_alarm_log_free_one_nochecks_nounlink(ALARM_ENTRY *ae) { inline void health_alarm_log_free(RRDHOST *host) { rrdhost_check_wrlock(host); - pthread_rwlock_wrlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_wrlock(&host->health_log.alarm_log_rwlock); ALARM_ENTRY *ae; while((ae = host->health_log.alarms)) { @@ -461,5 +461,5 @@ inline void health_alarm_log_free(RRDHOST *host) { health_alarm_log_free_one_nochecks_nounlink(ae); } - pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock); + netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock); } diff --git a/src/locks.h b/src/locks.h new file mode 100644 index 00000000..80e0569a --- /dev/null +++ b/src/locks.h @@ -0,0 +1,294 @@ +#ifndef NETDATA_LOCKS_H +#define NETDATA_LOCKS_H + +// ---------------------------------------------------------------------------- +// mutex + +typedef pthread_mutex_t netdata_mutex_t; + +#define NETDATA_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +static inline int __netdata_mutex_init(netdata_mutex_t *mutex) { + int ret = pthread_mutex_init(mutex, NULL); + if(unlikely(ret != 0)) + error("MUTEX_LOCK: failed to initialize (code %d).", ret); + return ret; +} + +static inline int __netdata_mutex_lock(netdata_mutex_t *mutex) { + int ret = pthread_mutex_lock(mutex); + if(unlikely(ret != 0)) + error("MUTEX_LOCK: failed to get lock (code %d)", ret); + return ret; +} + +static inline int __netdata_mutex_trylock(netdata_mutex_t *mutex) { + int ret = pthread_mutex_trylock(mutex); + return ret; +} + +static inline int __netdata_mutex_unlock(netdata_mutex_t *mutex) { + int ret = pthread_mutex_unlock(mutex); + if(unlikely(ret != 0)) + error("MUTEX_LOCK: failed to unlock (code %d).", ret); + return ret; +} + +#ifdef NETDATA_INTERNAL_CHECKS + +static inline int netdata_mutex_init_debug( const char *file, const char *function, const unsigned long line, netdata_mutex_t *mutex) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_init() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_mutex_init(mutex); + + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_init() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_mutex_lock_debug( const char *file, const char *function, const unsigned long line, netdata_mutex_t *mutex) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_lock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_mutex_lock(mutex); + + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_lock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_mutex_trylock_debug( const char *file, const char *function, const unsigned long line, netdata_mutex_t *mutex) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_trylock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_mutex_trylock(mutex); + + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_trylock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_mutex_unlock_debug( const char *file, const char *function, const unsigned long line, netdata_mutex_t *mutex) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_unlock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_mutex_unlock(mutex); + + debug(D_LOCKS, "MUTEX_LOCK: netdata_mutex_unlock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +#define netdata_mutex_init(mutex) netdata_mutex_init_debug(__FILE__, __FUNCTION__, __LINE__, mutex) +#define netdata_mutex_lock(mutex) netdata_mutex_lock_debug(__FILE__, __FUNCTION__, __LINE__, mutex) +#define netdata_mutex_trylock(mutex) netdata_mutex_trylock_debug(__FILE__, __FUNCTION__, __LINE__, mutex) +#define netdata_mutex_unlock(mutex) netdata_mutex_unlock_debug(__FILE__, __FUNCTION__, __LINE__, mutex) + +#else // !NETDATA_INTERNAL_CHECKS + +#define netdata_mutex_init(mutex) __netdata_mutex_init(mutex) +#define netdata_mutex_lock(mutex) __netdata_mutex_lock(mutex) +#define netdata_mutex_trylock(mutex) __netdata_mutex_trylock(mutex) +#define netdata_mutex_unlock(mutex) __netdata_mutex_unlock(mutex) + +#endif // NETDATA_INTERNAL_CHECKS + + +// ---------------------------------------------------------------------------- +// r/w lock + +typedef pthread_rwlock_t netdata_rwlock_t; + +#define NETDATA_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER + +static inline int __netdata_rwlock_destroy(netdata_rwlock_t *rwlock) { + int ret = pthread_rwlock_destroy(rwlock); + if(unlikely(ret != 0)) + error("RW_LOCK: failed to destroy lock (code %d)", ret); + return ret; +} + +static inline int __netdata_rwlock_init(netdata_rwlock_t *rwlock) { + int ret = pthread_rwlock_init(rwlock, NULL); + if(unlikely(ret != 0)) + error("RW_LOCK: failed to initialize lock (code %d)", ret); + return ret; +} + +static inline int __netdata_rwlock_rdlock(netdata_rwlock_t *rwlock) { + int ret = pthread_rwlock_rdlock(rwlock); + if(unlikely(ret != 0)) + error("RW_LOCK: failed to obtain read lock (code %d)", ret); + return ret; +} + +static inline int __netdata_rwlock_wrlock(netdata_rwlock_t *rwlock) { + int ret = pthread_rwlock_wrlock(rwlock); + if(unlikely(ret != 0)) + error("RW_LOCK: failed to obtain write lock (code %d)", ret); + return ret; +} + +static inline int __netdata_rwlock_unlock(netdata_rwlock_t *rwlock) { + int ret = pthread_rwlock_unlock(rwlock); + if(unlikely(ret != 0)) + error("RW_LOCK: failed to release lock (code %d)", ret); + return ret; +} + +static inline int __netdata_rwlock_tryrdlock(netdata_rwlock_t *rwlock) { + int ret = pthread_rwlock_tryrdlock(rwlock); + return ret; +} + +static inline int __netdata_rwlock_trywrlock(netdata_rwlock_t *rwlock) { + int ret = pthread_rwlock_trywrlock(rwlock); + return ret; +} + + +#ifdef NETDATA_INTERNAL_CHECKS + +static inline int netdata_rwlock_destroy_debug( const char *file, const char *function, const unsigned long line, netdata_rwlock_t *rwlock) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_destroy() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_rwlock_destroy(rwlock); + + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_destroy() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_rwlock_init_debug( const char *file, const char *function, const unsigned long line, netdata_rwlock_t *rwlock) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_init() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_rwlock_init(rwlock); + + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_init() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_rwlock_rdlock_debug( const char *file, const char *function, const unsigned long line, netdata_rwlock_t *rwlock) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_rdlock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_rwlock_rdlock(rwlock); + + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_rdlock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_rwlock_wrlock_debug( const char *file, const char *function, const unsigned long line, netdata_rwlock_t *rwlock) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_wrlock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_rwlock_wrlock(rwlock); + + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_wrlock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_rwlock_unlock_debug( const char *file, const char *function, const unsigned long line, netdata_rwlock_t *rwlock) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_unlock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_rwlock_unlock(rwlock); + + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_unlock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_rwlock_tryrdlock_debug( const char *file, const char *function, const unsigned long line, netdata_rwlock_t *rwlock) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_tryrdlock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_rwlock_tryrdlock(rwlock); + + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_tryrdlock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +static inline int netdata_rwlock_trywrlock_debug( const char *file, const char *function, const unsigned long line, netdata_rwlock_t *rwlock) { + usec_t start = 0; + + if(unlikely(debug_flags & D_LOCKS)) { + start = now_boottime_usec(); + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_trywrlock() from %lu@%s, %s()", line, file, function); + } + + int ret = __netdata_rwlock_trywrlock(rwlock); + + debug(D_LOCKS, "RW_LOCK: netdata_rwlock_trywrlock() = %d in %llu usec, from %lu@%s, %s()", ret, now_boottime_usec() - start, line, file, function); + + return ret; +} + +#define netdata_rwlock_destroy(rwlock) netdata_rwlock_destroy_debug(__FILE__, __FUNCTION__, __LINE__, rwlock) +#define netdata_rwlock_init(rwlock) netdata_rwlock_init_debug(__FILE__, __FUNCTION__, __LINE__, rwlock) +#define netdata_rwlock_rdlock(rwlock) netdata_rwlock_rdlock_debug(__FILE__, __FUNCTION__, __LINE__, rwlock) +#define netdata_rwlock_wrlock(rwlock) netdata_rwlock_wrlock_debug(__FILE__, __FUNCTION__, __LINE__, rwlock) +#define netdata_rwlock_unlock(rwlock) netdata_rwlock_unlock_debug(__FILE__, __FUNCTION__, __LINE__, rwlock) +#define netdata_rwlock_tryrdlock(rwlock) netdata_rwlock_tryrdlock_debug(__FILE__, __FUNCTION__, __LINE__, rwlock) +#define netdata_rwlock_trywrlock(rwlock) netdata_rwlock_trywrlock_debug(__FILE__, __FUNCTION__, __LINE__, rwlock) + +#else // !NETDATA_INTERNAL_CHECKS + +#define netdata_rwlock_destroy(rwlock) __netdata_rwlock_destroy(rwlock) +#define netdata_rwlock_init(rwlock) __netdata_rwlock_init(rwlock) +#define netdata_rwlock_rdlock(rwlock) __netdata_rwlock_rdlock(rwlock) +#define netdata_rwlock_wrlock(rwlock) __netdata_rwlock_wrlock(rwlock) +#define netdata_rwlock_unlock(rwlock) __netdata_rwlock_unlock(rwlock) +#define netdata_rwlock_tryrdlock(rwlock) __netdata_rwlock_tryrdlock(rwlock) +#define netdata_rwlock_trywrlock(rwlock) __netdata_rwlock_trywrlock(rwlock) + +#endif // NETDATA_INTERNAL_CHECKS + +#endif //NETDATA_LOCKS_H diff --git a/src/log.h b/src/log.h index 24b971e2..d8ff0654 100644 --- a/src/log.h +++ b/src/log.h @@ -27,6 +27,7 @@ #define D_HEALTH 0x0000000000800000 #define D_CONNECT_TO 0x0000000001000000 #define D_RRDHOST 0x0000000002000000 +#define D_LOCKS 0x0000000004000000 #define D_SYSTEM 0x8000000000000000 //#define DEBUG (D_WEB_CLIENT_ACCESS|D_LISTENER|D_RRD_STATS) diff --git a/src/registry.c b/src/registry.c index ec6fb83b..ed9be984 100644 --- a/src/registry.c +++ b/src/registry.c @@ -10,11 +10,11 @@ // REGISTRY concurrency locking static inline void registry_lock(void) { - pthread_mutex_lock(®istry.lock); + netdata_mutex_lock(®istry.lock); } static inline void registry_unlock(void) { - pthread_mutex_unlock(®istry.lock); + netdata_mutex_unlock(®istry.lock); } diff --git a/src/registry_init.c b/src/registry_init.c index 09167260..2a41d36e 100644 --- a/src/registry_init.c +++ b/src/registry_init.c @@ -68,7 +68,7 @@ int registry_init(void) { registry.machines_urls_memory = 0; // initialize locks - pthread_mutex_init(®istry.lock, NULL); + netdata_mutex_init(®istry.lock); // create dictionaries registry.persons = dictionary_create(DICTIONARY_FLAGS); diff --git a/src/registry_internals.h b/src/registry_internals.h index 27c2fe07..433f04a6 100644 --- a/src/registry_internals.h +++ b/src/registry_internals.h @@ -56,7 +56,7 @@ struct registry { avl_tree registry_urls_root_index; - pthread_mutex_t lock; + netdata_mutex_t lock; }; extern int regenerate_guid(const char *guid, char *result); diff --git a/src/rrd.h b/src/rrd.h index bc642d80..86c4d25d 100644 --- a/src/rrd.h +++ b/src/rrd.h @@ -273,7 +273,7 @@ struct rrdset { char *cache_dir; // the directory to store dimensions char cache_filename[FILENAME_MAX+1]; // the filename to store this set - pthread_rwlock_t rrdset_rwlock; // protects dimensions linked list + netdata_rwlock_t rrdset_rwlock; // protects dimensions linked list size_t counter; // the number of times we added values to this database size_t counter_done; // the number of times rrdset_done() has been called @@ -325,6 +325,11 @@ struct rrdset { }; typedef struct rrdset RRDSET; +#define rrdset_rdlock(st) netdata_rwlock_rdlock(&((st)->rrdset_rwlock)) +#define rrdset_wrlock(st) netdata_rwlock_wrlock(&((st)->rrdset_rwlock)) +#define rrdset_unlock(st) netdata_rwlock_unlock(&((st)->rrdset_rwlock)) + + // ---------------------------------------------------------------------------- // these loop macros make sure the linked list is accessed with the right lock @@ -389,7 +394,7 @@ struct rrdhost { volatile int rrdpush_error_shown:1; // 1 when we have logged a communication error int rrdpush_socket; // the fd of the socket to the remote host, or -1 pthread_t rrdpush_thread; // the sender thread - pthread_mutex_t rrdpush_mutex; // exclusive access to rrdpush_buffer + netdata_mutex_t rrdpush_mutex; // exclusive access to rrdpush_buffer int rrdpush_pipe[2]; // collector to sender thread communication BUFFER *rrdpush_buffer; // collector fills it, sender sends them @@ -435,7 +440,7 @@ struct rrdhost { // ------------------------------------------------------------------------ // locks - pthread_rwlock_t rrdhost_rwlock; // lock for this RRDHOST (protects rrdset_root linked list) + netdata_rwlock_t rrdhost_rwlock; // lock for this RRDHOST (protects rrdset_root linked list) avl_tree_lock rrdset_root_index; // the host's charts index (by id) avl_tree_lock rrdset_root_index_name; // the host's charts index (by name) @@ -448,21 +453,9 @@ struct rrdhost { typedef struct rrdhost RRDHOST; extern RRDHOST *localhost; -static inline void rrdhost_rdlock(RRDHOST *host) { - if(unlikely(pthread_rwlock_rdlock(&host->rrdhost_rwlock) != 0)) - error("Cannot obtain read lock on host '%s'", host->hostname); -} - -static inline void rrdhost_wrlock(RRDHOST *host) { - if(unlikely(pthread_rwlock_wrlock(&host->rrdhost_rwlock) != 0)) - error("Cannot obtain write lock on host '%s'", host->hostname); -} - -static inline void rrdhost_unlock(RRDHOST *host) { - if(unlikely(pthread_rwlock_unlock(&host->rrdhost_rwlock) != 0)) - error("Cannot unlock host '%s'", host->hostname); -} - +#define rrdhost_rdlock(host) netdata_rwlock_rdlock(&((host)->rrdhost_rwlock)) +#define rrdhost_wrlock(host) netdata_rwlock_wrlock(&((host)->rrdhost_rwlock)) +#define rrdhost_unlock(host) netdata_rwlock_unlock(&((host)->rrdhost_rwlock)) // ---------------------------------------------------------------------------- // these loop macros make sure the linked list is accessed with the right lock @@ -477,37 +470,11 @@ static inline void rrdhost_unlock(RRDHOST *host) { // ---------------------------------------------------------------------------- // global lock for all RRDHOSTs -extern pthread_rwlock_t rrd_rwlock; - -static inline void rrd_rdlock() { - if(unlikely(pthread_rwlock_rdlock(&rrd_rwlock) != 0)) - error("Cannot read lock the RRD database."); -} - -static inline void rrd_wrlock() { - if(unlikely(pthread_rwlock_wrlock(&rrd_rwlock) != 0)) - error("Cannot write lock the RRD database."); -} - -static inline void rrd_unlock() { - if(unlikely(pthread_rwlock_unlock(&rrd_rwlock) != 0)) - error("Cannot unlock the RRD database."); -} - -static inline void rrdset_rdlock(RRDSET *st) { - if(unlikely(pthread_rwlock_rdlock(&st->rrdset_rwlock) != 0)) - error("Cannot read lock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname); -} - -static inline void rrdset_wrlock(RRDSET *st) { - if(unlikely(pthread_rwlock_wrlock(&st->rrdset_rwlock) != 0)) - error("Cannot write lock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname); -} - -static inline void rrdset_unlock(RRDSET *st) { - if(unlikely(pthread_rwlock_unlock(&st->rrdset_rwlock) != 0)) - error("Cannot unlock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname); -} +extern netdata_rwlock_t rrd_rwlock; + +#define rrd_rdlock() netdata_rwlock_rdlock(&rrd_rwlock) +#define rrd_wrlock() netdata_rwlock_wrlock(&rrd_rwlock) +#define rrd_unlock() netdata_rwlock_unlock(&rrd_rwlock) // ---------------------------------------------------------------------------- diff --git a/src/rrdhost.c b/src/rrdhost.c index a6824cb9..3ec71b58 100644 --- a/src/rrdhost.c +++ b/src/rrdhost.c @@ -3,7 +3,7 @@ RRDHOST *localhost = NULL; size_t rrd_hosts_available = 0; -pthread_rwlock_t rrd_rwlock = PTHREAD_RWLOCK_INITIALIZER; +netdata_rwlock_t rrd_rwlock = NETDATA_RWLOCK_INITIALIZER; time_t rrdset_free_obsolete_time = 3600; time_t rrdhost_free_orphan_time = 3600; @@ -108,8 +108,8 @@ RRDHOST *rrdhost_create(const char *hostname, host->rrdpush_pipe[1] = -1; host->rrdpush_socket = -1; - pthread_mutex_init(&host->rrdpush_mutex, NULL); - pthread_rwlock_init(&host->rrdhost_rwlock, NULL); + netdata_mutex_init(&host->rrdpush_mutex); + netdata_rwlock_init(&host->rrdhost_rwlock); rrdhost_init_hostname(host, hostname); rrdhost_init_machine_guid(host, guid); @@ -144,7 +144,7 @@ RRDHOST *rrdhost_create(const char *hostname, else host->health_log.max = (unsigned int)n; - pthread_rwlock_init(&(host->health_log.alarm_log_rwlock), NULL); + netdata_rwlock_init(&host->health_log.alarm_log_rwlock); char filename[FILENAME_MAX + 1]; @@ -383,7 +383,7 @@ void rrd_init(char *hostname) { void rrdhost_check_rdlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line) { debug(D_RRDHOST, "Checking read lock on host '%s'", host->hostname); - int ret = pthread_rwlock_trywrlock(&host->rrdhost_rwlock); + int ret = netdata_rwlock_trywrlock(&host->rrdhost_rwlock); if(ret == 0) fatal("RRDHOST '%s' should be read-locked, but it is not, at function %s() at line %lu of file '%s'", host->hostname, function, line, file); } @@ -391,7 +391,7 @@ void rrdhost_check_rdlock_int(RRDHOST *host, const char *file, const char *funct void rrdhost_check_wrlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line) { debug(D_RRDHOST, "Checking write lock on host '%s'", host->hostname); - int ret = pthread_rwlock_tryrdlock(&host->rrdhost_rwlock); + int ret = netdata_rwlock_tryrdlock(&host->rrdhost_rwlock); if(ret == 0) fatal("RRDHOST '%s' should be write-locked, but it is not, at function %s() at line %lu of file '%s'", host->hostname, function, line, file); } @@ -399,7 +399,7 @@ void rrdhost_check_wrlock_int(RRDHOST *host, const char *file, const char *funct void rrd_check_rdlock_int(const char *file, const char *function, const unsigned long line) { debug(D_RRDHOST, "Checking read lock on all RRDs"); - int ret = pthread_rwlock_trywrlock(&rrd_rwlock); + int ret = netdata_rwlock_trywrlock(&rrd_rwlock); if(ret == 0) fatal("RRDs should be read-locked, but it are not, at function %s() at line %lu of file '%s'", function, line, file); } @@ -407,7 +407,7 @@ void rrd_check_rdlock_int(const char *file, const char *function, const unsigned void rrd_check_wrlock_int(const char *file, const char *function, const unsigned long line) { debug(D_RRDHOST, "Checking write lock on all RRDs"); - int ret = pthread_rwlock_tryrdlock(&rrd_rwlock); + int ret = netdata_rwlock_tryrdlock(&rrd_rwlock); if(ret == 0) fatal("RRDs should be write-locked, but it are not, at function %s() at line %lu of file '%s'", function, line, file); } @@ -473,6 +473,8 @@ void rrdhost_free(RRDHOST *host) { freez(host->health_log_filename); freez(host->hostname); rrdhost_unlock(host); + netdata_rwlock_destroy(&host->health_log.alarm_log_rwlock); + netdata_rwlock_destroy(&host->rrdhost_rwlock); freez(host); rrd_hosts_available--; diff --git a/src/rrdpush.c b/src/rrdpush.c index 5b626410..87c4309a 100644 --- a/src/rrdpush.c +++ b/src/rrdpush.c @@ -59,8 +59,8 @@ int rrdpush_init() { // this is for the first iterations of each chart static unsigned int remote_clock_resync_iterations = 60; -#define rrdpush_lock(host) pthread_mutex_lock(&((host)->rrdpush_mutex)) -#define rrdpush_unlock(host) pthread_mutex_unlock(&((host)->rrdpush_mutex)) +#define rrdpush_lock(host) netdata_mutex_lock(&((host)->rrdpush_mutex)) +#define rrdpush_unlock(host) netdata_mutex_unlock(&((host)->rrdpush_mutex)) // checks if the current chart definition has been sent static inline int need_to_send_chart_definition(RRDSET *st) { diff --git a/src/rrdset.c b/src/rrdset.c index 30fd561a..51950603 100644 --- a/src/rrdset.c +++ b/src/rrdset.c @@ -6,7 +6,7 @@ void rrdset_check_rdlock_int(RRDSET *st, const char *file, const char *function, const unsigned long line) { debug(D_RRD_CALLS, "Checking read lock on chart '%s'", st->id); - int ret = pthread_rwlock_trywrlock(&st->rrdset_rwlock); + int ret = netdata_rwlock_trywrlock(&st->rrdset_rwlock); if(ret == 0) fatal("RRDSET '%s' should be read-locked, but it is not, at function %s() at line %lu of file '%s'", st->id, function, line, file); } @@ -14,7 +14,7 @@ void rrdset_check_rdlock_int(RRDSET *st, const char *file, const char *function, void rrdset_check_wrlock_int(RRDSET *st, const char *file, const char *function, const unsigned long line) { debug(D_RRD_CALLS, "Checking write lock on chart '%s'", st->id); - int ret = pthread_rwlock_tryrdlock(&st->rrdset_rwlock); + int ret = netdata_rwlock_tryrdlock(&st->rrdset_rwlock); if(ret == 0) fatal("RRDSET '%s' should be write-locked, but it is not, at function %s() at line %lu of file '%s'", st->id, function, line, file); } @@ -274,6 +274,8 @@ void rrdset_free(RRDSET *st) { // ------------------------------------------------------------------------ // free it + netdata_rwlock_destroy(&st->rrdset_rwlock); + // free directly allocated members freez(st->config_section); @@ -421,7 +423,7 @@ RRDSET *rrdset_create( memset(&st->avlname, 0, sizeof(avl)); memset(&st->variables_root_index, 0, sizeof(avl_tree_lock)); memset(&st->dimensions_index, 0, sizeof(avl_tree_lock)); - memset(&st->rrdset_rwlock, 0, sizeof(pthread_rwlock_t)); + memset(&st->rrdset_rwlock, 0, sizeof(netdata_rwlock_t)); st->name = NULL; st->type = NULL; @@ -537,7 +539,7 @@ RRDSET *rrdset_create( avl_init_lock(&st->dimensions_index, rrddim_compare); avl_init_lock(&st->variables_root_index, rrdvar_compare); - pthread_rwlock_init(&st->rrdset_rwlock, NULL); + netdata_rwlock_init(&st->rrdset_rwlock); if(name && *name) rrdset_set_name(st, name); else rrdset_set_name(st, id);