1 #define NETDATA_RRD_INTERNALS 1
4 // ----------------------------------------------------------------------------
8 .hostname = "localhost",
11 .rrdset_root_rwlock = PTHREAD_RWLOCK_INITIALIZER,
12 .rrdset_root_index = {
13 { NULL, rrdset_compare },
16 .rrdset_root_index_name = {
17 { NULL, rrdset_compare_name },
20 .rrdfamily_root_index = {
21 { NULL, rrdfamily_compare },
24 .variables_root_index = {
25 { NULL, rrdvar_compare },
34 .alarm_log_rwlock = PTHREAD_RWLOCK_INITIALIZER
39 void rrdhost_init(char *hostname) {
40 localhost.hostname = hostname;
41 localhost.health_log.next_log_id =
42 localhost.health_log.next_alarm_id = (uint32_t)now_realtime_sec();
45 void rrdhost_rwlock(RRDHOST *host) {
46 pthread_rwlock_wrlock(&host->rrdset_root_rwlock);
49 void rrdhost_rdlock(RRDHOST *host) {
50 pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
53 void rrdhost_unlock(RRDHOST *host) {
54 pthread_rwlock_unlock(&host->rrdset_root_rwlock);
57 void rrdhost_check_rdlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line) {
58 int ret = pthread_rwlock_trywrlock(&host->rrdset_root_rwlock);
61 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);
64 void rrdhost_check_wrlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line) {
65 int ret = pthread_rwlock_tryrdlock(&host->rrdset_root_rwlock);
68 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);
71 void rrdhost_free(RRDHOST *host) {
72 info("Freeing all memory...");
77 for(st = host->rrdset_root; st ;) {
78 RRDSET *next = st->next;
80 pthread_rwlock_wrlock(&st->rwlock);
83 rrdsetvar_free(st->variables);
86 rrdsetcalc_unlink(st->alarms);
89 rrddim_free(st, st->dimensions);
91 if(unlikely(rrdset_index_del(host, st) != st))
92 error("RRDSET: INTERNAL ERROR: attempt to remove from index chart '%s', removed a different chart.", st->id);
94 rrdset_index_del_name(host, st);
96 st->rrdfamily->use_count--;
97 if(!st->rrdfamily->use_count)
98 rrdfamily_free(host, st->rrdfamily);
100 pthread_rwlock_unlock(&st->rwlock);
102 if(st->mapped == RRD_MEMORY_MODE_SAVE || st->mapped == RRD_MEMORY_MODE_MAP) {
103 debug(D_RRD_CALLS, "Unmapping stats '%s'.", st->name);
104 munmap(st, st->memsize);
111 host->rrdset_root = NULL;
113 rrdhost_unlock(host);
115 info("Memory cleanup completed...");
118 void rrdhost_save(RRDHOST *host) {
119 info("Saving database...");
124 // we get an write lock
125 // to ensure only one thread is saving the database
126 rrdhost_rwlock(host);
128 for(st = host->rrdset_root; st ; st = st->next) {
129 pthread_rwlock_rdlock(&st->rwlock);
131 if(st->mapped == RRD_MEMORY_MODE_SAVE) {
132 debug(D_RRD_CALLS, "Saving stats '%s' to '%s'.", st->name, st->cache_filename);
133 savememory(st->cache_filename, st, st->memsize);
136 for(rd = st->dimensions; rd ; rd = rd->next) {
137 if(likely(rd->memory_mode == RRD_MEMORY_MODE_SAVE)) {
138 debug(D_RRD_CALLS, "Saving dimension '%s' to '%s'.", rd->name, rd->cache_filename);
139 savememory(rd->cache_filename, rd, rd->memsize);
143 pthread_rwlock_unlock(&st->rwlock);
146 rrdhost_unlock(host);
149 void rrdhost_free_all(void) {
152 // FIXME: lock all hosts
154 for(host = &localhost; host ;) {
155 RRDHOST *next = host = host->next;
160 // FIXME: unlock all hosts
163 void rrdhost_save_all(void) {
165 for(host = &localhost; host ; host = host->next)