src/web_client.h
src/web_server.c
src/web_server.h
- )
+ src/locks.h)
set(APPS_PLUGIN_SOURCE_FILES
src/appconfig.c
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 \
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 \
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
};
struct config netdata_config = {
.sections = NULL,
- .mutex = PTHREAD_MUTEX_INITIALIZER,
+ .mutex = NETDATA_MUTEX_INITIALIZER,
.index = {
{ NULL, appconfig_section_compare },
AVL_LOCK_INITIALIZER
struct config stream_config = {
.sections = NULL,
- .mutex = PTHREAD_MUTEX_INITIALIZER,
+ .mutex = NETDATA_MUTEX_INITIALIZER,
.index = {
{ NULL, appconfig_section_compare },
AVL_LOCK_INITIALIZER
// 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);
}
struct config {
struct section *sections;
- pthread_mutex_t mutex;
+ netdata_mutex_t mutex;
avl_tree_lock index;
};
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 */
}
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 */
}
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 */
}
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)
// #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 */
#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;
// ----------------------------------------------------------------------------
// 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"
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);
}
}
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);
if(dict->stats)
freez(dict->stats);
- if(dict->rwlock)
+ if(dict->rwlock) {
+ netdata_rwlock_destroy(dict->rwlock);
freez(dict->rwlock);
+ }
freez(dict);
}
uint8_t flags;
struct dictionary_stats *stats;
- pthread_rwlock_t *rwlock;
+ netdata_rwlock_t *rwlock;
} DICTIONARY;
#define DICTIONARY_FLAG_DEFAULT 0x00000000
.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,
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) {
// 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;
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) {
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"
}
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, "[");
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) {
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++;
}
}
- pthread_rwlock_unlock(&host->health_log.alarm_log_rwlock);
+ netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
freez(buf);
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) {
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);
}
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)) {
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);
}
--- /dev/null
+#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
#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)
// 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);
}
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);
avl_tree registry_urls_root_index;
- pthread_mutex_t lock;
+ netdata_mutex_t lock;
};
extern int regenerate_guid(const char *guid, char *result);
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
};
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
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
// ------------------------------------------------------------------------
// 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)
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
// ----------------------------------------------------------------------------
// 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)
// ----------------------------------------------------------------------------
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;
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);
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];
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);
}
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);
}
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);
}
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);
}
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--;
// 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) {
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);
}
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);
}
// ------------------------------------------------------------------------
// free it
+ netdata_rwlock_destroy(&st->rrdset_rwlock);
+
// free directly allocated members
freez(st->config_section);
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;
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);