X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=src%2Frrdset.c;h=c847b96907de21c655707b725712a54289166886;hb=909e26f825bc1f6f907231761412c885331fec7e;hp=13d6014e8abf5af92c54a6dd479c29551162ec1a;hpb=cacc1a70bcb6926a7b56f9f3a2e8948aea29e145;p=netdata.git diff --git a/src/rrdset.c b/src/rrdset.c index 13d6014e..c847b969 100644 --- a/src/rrdset.c +++ b/src/rrdset.c @@ -3,18 +3,18 @@ #define RRD_DEFAULT_GAP_INTERPOLATIONS 1 -void rrdset_check_rdlock_int(RRDSET *st, const char *file, const char *function, const unsigned long line) { +void __rrdset_check_rdlock(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) { +void __rrdset_check_wrlock(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); } @@ -234,14 +234,7 @@ void rrdset_free(RRDSET *st) { rrdhost_check_wrlock(st->rrdhost); // make sure we have a write lock on the host rrdset_wrlock(st); // lock this RRDSET - // ------------------------------------------------------------------------ - // free its children structures - - while(st->variables) rrdsetvar_free(st->variables); - while(st->alarms) rrdsetcalc_unlink(st->alarms); - while(st->dimensions) rrddim_free(st, st->dimensions); - - rrdfamily_free(st->rrdhost, st->rrdfamily); + // info("Removing chart '%s' ('%s')", st->id, st->name); // ------------------------------------------------------------------------ // remove it from the indexes @@ -251,6 +244,15 @@ void rrdset_free(RRDSET *st) { rrdset_index_del_name(st->rrdhost, st); + // ------------------------------------------------------------------------ + // free its children structures + + while(st->variables) rrdsetvar_free(st->variables); + while(st->alarms) rrdsetcalc_unlink(st->alarms); + while(st->dimensions) rrddim_free(st, st->dimensions); + + rrdfamily_free(st->rrdhost, st->rrdfamily); + // ------------------------------------------------------------------------ // unlink it from the host @@ -272,6 +274,8 @@ void rrdset_free(RRDSET *st) { // ------------------------------------------------------------------------ // free it + netdata_rwlock_destroy(&st->rrdset_rwlock); + // free directly allocated members freez(st->config_section); @@ -283,13 +287,73 @@ void rrdset_free(RRDSET *st) { freez(st); } +void rrdset_save(RRDSET *st) { + RRDDIM *rd; + + rrdset_check_rdlock(st); + + // info("Saving chart '%s' ('%s')", st->id, st->name); + + if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) { + debug(D_RRD_STATS, "Saving stats '%s' to '%s'.", st->name, st->cache_filename); + savememory(st->cache_filename, st, st->memsize); + } + + rrddim_foreach_read(rd, st) { + if(likely(rd->rrd_memory_mode == RRD_MEMORY_MODE_SAVE)) { + debug(D_RRD_STATS, "Saving dimension '%s' to '%s'.", rd->name, rd->cache_filename); + savememory(rd->cache_filename, rd, rd->memsize); + } + } +} + +void rrdset_delete(RRDSET *st) { + RRDDIM *rd; + + rrdset_check_rdlock(st); + + // info("Deleting chart '%s' ('%s')", st->id, st->name); + + if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) { + debug(D_RRD_STATS, "Deleting stats '%s' to '%s'.", st->name, st->cache_filename); + unlink(st->cache_filename); + } + + rrddim_foreach_read(rd, st) { + if(likely(rd->rrd_memory_mode == RRD_MEMORY_MODE_SAVE)) { + debug(D_RRD_STATS, "Deleting dimension '%s' to '%s'.", rd->name, rd->cache_filename); + unlink(rd->cache_filename); + } + } +} + // ---------------------------------------------------------------------------- // RRDSET - create a chart -RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const char *name, const char *family - , const char *context, const char *title, const char *units, long priority - , int update_every, RRDSET_TYPE chart_type) { +static inline RRDSET *rrdset_find_on_create(RRDHOST *host, const char *fullid) { + RRDSET *st = rrdset_find(host, fullid); + if(unlikely(st)) { + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE); + debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid); + return st; + } + + return NULL; +} +RRDSET *rrdset_create( + RRDHOST *host + , const char *type + , const char *id + , const char *name + , const char *family + , const char *context + , const char *title + , const char *units + , long priority + , int update_every + , RRDSET_TYPE chart_type +) { if(!type || !type[0]) { fatal("Cannot create rrd stats without a type."); return NULL; @@ -306,9 +370,14 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha char fullid[RRD_ID_LENGTH_MAX + 1]; snprintfz(fullid, RRD_ID_LENGTH_MAX, "%s.%s", type, id); - RRDSET *st = rrdset_find(host, fullid); + RRDSET *st = rrdset_find_on_create(host, fullid); + if(st) return st; + + rrdhost_wrlock(host); + + st = rrdset_find_on_create(host, fullid); if(st) { - debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid); + rrdhost_unlock(host); return st; } @@ -354,7 +423,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha 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; @@ -449,6 +518,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha rrdset_flag_clear(st, RRDSET_FLAG_DETAIL); rrdset_flag_clear(st, RRDSET_FLAG_DEBUG); + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE); // if(!strcmp(st->id, "disk_util.dm-0")) { // st->debug = 1; @@ -469,8 +539,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha avl_init_lock(&st->dimensions_index, rrddim_compare); avl_init_lock(&st->variables_root_index, rrdvar_compare); - pthread_rwlock_init(&st->rrdset_rwlock, NULL); - rrdhost_wrlock(host); + netdata_rwlock_init(&st->rrdset_rwlock); if(name && *name) rrdset_set_name(st, name); else rrdset_set_name(st, id); @@ -502,6 +571,8 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha rrdsetcalc_link_matching(st); rrdcalctemplate_link_matching(st); + rrdhost_cleanup_obsolete(host); + rrdhost_unlock(host); return(st); @@ -677,6 +748,11 @@ void rrdset_done(RRDSET *st) { st->enabled = 1; */ + if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE))) { + error("Chart '%s' has the OBSOLETE flag set, but it is collected.", st->id); + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE); + } + // check if the chart has a long time to be updated if(unlikely(st->usec_since_last_update > st->entries * update_every_ut)) { info("%s: took too long to be updated (%0.3Lf secs). Resetting it.", st->name, (long double)(st->usec_since_last_update / 1000000.0)); @@ -1190,8 +1266,8 @@ void rrdset_done(RRDSET *st) { RRDDIM *last; // there is dimension to free // upgrade our read lock to a write lock - pthread_rwlock_unlock(&st->rrdset_rwlock); - pthread_rwlock_wrlock(&st->rrdset_rwlock); + rrdset_unlock(st); + rrdset_wrlock(st); for( rd = st->dimensions, last = NULL ; likely(rd) ; ) { // remove it only it is not updated in rrd_delete_unupdated_dimensions seconds