From: Costa Tsaousis (ktsaou) Date: Sat, 3 Oct 2015 09:56:20 +0000 (+0300) Subject: code optimizations; added temperature charts.d plugin X-Git-Tag: v1.0rc~324 X-Git-Url: https://arthur.barton.de/gitweb/?a=commitdiff_plain;h=71b72e4f59b129ced0a1d15e5ce3b21370edfbbd;hp=3d916bd468a12150385083d998c866f275c5ab64;p=netdata.git code optimizations; added temperature charts.d plugin --- diff --git a/charts.d/example.chart.sh b/charts.d/example.chart.sh index 0f6251ad..aa1005d1 100755 --- a/charts.d/example.chart.sh +++ b/charts.d/example.chart.sh @@ -1,7 +1,13 @@ #!/bin/sh +# if this chart is called X.chart.sh, then all functions and global variables +# must start with X_ + +# _update_every is a special variable - it holds the number of seconds +# between the calls of the _update() function example_update_every= +# _check is called once, to find out if this chart should be enabled or not example_check() { # this should return: # - 0 to enable the chart @@ -10,9 +16,10 @@ example_check() { return 0 } +# _create is called once, to create the charts example_create() { -# create the chart with 3 dimensions -cat <&2 "charts.d: chart '$chart' does not seem to have a $chart$charts_check() function. Disabling it." continue fi - local create="`cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_create()"`" + local create="$( cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_create()" )" if [ -z "$create" ] then echo >&2 "charts.d: chart '$chart' does not seem to have a $chart$charts_create() function. Disabling it." continue fi - local update="`cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_update()"`" + local update="$( cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_update()" )" if [ -z "$update" ] then echo >&2 "charts.d: chart '$chart' does not seem to have a $chart$charts_update() function. Disabling it." @@ -182,7 +182,7 @@ all_enabled_charts() { # check its config if [ -f "$confd/$chart.conf" ] then - if [ ! -z "`cat "$confd/$chart.conf" | sed "s/^ \+//g" | grep -v "^$" | grep -v "^#" | grep -v "^$chart$charts_undescore"`" ] + if [ ! -z "$( cat "$confd/$chart.conf" | sed "s/^ \+//g" | grep -v "^$" | grep -v "^#" | grep -v "^$chart$charts_undescore" )" ] then echo >&2 "charts.d: chart's $chart config $confd/$chart.conf should only have lines starting with $chart$charts_undescore . Disabling it." continue @@ -208,7 +208,7 @@ all_enabled_charts() { suffix_update_every="_update_every" active_charts= -for chart in `all_enabled_charts` +for chart in $( all_enabled_charts ) do . "$chartsd/$chart.chart.sh" @@ -264,6 +264,39 @@ then exit 0 fi +# ----------------------------------------------------------------------------- +# create temp dir + +TMP_DIR= +chartsd_cleanup() { + if [ ! -z "$TMP_DIR" -a -d "$TMP_DIR" ] + then + echo >&2 "charts.d: cleaning up temporary directory $TMP_DIR ..." + rm -rf "$TMP_DIR" + fi + exit 0 +} +trap chartsd_cleanup EXIT +trap chartsd_cleanup SIGHUP +trap chartsd_cleanup INT + +if [ $UID = "0" ] +then + TMP_DIR="$( mktemp -d /var/run/netdata-charts.d-XXXXXXXXXX )" +else + TMP_DIR="$( mktemp -d /tmp/.netdata-charts.d-XXXXXXXXXX )" +fi + +# ----------------------------------------------------------------------------- +# library functions + +fixid() { + echo "$*" |\ + tr -c "[A-Z][a-z][0-9]" "_" |\ + sed -e "s|^_\+||g" -e "s|_\+$||g" -e "s|_\+|_|g" |\ + tr "[A-Z]" "[a-z]" +} + # ----------------------------------------------------------------------------- # create charts diff --git a/src/common.h b/src/common.h index 90ae1497..85c30712 100755 --- a/src/common.h +++ b/src/common.h @@ -16,4 +16,14 @@ extern int savememory(const char *filename, void *mem, unsigned long size); extern int fd_is_valid(int fd); +#ifdef __GNUC__ +// gcc branch optimization +// #warning "Using GCC branch optimizations" +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#endif + #endif /* NETDATA_COMMON_H */ diff --git a/src/config.c b/src/config.c index e1be0ced..d76f20c9 100755 --- a/src/config.c +++ b/src/config.c @@ -230,7 +230,7 @@ int load_config(char *filename, int overwrite_used) if(!cv) cv = config_value_create(co, name, value); else { - if((cv->flags & CONFIG_VALUE_USED && overwrite_used) || !(cv->flags & CONFIG_VALUE_USED)) { + if(((cv->flags & CONFIG_VALUE_USED) && overwrite_used) || !(cv->flags & CONFIG_VALUE_USED)) { debug(D_CONFIG, "Overwriting '%s/%s'.", line, co->name, cv->name); free(cv->value); cv->value = strdup(value); @@ -266,7 +266,7 @@ char *config_get(const char *section, const char *name, const char *default_valu } cv->flags |= CONFIG_VALUE_USED; - if(cv->flags & CONFIG_VALUE_LOADED || cv->flags & CONFIG_VALUE_CHANGED) { + if((cv->flags & CONFIG_VALUE_LOADED) || (cv->flags & CONFIG_VALUE_CHANGED)) { // this is a loaded value from the config file // if it is different that the default, mark it if(!(cv->flags & CONFIG_VALUE_CHECKED)) { diff --git a/src/global_statistics.c b/src/global_statistics.c index 51c8b513..493e92ea 100755 --- a/src/global_statistics.c +++ b/src/global_statistics.c @@ -1,5 +1,6 @@ #include +#include "common.h" #include "global_statistics.h" struct global_statistics global_statistics = { 0ULL, 0ULL, 0ULL, 0ULL }; diff --git a/src/log.c b/src/log.c index f12061c8..c7b8283b 100755 --- a/src/log.c +++ b/src/log.c @@ -6,6 +6,8 @@ #include #include "log.h" +#include "common.h" + // ---------------------------------------------------------------------------- // LOG diff --git a/src/log.h b/src/log.h index 455db1d3..5e6fe1b0 100755 --- a/src/log.h +++ b/src/log.h @@ -42,7 +42,7 @@ extern int access_log_syslog; extern int error_log_syslog; extern int output_log_syslog; -#define debug(type, args...) do { if(!silent && debug_flags & type) debug_int(__FILE__, __FUNCTION__, __LINE__, ##args); } while(0) +#define debug(type, args...) do { if(unlikely(!silent && (debug_flags & type))) debug_int(__FILE__, __FUNCTION__, __LINE__, ##args); } while(0) #define info(args...) info_int(__FILE__, __FUNCTION__, __LINE__, ##args) #define error(args...) error_int(__FILE__, __FUNCTION__, __LINE__, ##args) #define fatal(args...) fatal_int(__FILE__, __FUNCTION__, __LINE__, ##args) diff --git a/src/main.c b/src/main.c index a8f090d3..dbf0c674 100755 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include #include +#include "common.h" #include "log.h" #include "daemon.h" #include "web_server.h" diff --git a/src/plugins_d.c b/src/plugins_d.c index 11f26edd..a8baf6c7 100755 --- a/src/plugins_d.c +++ b/src/plugins_d.c @@ -37,10 +37,10 @@ static void pluginsd_split_words(char *str, char **words, int max_words) { int i = 0; // skip all white space - while(pluginsd_space(*s)) s++; + while(unlikely(pluginsd_space(*s))) s++; // check for quote - if(*s == '\'' || *s == '"') { + if(unlikely(*s == '\'' || *s == '"')) { quote = *s; // remember the quote s++; // skip the quote } @@ -49,40 +49,40 @@ static void pluginsd_split_words(char *str, char **words, int max_words) { words[i++] = s; // while we have something - while(*s) { + while(likely(*s)) { // if it is escape - if(*s == '\\' && s[1]) { + if(unlikely(*s == '\\' && s[1])) { s += 2; continue; } // if it is quote - else if(*s == quote) { + else if(unlikely(*s == quote)) { quote = 0; *s = ' '; continue; } // if it is a space - else if(quote == 0 && pluginsd_space(*s)) { + else if(unlikely(quote == 0 && pluginsd_space(*s))) { // terminate the word *s++ = '\0'; // skip all white space - while(pluginsd_space(*s)) s++; + while(likely(pluginsd_space(*s))) s++; // check for quote - if(*s == '\'' || *s == '"') { + if(unlikely(*s == '\'' || *s == '"')) { quote = *s; // remember the quote s++; // skip the quote } // if we reached the end, stop - if(!*s) break; + if(unlikely(!*s)) break; // store the next word - if(i < max_words) words[i++] = s; + if(likely(i < max_words)) words[i++] = s; else break; } @@ -91,7 +91,7 @@ static void pluginsd_split_words(char *str, char **words, int max_words) { } // terminate the words - while(i < max_words) words[i++] = NULL; + while(likely(i < max_words)) words[i++] = NULL; } @@ -118,9 +118,9 @@ void *pluginsd_worker_thread(void *arg) uint32_t STOPPING_WAKE_ME_UP_PLEASE_HASH = simple_hash("STOPPING_WAKE_ME_UP_PLEASE"); #endif - while(1) { + while(likely(1)) { FILE *fp = mypopen(cd->cmd, &cd->pid); - if(!fp) { + if(unlikely(!fp)) { error("Cannot popen(\"%s\", \"r\").", cd->cmd); break; } @@ -132,14 +132,14 @@ void *pluginsd_worker_thread(void *arg) char *s; uint32_t hash; - while(fgets(line, PLUGINSD_LINE_MAX, fp) != NULL) { + while(likely(fgets(line, PLUGINSD_LINE_MAX, fp) != NULL)) { line[PLUGINSD_LINE_MAX] = '\0'; // debug(D_PLUGINSD, "PLUGINSD: %s: %s", cd->filename, line); pluginsd_split_words(line, words, MAX_WORDS); s = words[0]; - if(!s || !*s) { + if(unlikely(!s || !*s)) { // debug(D_PLUGINSD, "PLUGINSD: empty line"); continue; } @@ -148,36 +148,36 @@ void *pluginsd_worker_thread(void *arg) hash = simple_hash(s); - if(hash == SET_HASH && !strcmp(s, "SET")) { + if(likely(hash == SET_HASH && !strcmp(s, "SET"))) { char *dimension = words[1]; char *value = words[2]; - if(!dimension || !*dimension) { + if(unlikely(!dimension || !*dimension)) { error("PLUGINSD: '%s' is requesting a SET on chart '%s', like this: 'SET %s = %s'. Disabling it.", cd->fullfilename, st->id, dimension?dimension:"", value?value:""); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } - if(!value || !*value) value = "0"; + if(unlikely(!value || !*value)) value = "0"; - if(!st) { + if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } - if(st->debug) debug(D_PLUGINSD, "PLUGINSD: '%s' is setting dimension %s/%s to %s", cd->fullfilename, st->id, dimension, value); + if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is setting dimension %s/%s to %s", cd->fullfilename, st->id, dimension, value); rrddim_set(st, dimension, atoll(value)); count++; } - else if(hash == BEGIN_HASH && !strcmp(s, "BEGIN")) { + else if(likely(hash == BEGIN_HASH && !strcmp(s, "BEGIN"))) { char *id = words[1]; char *microseconds_txt = words[2]; - if(!id) { + if(unlikely(!id)) { error("PLUGINSD: '%s' is requesting a BEGIN without a chart id. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); @@ -185,45 +185,45 @@ void *pluginsd_worker_thread(void *arg) } st = rrdset_find(id); - if(!st) { + if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting a BEGIN on chart '%s', which does not exist. Disabling it.", cd->fullfilename, id); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } - if(st->counter_done) { + if(likely(st->counter_done)) { unsigned long long microseconds = 0; if(microseconds_txt && *microseconds_txt) microseconds = strtoull(microseconds_txt, NULL, 10); if(microseconds) rrdset_next_usec(st, microseconds); else rrdset_next_plugins(st); } } - else if(hash == END_HASH && !strcmp(s, "END")) { - if(!st) { + else if(likely(hash == END_HASH && !strcmp(s, "END"))) { + if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting an END, without a BEGIN. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } - if(st->debug) debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a END on chart %s", cd->fullfilename, st->id); + if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a END on chart %s", cd->fullfilename, st->id); rrdset_done(st); st = NULL; } - else if(hash == FLUSH_HASH && !strcmp(s, "FLUSH")) { + else if(likely(hash == FLUSH_HASH && !strcmp(s, "FLUSH"))) { debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a FLUSH", cd->fullfilename); st = NULL; } - else if(hash == CHART_HASH && !strcmp(s, "CHART")) { + else if(likely(hash == CHART_HASH && !strcmp(s, "CHART"))) { st = NULL; char *type = words[1]; char *id = NULL; - if(type) { + if(likely(type)) { id = strchr(type, '.'); - if(id) { *id = '\0'; id++; } + if(likely(id)) { *id = '\0'; id++; } } char *name = words[2]; char *title = words[3]; @@ -234,7 +234,7 @@ void *pluginsd_worker_thread(void *arg) char *priority_s = words[8]; char *update_every_s = words[9]; - if(!type || !*type || !id || !*id) { + if(unlikely(!type || !*type || !id || !*id)) { error("PLUGINSD: '%s' is requesting a CHART, without a type.id. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); @@ -242,21 +242,21 @@ void *pluginsd_worker_thread(void *arg) } int priority = 1000; - if(priority_s) priority = atoi(priority_s); + if(likely(priority_s)) priority = atoi(priority_s); int update_every = cd->update_every; - if(update_every_s) update_every = atoi(update_every_s); - if(!update_every) update_every = cd->update_every; + if(likely(update_every_s)) update_every = atoi(update_every_s); + if(unlikely(!update_every)) update_every = cd->update_every; int chart_type = RRDSET_TYPE_LINE; - if(chart) chart_type = rrdset_type_id(chart); + if(unlikely(chart)) chart_type = rrdset_type_id(chart); - if(!name || !*name) name = NULL; - if(!family || !*family) family = id; - if(!category || !*category) category = type; + if(unlikely(!name || !*name)) name = NULL; + if(unlikely(!family || !*family)) family = id; + if(unlikely(!category || !*category)) category = type; st = rrdset_find_bytype(type, id); - if(!st) { + if(unlikely(!st)) { debug(D_PLUGINSD, "PLUGINSD: Creating chart type='%s', id='%s', name='%s', family='%s', category='%s', chart='%s', priority=%d, update_every=%d" , type, id , name?name:"" @@ -270,11 +270,11 @@ void *pluginsd_worker_thread(void *arg) st = rrdset_create(type, id, name, family, title, units, priority, update_every, chart_type); cd->update_every = update_every; - if(strcmp(category, "none") == 0) st->isdetail = 1; + if(unlikely(strcmp(category, "none") == 0)) st->isdetail = 1; } else debug(D_PLUGINSD, "PLUGINSD: Chart '%s' already exists. Not adding it again.", st->id); } - else if(hash == DIMENSION_HASH && !strcmp(s, "DIMENSION")) { + else if(likely(hash == DIMENSION_HASH && !strcmp(s, "DIMENSION"))) { char *id = words[1]; char *name = words[2]; char *algorithm = words[3]; @@ -282,14 +282,14 @@ void *pluginsd_worker_thread(void *arg) char *divisor_s = words[5]; char *hidden = words[6]; - if(!id || !*id) { + if(unlikely(!id || !*id)) { error("PLUGINSD: '%s' is requesting a DIMENSION, without an id. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } - if(!st) { + if(unlikely(!st)) { error("PLUGINSD: '%s' is requesting a DIMENSION, without a CHART. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); @@ -298,15 +298,15 @@ void *pluginsd_worker_thread(void *arg) long multiplier = 1; if(multiplier_s && *multiplier_s) multiplier = atol(multiplier_s); - if(!multiplier) multiplier = 1; + if(unlikely(!multiplier)) multiplier = 1; long divisor = 1; - if(divisor_s && *divisor_s) divisor = atol(divisor_s); - if(!divisor) divisor = 1; + if(likely(divisor_s && *divisor_s)) divisor = atol(divisor_s); + if(unlikely(!divisor)) divisor = 1; - if(!algorithm || !*algorithm) algorithm = "absolute"; + if(unlikely(!algorithm || !*algorithm)) algorithm = "absolute"; - if(st->debug) debug(D_PLUGINSD, "PLUGINSD: Creating dimension in chart %s, id='%s', name='%s', algorithm='%s', multiplier=%ld, divisor=%ld, hidden='%s'" + if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: Creating dimension in chart %s, id='%s', name='%s', algorithm='%s', multiplier=%ld, divisor=%ld, hidden='%s'" , st->id , id , name?name:"" @@ -317,31 +317,31 @@ void *pluginsd_worker_thread(void *arg) ); RRDDIM *rd = rrddim_find(st, id); - if(!rd) { + if(unlikely(!rd)) { rd = rrddim_add(st, id, name, multiplier, divisor, rrddim_algorithm_id(algorithm)); - if(hidden && strcmp(hidden, "hidden") == 0) rd->hidden = 1; + if(unlikely(hidden && strcmp(hidden, "hidden") == 0)) rd->hidden = 1; } - else if(st->debug) debug(D_PLUGINSD, "PLUGINSD: dimension %s/%s already exists. Not adding it again.", st->id, id); + else if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: dimension %s/%s already exists. Not adding it again.", st->id, id); } - else if(hash == DISABLE_HASH && !strcmp(s, "DISABLE")) { + else if(unlikely(hash == DISABLE_HASH && !strcmp(s, "DISABLE"))) { error("PLUGINSD: '%s' called DISABLE. Disabling it.", cd->fullfilename); cd->enabled = 0; killpid(cd->pid, SIGTERM); break; } #ifdef DETACH_PLUGINS_FROM_NETDATA - else if(hash == MYPID_HASH && !strcmp(s, "MYPID")) { + else if(likely(hash == MYPID_HASH && !strcmp(s, "MYPID"))) { char *pid_s = words[1]; pid_t pid = atol(pid_s); - if(pid) cd->pid = pid; + if(likely(pid)) cd->pid = pid; debug(D_PLUGINSD, "PLUGINSD: %s is on pid %d", cd->id, cd->pid); } - else if(hash == STOPPING_WAKE_ME_UP_PLEASE_HASH && !strcmp(s, "STOPPING_WAKE_ME_UP_PLEASE")) { + else if(likely(hash == STOPPING_WAKE_ME_UP_PLEASE_HASH && !strcmp(s, "STOPPING_WAKE_ME_UP_PLEASE"))) { error("PLUGINSD: '%s' (pid %d) called STOPPING_WAKE_ME_UP_PLEASE.", cd->fullfilename, cd->pid); gettimeofday(&now, NULL); - if(!usec && !susec) { + if(unlikely(!usec && !susec)) { // our first run susec = cd->rrd_update_every * 1000000ULL; } @@ -349,7 +349,7 @@ void *pluginsd_worker_thread(void *arg) // second+ run usec = usecdiff(&now, &last) - susec; error("PLUGINSD: %s last loop took %llu usec (worked for %llu, sleeped for %llu).\n", cd->fullfilename, usec + susec, usec, susec); - if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec; + if(unlikely(usec < (rrd_update_every * 1000000ULL / 2ULL))) susec = (rrd_update_every * 1000000ULL) - usec; else susec = rrd_update_every * 1000000ULL / 2ULL; } @@ -373,14 +373,14 @@ void *pluginsd_worker_thread(void *arg) // fgets() failed or loop broke mypclose(fp, cd->pid); - if(!count && cd->enabled) { + if(unlikely(!count && cd->enabled)) { error("PLUGINSD: '%s' (pid %d) does not generate usefull output. Waiting a bit before starting it again.", cd->fullfilename, cd->pid); sleep(cd->update_every * 10); } cd->pid = 0; - if(cd->enabled) sleep(cd->update_every); + if(likely(cd->enabled)) sleep(cd->update_every); else break; } @@ -410,21 +410,21 @@ void *pluginsd_main(void *ptr) if(scan_frequency < 1) scan_frequency = 1; - while(1) { + while(likely(1)) { dir = opendir(dir_name); - if(!dir) { + if(unlikely(!dir)) { error("Cannot open directory '%s'.", dir_name); return NULL; } - while((file = readdir(dir))) { + while(likely((file = readdir(dir)))) { debug(D_PLUGINSD, "PLUGINSD: Examining file '%s'", file->d_name); - if(strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0) continue; + if(unlikely(strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)) continue; int len = strlen(file->d_name); - if(len <= (int)PLUGINSD_FILE_SUFFIX_LEN) continue; - if(strcmp(PLUGINSD_FILE_SUFFIX, &file->d_name[len - (int)PLUGINSD_FILE_SUFFIX_LEN]) != 0) { + if(unlikely(len <= (int)PLUGINSD_FILE_SUFFIX_LEN)) continue; + if(unlikely(strcmp(PLUGINSD_FILE_SUFFIX, &file->d_name[len - (int)PLUGINSD_FILE_SUFFIX_LEN]) != 0)) { debug(D_PLUGINSD, "PLUGINSD: File '%s' does not end in '%s'.", file->d_name, PLUGINSD_FILE_SUFFIX); continue; } @@ -433,25 +433,25 @@ void *pluginsd_main(void *ptr) snprintf(pluginname, CONFIG_MAX_NAME, "%.*s", (int)(len - PLUGINSD_FILE_SUFFIX_LEN), file->d_name); int enabled = config_get_boolean("plugins", pluginname, automatic_run); - if(!enabled) { + if(unlikely(!enabled)) { debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is not enabled", file->d_name); continue; } // check if it runs already - for(cd = pluginsd_root ; cd ; cd = cd->next) { - if(strcmp(cd->filename, file->d_name) == 0) break; + for(cd = pluginsd_root ; likely(cd) ; cd = cd->next) { + if(unlikely(strcmp(cd->filename, file->d_name) == 0)) break; } - if(cd && !cd->obsolete) { + if(likely(cd && !cd->obsolete)) { debug(D_PLUGINSD, "PLUGINSD: plugin '%s' is already running", cd->filename); continue; } // it is not running // allocate a new one, or use the obsolete one - if(!cd) { + if(unlikely(!cd)) { cd = calloc(sizeof(struct plugind), 1); - if(!cd) fatal("Cannot allocate memory for plugin."); + if(unlikely(!cd)) fatal("Cannot allocate memory for plugin."); snprintf(cd->id, CONFIG_MAX_NAME, "plugin:%s", pluginname); @@ -466,19 +466,19 @@ void *pluginsd_main(void *ptr) snprintf(cd->cmd, PLUGINSD_CMD_MAX, "exec %s %d %s", cd->fullfilename, cd->update_every, config_get(cd->id, "command options", def)); // link it - if(pluginsd_root) cd->next = pluginsd_root; + if(likely(pluginsd_root)) cd->next = pluginsd_root; pluginsd_root = cd; } cd->obsolete = 0; - if(!cd->enabled) continue; + if(unlikely(!cd->enabled)) continue; // spawn a new thread for it - if(pthread_create(&cd->thread, NULL, pluginsd_worker_thread, cd) != 0) { + if(unlikely(pthread_create(&cd->thread, NULL, pluginsd_worker_thread, cd) != 0)) { error("CHARTS.D: failed to create new thread for chart.d %s.", cd->filename); cd->obsolete = 1; } - else if(pthread_detach(cd->thread) != 0) + else if(unlikely(pthread_detach(cd->thread) != 0)) error("CHARTS.D: Cannot request detach of newly created thread for chart.d %s.", cd->filename); } diff --git a/src/popen.c b/src/popen.c index aaaf6b47..dbc55c1b 100755 --- a/src/popen.c +++ b/src/popen.c @@ -6,6 +6,8 @@ #include "log.h" #include "popen.h" +#include "common.h" + /* struct mypopen { pid_t pid; diff --git a/src/proc_diskstats.c b/src/proc_diskstats.c index e2bb72bc..fcdf51d2 100755 --- a/src/proc_diskstats.c +++ b/src/proc_diskstats.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/proc_interrupts.c b/src/proc_interrupts.c index 700bea97..c402e976 100755 --- a/src/proc_interrupts.c +++ b/src/proc_interrupts.c @@ -4,6 +4,7 @@ #include #include +#include "common.h" #include "config.h" #include "procfile.h" #include "rrd.h" diff --git a/src/proc_meminfo.c b/src/proc_meminfo.c index 010767cf..ab9a80d1 100755 --- a/src/proc_meminfo.c +++ b/src/proc_meminfo.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/proc_net_dev.c b/src/proc_net_dev.c index 62837a91..2416c752 100755 --- a/src/proc_net_dev.c +++ b/src/proc_net_dev.c @@ -2,6 +2,7 @@ #include #include +#include "common.h" #include "config.h" #include "procfile.h" #include "rrd.h" diff --git a/src/proc_net_ip_vs_stats.c b/src/proc_net_ip_vs_stats.c index 6b5cd6f6..862cc51d 100755 --- a/src/proc_net_ip_vs_stats.c +++ b/src/proc_net_ip_vs_stats.c @@ -2,6 +2,7 @@ #include #include +#include "common.h" #include "config.h" #include "procfile.h" #include "rrd.h" diff --git a/src/proc_net_netstat.c b/src/proc_net_netstat.c index 5f91e7bb..0b5c3938 100755 --- a/src/proc_net_netstat.c +++ b/src/proc_net_netstat.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/proc_net_rpc_nfsd.c b/src/proc_net_rpc_nfsd.c index 99ac0b10..ca75edd6 100644 --- a/src/proc_net_rpc_nfsd.c +++ b/src/proc_net_rpc_nfsd.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/proc_net_snmp.c b/src/proc_net_snmp.c index 82f2c801..4efd2483 100755 --- a/src/proc_net_snmp.c +++ b/src/proc_net_snmp.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/proc_net_stat_conntrack.c b/src/proc_net_stat_conntrack.c index ebb2350b..5ffa5da9 100755 --- a/src/proc_net_stat_conntrack.c +++ b/src/proc_net_stat_conntrack.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/proc_stat.c b/src/proc_stat.c index a24eef24..a2972599 100755 --- a/src/proc_stat.c +++ b/src/proc_stat.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/proc_sys_kernel_random_entropy_avail.c b/src/proc_sys_kernel_random_entropy_avail.c index cb6154b4..0488f5b6 100755 --- a/src/proc_sys_kernel_random_entropy_avail.c +++ b/src/proc_sys_kernel_random_entropy_avail.c @@ -2,6 +2,7 @@ #include #include +#include "common.h" #include "config.h" #include "procfile.h" #include "rrd.h" diff --git a/src/proc_vmstat.c b/src/proc_vmstat.c index 7c2476ec..0842ebe0 100755 --- a/src/proc_vmstat.c +++ b/src/proc_vmstat.c @@ -4,6 +4,7 @@ #include #include +#include "common.h" #include "log.h" #include "config.h" #include "procfile.h" diff --git a/src/procfile.c b/src/procfile.c index 101da83d..f2269457 100755 --- a/src/procfile.c +++ b/src/procfile.c @@ -15,6 +15,7 @@ #include #include +#include "common.h" #include "log.h" #include "procfile.h" @@ -39,11 +40,11 @@ size_t procfile_max_allocation = PROCFILE_INCREMENT_BUFFER; pfwords *pfwords_add(pfwords *fw, char *str) { // debug(D_PROCFILE, PF_PREFIX ": adding word No %d: '%s'", fw->len, str); - if(fw->len == fw->size) { + if(unlikely(fw->len == fw->size)) { // debug(D_PROCFILE, PF_PREFIX ": expanding words"); pfwords *new = realloc(fw, sizeof(pfwords) + (fw->size + PFWORDS_INCREASE_STEP) * sizeof(char *)); - if(!new) { + if(unlikely(!new)) { error(PF_PREFIX ": failed to expand words"); free(fw); return NULL; @@ -63,7 +64,7 @@ pfwords *pfwords_new(void) { uint32_t size = (procfile_adaptive_initial_allocation) ? procfile_max_words : PFWORDS_INCREASE_STEP; pfwords *new = malloc(sizeof(pfwords) + size * sizeof(char *)); - if(!new) return NULL; + if(unlikely(!new)) return NULL; new->len = 0; new->size = size; @@ -88,11 +89,11 @@ void pfwords_free(pfwords *fw) { pflines *pflines_add(pflines *fl, uint32_t first_word) { // debug(D_PROCFILE, PF_PREFIX ": adding line %d at word %d", fl->len, first_word); - if(fl->len == fl->size) { + if(unlikely(fl->len == fl->size)) { // debug(D_PROCFILE, PF_PREFIX ": expanding lines"); pflines *new = realloc(fl, sizeof(pflines) + (fl->size + PFLINES_INCREASE_STEP) * sizeof(ffline)); - if(!new) { + if(unlikely(!new)) { error(PF_PREFIX ": failed to expand lines"); free(fl); return NULL; @@ -110,10 +111,10 @@ pflines *pflines_add(pflines *fl, uint32_t first_word) { pflines *pflines_new(void) { // debug(D_PROCFILE, PF_PREFIX ": initializing lines"); - uint32_t size = (procfile_adaptive_initial_allocation) ? procfile_max_words : PFLINES_INCREASE_STEP; + uint32_t size = (unlikely(procfile_adaptive_initial_allocation)) ? procfile_max_words : PFLINES_INCREASE_STEP; pflines *new = malloc(sizeof(pflines) + size * sizeof(ffline)); - if(!new) return NULL; + if(unlikely(!new)) return NULL; new->len = 0; new->size = size; @@ -143,10 +144,10 @@ void pflines_free(pflines *fl) { void procfile_close(procfile *ff) { debug(D_PROCFILE, PF_PREFIX ": Closing file '%s'", ff->filename); - if(ff->lines) pflines_free(ff->lines); - if(ff->words) pfwords_free(ff->words); + if(likely(ff->lines)) pflines_free(ff->lines); + if(likely(ff->words)) pfwords_free(ff->words); - if(ff->fd != -1) close(ff->fd); + if(likely(ff->fd != -1)) close(ff->fd); free(ff); } @@ -158,12 +159,12 @@ procfile *procfile_parser(procfile *ff) { e += ff->len; ff->lines = pflines_add(ff->lines, w); - if(!ff->lines) goto cleanup; + if(unlikely(!ff->lines)) goto cleanup; - while(s < e) { + while(likely(s < e)) { switch(ff->separators[(int)(*s)]) { case PF_CHAR_IS_SEPARATOR: - if(s == t) { + if(likely(s == t)) { // skip all leading white spaces t = ++s; continue; @@ -173,7 +174,7 @@ procfile *procfile_parser(procfile *ff) { *s = '\0'; ff->words = pfwords_add(ff->words, t); - if(!ff->words) goto cleanup; + if(unlikely(!ff->words)) goto cleanup; ff->lines->lines[l].words++; w++; @@ -186,7 +187,7 @@ procfile *procfile_parser(procfile *ff) { *s = '\0'; ff->words = pfwords_add(ff->words, t); - if(!ff->words) goto cleanup; + if(unlikely(!ff->words)) goto cleanup; ff->lines->lines[l].words++; w++; @@ -194,7 +195,7 @@ procfile *procfile_parser(procfile *ff) { // debug(D_PROCFILE, PF_PREFIX ": ended line %d with %d words", l, ff->lines->lines[l].words); ff->lines = pflines_add(ff->lines, w); - if(!ff->lines) goto cleanup; + if(unlikely(!ff->lines)) goto cleanup; l++; t = ++s; @@ -206,16 +207,16 @@ procfile *procfile_parser(procfile *ff) { } } - if(s != t) { + if(likely(s != t)) { // the last word - if(ff->len < ff->size) *s = '\0'; + if(likely(ff->len < ff->size)) *s = '\0'; else { // we are going to loose the last byte ff->data[ff->size - 1] = '\0'; } ff->words = pfwords_add(ff->words, t); - if(!ff->words) goto cleanup; + if(unlikely(!ff->words)) goto cleanup; ff->lines->lines[l].words++; w++; @@ -235,12 +236,12 @@ procfile *procfile_readall(procfile *ff) { ssize_t s = 0, r = ff->size, x = ff->size; ff->len = 0; - while(r == x) { + while(likely(r == x)) { if(s) { debug(D_PROCFILE, PF_PREFIX ": Expanding data buffer for file '%s'.", ff->filename); procfile *new = realloc(ff, sizeof(procfile) + ff->size + PROCFILE_INCREMENT_BUFFER); - if(!new) { + if(unlikely(!new)) { error(PF_PREFIX ": Cannot allocate memory for file '%s'", ff->filename); procfile_close(ff); return NULL; @@ -252,8 +253,8 @@ procfile *procfile_readall(procfile *ff) { debug(D_PROCFILE, "Reading file '%s', from position %ld with length %ld", ff->filename, s, ff->size - s); r = read(ff->fd, &ff->data[s], ff->size - s); - if(r == -1) { - if(!(ff->flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO)) error(PF_PREFIX ": Cannot read from file '%s'", ff->filename); + if(unlikely(r == -1)) { + if(unlikely(!(ff->flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO))) error(PF_PREFIX ": Cannot read from file '%s'", ff->filename); procfile_close(ff); return NULL; } @@ -263,8 +264,8 @@ procfile *procfile_readall(procfile *ff) { } debug(D_PROCFILE, "Rewinding file '%s'", ff->filename); - if(lseek(ff->fd, 0, SEEK_SET) == -1) { - if(!(ff->flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO)) error(PF_PREFIX ": Cannot rewind on file '%s'.", ff->filename); + if(unlikely(lseek(ff->fd, 0, SEEK_SET) == -1)) { + if(unlikely(!(ff->flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO))) error(PF_PREFIX ": Cannot rewind on file '%s'.", ff->filename); procfile_close(ff); return NULL; } @@ -274,10 +275,10 @@ procfile *procfile_readall(procfile *ff) { ff = procfile_parser(ff); - if(procfile_adaptive_initial_allocation) { - if(ff->len > procfile_max_allocation) procfile_max_allocation = ff->len; - if(ff->lines->len > procfile_max_lines) procfile_max_lines = ff->lines->len; - if(ff->words->len > procfile_max_words) procfile_max_words = ff->words->len; + if(unlikely(procfile_adaptive_initial_allocation)) { + if(unlikely(ff->len > procfile_max_allocation)) procfile_max_allocation = ff->len; + if(unlikely(ff->lines->len > procfile_max_lines)) procfile_max_lines = ff->lines->len; + if(unlikely(ff->words->len > procfile_max_words)) procfile_max_words = ff->words->len; } debug(D_PROCFILE, "File '%s' updated.", ff->filename); @@ -288,41 +289,41 @@ static void procfile_set_separators(procfile *ff, const char *separators) { static char def[256] = { [0 ... 255] = 0 }; int i; - if(!def[255]) { + if(unlikely(!def[255])) { // this is thread safe // we check that the last byte is non-zero // if it is zero, multiple threads may be executing this at the same time // setting in def[] the exact same values - for(i = 0; i < 256 ;i++) { - if(i == '\n' || i == '\r') def[i] = PF_CHAR_IS_NEWLINE; - else if(isspace(i) || !isprint(i)) def[i] = PF_CHAR_IS_SEPARATOR; + for(i = 0; likely(i < 256) ;i++) { + if(unlikely(i == '\n' || i == '\r')) def[i] = PF_CHAR_IS_NEWLINE; + else if(unlikely(isspace(i) || !isprint(i))) def[i] = PF_CHAR_IS_SEPARATOR; else def[i] = PF_CHAR_IS_WORD; } } // copy the default char *ffs = ff->separators, *ffd = def, *ffe = &def[256]; - while(ffd != ffe) *ffs++ = *ffd++; + while(likely(ffd != ffe)) *ffs++ = *ffd++; // set the separators - if(!separators) separators = " \t=|"; + if(unlikely(!separators)) separators = " \t=|"; ffs = ff->separators; const char *s = separators; - while(*s) ffs[(int)*s++] = PF_CHAR_IS_SEPARATOR; + while(likely(*s)) ffs[(int)*s++] = PF_CHAR_IS_SEPARATOR; } procfile *procfile_open(const char *filename, const char *separators, uint32_t flags) { debug(D_PROCFILE, PF_PREFIX ": Opening file '%s'", filename); int fd = open(filename, O_RDONLY, 0666); - if(fd == -1) { - if(!(flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO)) error(PF_PREFIX ": Cannot open file '%s'", filename); + if(unlikely(fd == -1)) { + if(unlikely(!(flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO))) error(PF_PREFIX ": Cannot open file '%s'", filename); return NULL; } - size_t size = (procfile_adaptive_initial_allocation) ? procfile_max_allocation : PROCFILE_INCREMENT_BUFFER; + size_t size = (unlikely(procfile_adaptive_initial_allocation)) ? procfile_max_allocation : PROCFILE_INCREMENT_BUFFER; procfile *ff = malloc(sizeof(procfile) + size); - if(!ff) { + if(unlikely(!ff)) { error(PF_PREFIX ": Cannot allocate memory for file '%s'", filename); close(fd); return NULL; @@ -339,7 +340,7 @@ procfile *procfile_open(const char *filename, const char *separators, uint32_t f ff->lines = pflines_new(); ff->words = pfwords_new(); - if(!ff->lines || !ff->words) { + if(unlikely(!ff->lines || !ff->words)) { error(PF_PREFIX ": Cannot initialize parser for file '%s'", filename); procfile_close(ff); return NULL; @@ -352,12 +353,12 @@ procfile *procfile_open(const char *filename, const char *separators, uint32_t f } procfile *procfile_reopen(procfile *ff, const char *filename, const char *separators, uint32_t flags) { - if(!ff) return procfile_open(filename, separators, flags); + if(unlikely(!ff)) return procfile_open(filename, separators, flags); - if(ff->fd != -1) close(ff->fd); + if(likely(ff->fd != -1)) close(ff->fd); ff->fd = open(filename, O_RDONLY, 0666); - if(ff->fd == -1) { + if(unlikely(ff->fd == -1)) { procfile_close(ff); return NULL; } @@ -368,7 +369,7 @@ procfile *procfile_reopen(procfile *ff, const char *filename, const char *separa ff->flags = flags; // do not do the separators again if NULL is given - if(separators) procfile_set_separators(ff, separators); + if(likely(separators)) procfile_set_separators(ff, separators); return ff; } @@ -383,12 +384,12 @@ void procfile_print(procfile *ff) { debug(D_PROCFILE, "File '%s' with %d lines and %d words", ff->filename, ff->lines->len, ff->words->len); - for(l = 0; l < lines ;l++) { + for(l = 0; likely(l < lines) ;l++) { words = procfile_linewords(ff, l); debug(D_PROCFILE, " line %d starts at word %d and has %d words", l, ff->lines->lines[l].first, ff->lines->lines[l].words); - for(w = 0; w < words ;w++) { + for(w = 0; likely(w < words) ;w++) { s = procfile_lineword(ff, l, w); debug(D_PROCFILE, " [%d.%d] '%s'", l, w, s); } diff --git a/src/rrd.c b/src/rrd.c index 41847440..2a4cd836 100755 --- a/src/rrd.c +++ b/src/rrd.c @@ -143,9 +143,9 @@ static RRDDIM *rrddim_index_find(RRDSET *st, const char *id, uint32_t hash) { int rrdset_type_id(const char *name) { - if(strcmp(name, RRDSET_TYPE_AREA_NAME) == 0) return RRDSET_TYPE_AREA; - if(strcmp(name, RRDSET_TYPE_STACKED_NAME) == 0) return RRDSET_TYPE_STACKED; - if(strcmp(name, RRDSET_TYPE_LINE_NAME) == 0) return RRDSET_TYPE_LINE; + if(unlikely(strcmp(name, RRDSET_TYPE_AREA_NAME) == 0)) return RRDSET_TYPE_AREA; + else if(unlikely(strcmp(name, RRDSET_TYPE_STACKED_NAME) == 0)) return RRDSET_TYPE_STACKED; + else if(unlikely(strcmp(name, RRDSET_TYPE_LINE_NAME) == 0)) return RRDSET_TYPE_LINE; return RRDSET_TYPE_LINE; } @@ -194,9 +194,9 @@ const char *rrd_memory_mode_name(int id) int rrd_memory_mode_id(const char *name) { - if(!strcmp(name, RRD_MEMORY_MODE_RAM_NAME)) + if(unlikely(!strcmp(name, RRD_MEMORY_MODE_RAM_NAME))) return RRD_MEMORY_MODE_RAM; - else if(!strcmp(name, RRD_MEMORY_MODE_MAP_NAME)) + else if(unlikely(!strcmp(name, RRD_MEMORY_MODE_MAP_NAME))) return RRD_MEMORY_MODE_MAP; return RRD_MEMORY_MODE_SAVE; @@ -660,7 +660,7 @@ void rrdset_save_all(void) } for(rd = st->dimensions; rd ; rd = rd->next) { - if(rd->mapped == RRD_MEMORY_MODE_SAVE) { + if(likely(rd->mapped == RRD_MEMORY_MODE_SAVE)) { debug(D_RRD_CALLS, "Saving dimension '%s' to '%s'.", rd->name, rd->cache_filename); savememory(rd->cache_filename, rd, rd->memsize); } @@ -722,7 +722,7 @@ int rrddim_hide(RRDSET *st, const char *id) debug(D_RRD_CALLS, "rrddim_hide() for chart %s, dimension %s", st->name, id); RRDDIM *rd = rrddim_find(st, id); - if(!rd) { + if(unlikely(!rd)) { error("Cannot find dimension with id '%s' on stats '%s' (%s).", id, st->name, st->id); return 1; } @@ -736,7 +736,7 @@ int rrddim_unhide(RRDSET *st, const char *id) debug(D_RRD_CALLS, "rrddim_unhide() for chart %s, dimension %s", st->name, id); RRDDIM *rd = rrddim_find(st, id); - if(!rd) { + if(unlikely(!rd)) { error("Cannot find dimension with id '%s' on stats '%s' (%s).", id, st->name, st->id); return 1; } @@ -757,7 +757,7 @@ void rrddim_set_by_pointer(RRDSET *st, RRDDIM *rd, collected_number value) int rrddim_set(RRDSET *st, const char *id, collected_number value) { RRDDIM *rd = rrddim_find(st, id); - if(!rd) { + if(unlikely(!rd)) { error("Cannot find dimension with id '%s' on stats '%s' (%s).", id, st->name, st->id); return 1; } @@ -770,7 +770,7 @@ void rrdset_next_usec(RRDSET *st, unsigned long long microseconds) { debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds); - if(st->debug) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds); + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds); st->usec_since_last_update = microseconds; } @@ -778,7 +778,7 @@ void rrdset_next(RRDSET *st) { unsigned long long microseconds = 0; - if(st->last_collected_time.tv_sec) { + if(likely(st->last_collected_time.tv_sec)) { struct timeval now; gettimeofday(&now, NULL); microseconds = usecdiff(&now, &st->last_collected_time); @@ -799,22 +799,22 @@ unsigned long long rrdset_done(RRDSET *st) RRDDIM *rd, *last; int oldstate, store_this_entry = 1; - if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) != 0) + if(unlikely(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) != 0)) error("Cannot set pthread cancel state to DISABLE."); // a read lock is OK here pthread_rwlock_rdlock(&st->rwlock); // check if the chart has a long time to be refreshed - if(st->usec_since_last_update > st->entries * st->update_every * 1000000ULL) { + if(unlikely(st->usec_since_last_update > st->entries * st->update_every * 1000000ULL)) { info("%s: took too long to be updated (%0.3Lf secs). Reseting it.", st->name, (long double)(st->usec_since_last_update / 1000000.0)); rrdset_reset(st); st->usec_since_last_update = st->update_every * 1000000ULL; } - if(st->debug) debug(D_RRD_STATS, "%s: microseconds since last update: %llu", st->name, st->usec_since_last_update); + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: microseconds since last update: %llu", st->name, st->usec_since_last_update); // set last_collected_time - if(!st->last_collected_time.tv_sec) { + if(unlikely(!st->last_collected_time.tv_sec)) { // it is the first entry // set the last_collected_time to now gettimeofday(&st->last_collected_time, NULL); @@ -822,7 +822,7 @@ unsigned long long rrdset_done(RRDSET *st) // the first entry should not be stored store_this_entry = 0; - if(st->debug) debug(D_RRD_STATS, "%s: initializing last_collected to now. Will not store the next entry.", st->name); + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: initializing last_collected to now. Will not store the next entry.", st->name); } else { // it is not the first entry @@ -834,7 +834,7 @@ unsigned long long rrdset_done(RRDSET *st) // if this set has not been updated in the past // we fake the last_update time to be = now - usec_since_last_update - if(!st->last_updated.tv_sec) { + if(unlikely(!st->last_updated.tv_sec)) { // it has never been updated before // set a fake last_updated, in the past using usec_since_last_update unsigned long long ut = st->last_collected_time.tv_sec * 1000000ULL + st->last_collected_time.tv_usec - st->usec_since_last_update; @@ -844,11 +844,11 @@ unsigned long long rrdset_done(RRDSET *st) // the first entry should not be stored store_this_entry = 0; - if(st->debug) debug(D_RRD_STATS, "%s: initializing last_updated to now - %llu microseconds (%0.3Lf). Will not store the next entry.", st->name, st->usec_since_last_update, (long double)ut/1000000.0); + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: initializing last_updated to now - %llu microseconds (%0.3Lf). Will not store the next entry.", st->name, st->usec_since_last_update, (long double)ut/1000000.0); } // check if we will re-write the entire data set - if(usecdiff(&st->last_collected_time, &st->last_updated) > st->update_every * st->entries * 1000000ULL) { + if(unlikely(usecdiff(&st->last_collected_time, &st->last_updated) > st->update_every * st->entries * 1000000ULL)) { info("%s: too old data (last updated at %u.%u, last collected at %u.%u). Reseting it. Will not store the next entry.", st->name, st->last_updated.tv_sec, st->last_updated.tv_usec, st->last_collected_time.tv_sec, st->last_collected_time.tv_usec); rrdset_reset(st); @@ -872,20 +872,22 @@ unsigned long long rrdset_done(RRDSET *st) unsigned long long now_ut = st->last_collected_time.tv_sec * 1000000ULL + st->last_collected_time.tv_usec; unsigned long long next_ut = (st->last_updated.tv_sec + st->update_every) * 1000000ULL; - if(st->debug) debug(D_RRD_STATS, "%s: last ut = %0.3Lf (last updated time)", st->name, (long double)last_ut/1000000.0); - if(st->debug) debug(D_RRD_STATS, "%s: now ut = %0.3Lf (current update time)", st->name, (long double)now_ut/1000000.0); - if(st->debug) debug(D_RRD_STATS, "%s: next ut = %0.3Lf (next interpolation point)", st->name, (long double)next_ut/1000000.0); + if(unlikely(st->debug)) { + debug(D_RRD_STATS, "%s: last ut = %0.3Lf (last updated time)", st->name, (long double)last_ut/1000000.0); + debug(D_RRD_STATS, "%s: now ut = %0.3Lf (current update time)", st->name, (long double)now_ut/1000000.0); + debug(D_RRD_STATS, "%s: next ut = %0.3Lf (next interpolation point)", st->name, (long double)next_ut/1000000.0); + } - if(!st->counter_done) { + if(unlikely(!st->counter_done)) { store_this_entry = 0; - if(st->debug) debug(D_RRD_STATS, "%s: Will not store the next entry.", st->name); + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: Will not store the next entry.", st->name); } st->counter_done++; // calculate totals and count the dimensions int dimensions; st->collected_total = 0; - for( rd = st->dimensions, dimensions = 0 ; rd ; rd = rd->next, dimensions++ ) + for( rd = st->dimensions, dimensions = 0 ; likely(rd) ; rd = rd->next, dimensions++ ) st->collected_total += rd->collected_value; uint32_t storage_flags = SN_EXISTS; @@ -893,9 +895,9 @@ unsigned long long rrdset_done(RRDSET *st) // process all dimensions to calculate their values // based on the collected figures only // at this stage we do not interpolate anything - for( rd = st->dimensions ; rd ; rd = rd->next ) { + for( rd = st->dimensions ; likely(rd) ; rd = rd->next ) { - if(st->debug) debug(D_RRD_STATS, "%s/%s: " + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: " " last_collected_value = " COLLECTED_NUMBER_FORMAT " collected_value = " COLLECTED_NUMBER_FORMAT " last_calculated_value = " CALCULATED_NUMBER_FORMAT @@ -911,13 +913,13 @@ unsigned long long rrdset_done(RRDSET *st) case RRDDIM_PCENT_OVER_DIFF_TOTAL: // the percentage of the current increment // over the increment of all dimensions together - if(st->collected_total == st->last_collected_total) rd->calculated_value = rd->last_calculated_value; + if(unlikely(st->collected_total == st->last_collected_total)) rd->calculated_value = rd->last_calculated_value; else rd->calculated_value = (calculated_number)100 * (calculated_number)(rd->collected_value - rd->last_collected_value) / (calculated_number)(st->collected_total - st->last_collected_total); - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: CALC PCENT-DIFF " CALCULATED_NUMBER_FORMAT " = 100" " * (" COLLECTED_NUMBER_FORMAT " - " COLLECTED_NUMBER_FORMAT ")" @@ -930,7 +932,7 @@ unsigned long long rrdset_done(RRDSET *st) break; case RRDDIM_PCENT_OVER_ROW_TOTAL: - if(!st->collected_total) rd->calculated_value = 0; + if(unlikely(!st->collected_total)) rd->calculated_value = 0; else // the percentage of the current value // over the total of all dimensions @@ -939,7 +941,7 @@ unsigned long long rrdset_done(RRDSET *st) * (calculated_number)rd->collected_value / (calculated_number)st->collected_total; - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: CALC PCENT-ROW " CALCULATED_NUMBER_FORMAT " = 100" " * " COLLECTED_NUMBER_FORMAT @@ -954,7 +956,7 @@ unsigned long long rrdset_done(RRDSET *st) case RRDDIM_INCREMENTAL: // if the new is smaller than the old (an overflow, or reset), set the old equal to the new // to reset the calculation (it will give zero as the calculation for this second) - if(rd->last_collected_value > rd->collected_value) { + if(unlikely(rd->last_collected_value > rd->collected_value)) { info("%s.%s: Detect RESET or OVERFLOW. Last collected value = " COLLECTED_NUMBER_FORMAT ", current = " COLLECTED_NUMBER_FORMAT , st->name, rd->name , rd->last_collected_value @@ -965,7 +967,7 @@ unsigned long long rrdset_done(RRDSET *st) rd->calculated_value += (calculated_number)(rd->collected_value - rd->last_collected_value); - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: CALC INC " CALCULATED_NUMBER_FORMAT " += " COLLECTED_NUMBER_FORMAT " - " COLLECTED_NUMBER_FORMAT @@ -978,7 +980,7 @@ unsigned long long rrdset_done(RRDSET *st) case RRDDIM_ABSOLUTE: rd->calculated_value = (calculated_number)rd->collected_value; - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: CALC ABS/ABS-NO-IN " CALCULATED_NUMBER_FORMAT " = " COLLECTED_NUMBER_FORMAT @@ -993,7 +995,7 @@ unsigned long long rrdset_done(RRDSET *st) // it gets noticed when we add new types rd->calculated_value = 0; - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: CALC " CALCULATED_NUMBER_FORMAT " = 0" , st->id, rd->name @@ -1009,16 +1011,18 @@ unsigned long long rrdset_done(RRDSET *st) unsigned long long first_ut = last_ut; int iterations = (now_ut - last_ut) / (st->update_every * 1000000ULL); - for( ; next_ut <= now_ut ; next_ut += st->update_every * 1000000ULL, iterations-- ) { + for( ; likely(next_ut <= now_ut) ; next_ut += st->update_every * 1000000ULL, iterations-- ) { if(iterations < 0) error("iterations calculation wrapped!"); - if(st->debug) debug(D_RRD_STATS, "%s: last ut = %0.3Lf (last updated time)", st->name, (long double)last_ut/1000000.0); - if(st->debug) debug(D_RRD_STATS, "%s: next ut = %0.3Lf (next interpolation point)", st->name, (long double)next_ut/1000000.0); + if(unlikely(st->debug)) { + debug(D_RRD_STATS, "%s: last ut = %0.3Lf (last updated time)", st->name, (long double)last_ut/1000000.0); + debug(D_RRD_STATS, "%s: next ut = %0.3Lf (next interpolation point)", st->name, (long double)next_ut/1000000.0); + } st->last_updated.tv_sec = next_ut / 1000000ULL; st->last_updated.tv_usec = 0; - for( rd = st->dimensions ; rd ; rd = rd->next ) { + for( rd = st->dimensions ; likely(rd) ; rd = rd->next ) { calculated_number new_value; switch(rd->algorithm) { @@ -1029,7 +1033,7 @@ unsigned long long rrdset_done(RRDSET *st) / (calculated_number)(now_ut - last_ut) ); - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: CALC2 INC " CALCULATED_NUMBER_FORMAT " = " CALCULATED_NUMBER_FORMAT @@ -1057,7 +1061,7 @@ unsigned long long rrdset_done(RRDSET *st) + rd->last_calculated_value ); - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: CALC2 DEF " CALCULATED_NUMBER_FORMAT " = (((" "(" CALCULATED_NUMBER_FORMAT " - " CALCULATED_NUMBER_FORMAT ")" @@ -1070,23 +1074,23 @@ unsigned long long rrdset_done(RRDSET *st) , (now_ut - first_ut), rd->last_calculated_value ); - if(next_ut + st->update_every * 1000000ULL > now_ut) rd->calculated_value = new_value; + if(likely(next_ut + st->update_every * 1000000ULL > now_ut)) rd->calculated_value = new_value; break; } - if(!store_this_entry) { + if(unlikely(!store_this_entry)) { store_this_entry = 1; continue; } - if(rd->updated && iterations < st->gap_when_lost_iterations_above) { + if(likely(rd->updated && iterations < st->gap_when_lost_iterations_above)) { rd->values[st->current_entry] = pack_storage_number( new_value * (calculated_number)rd->multiplier / (calculated_number)rd->divisor , storage_flags ); - if(st->debug) + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: STORE[%ld] " CALCULATED_NUMBER_FORMAT " = " CALCULATED_NUMBER_FORMAT " * %ld" @@ -1099,14 +1103,14 @@ unsigned long long rrdset_done(RRDSET *st) ); } else { - if(st->debug) debug(D_RRD_STATS, "%s/%s: STORE[%ld] = NON EXISTING " + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: STORE[%ld] = NON EXISTING " , st->id, rd->name , st->current_entry ); rd->values[st->current_entry] = pack_storage_number(0, SN_NOT_EXISTS); } - if(st->debug) { + if(unlikely(st->debug)) { calculated_number t1 = new_value * (calculated_number)rd->multiplier / (calculated_number)rd->divisor; calculated_number t2 = unpack_storage_number(rd->values[st->current_entry]); calculated_number accuracy = accuracy_loss(t1, t2); @@ -1137,7 +1141,7 @@ unsigned long long rrdset_done(RRDSET *st) // reset the storage flags for the next point, if any; storage_flags = SN_EXISTS; - if(st->first_entry_t && st->counter >= (unsigned long long)st->entries) { + if(unlikely(st->first_entry_t && st->counter >= (unsigned long long)st->entries)) { // the db is overwriting values // add the value we will overwrite st->first_entry_t += st->update_every * 1000000ULL; @@ -1145,12 +1149,12 @@ unsigned long long rrdset_done(RRDSET *st) st->counter++; st->current_entry = ((st->current_entry + 1) >= st->entries) ? 0 : st->current_entry + 1; - if(!st->first_entry_t) st->first_entry_t = next_ut; + if(unlikely(!st->first_entry_t)) st->first_entry_t = next_ut; last_ut = next_ut; } - for( rd = st->dimensions; rd ; rd = rd->next ) { - if(!rd->updated) continue; + for( rd = st->dimensions; likely(rd) ; rd = rd->next ) { + if(unlikely(!rd->updated)) continue; rd->last_collected_value = rd->collected_value; rd->last_calculated_value = rd->calculated_value; rd->collected_value = 0; @@ -1159,7 +1163,7 @@ unsigned long long rrdset_done(RRDSET *st) // if this is the first entry of incremental dimensions // we have to set the first calculated_value to zero // to eliminate the first spike - if(st->counter_done == 1) switch(rd->algorithm) { + if(unlikely(st->counter_done == 1)) switch(rd->algorithm) { case RRDDIM_PCENT_OVER_DIFF_TOTAL: case RRDDIM_INCREMENTAL: rd->calculated_value = 0; @@ -1173,25 +1177,25 @@ unsigned long long rrdset_done(RRDSET *st) // -------------------------------------------------------------------- // find if there are any obsolete dimensions (not updated recently) - if(rrd_delete_unupdated_dimensions) { + if(unlikely(rrd_delete_unupdated_dimensions)) { - for( rd = st->dimensions; rd ; rd = rd->next ) + for( rd = st->dimensions; likely(rd) ; rd = rd->next ) if((rd->last_collected_time.tv_sec + (rrd_delete_unupdated_dimensions * st->update_every)) < st->last_collected_time.tv_sec) break; - if(rd) { + if(unlikely(rd)) { // there is dimension to free // upgrade our read lock to a write lock pthread_rwlock_unlock(&st->rwlock); pthread_rwlock_wrlock(&st->rwlock); - for( rd = st->dimensions, last = NULL ; rd ; ) { + for( rd = st->dimensions, last = NULL ; likely(rd) ; ) { // remove it only it is not updated in rrd_delete_unupdated_dimensions seconds - if((rd->last_collected_time.tv_sec + (rrd_delete_unupdated_dimensions * st->update_every)) < st->last_collected_time.tv_sec) { - debug(D_RRD_STATS, "Removing obsolete dimension '%s' (%s) of '%s' (%s).", rd->name, rd->id, st->name, st->id); + if(unlikely((rd->last_collected_time.tv_sec + (rrd_delete_unupdated_dimensions * st->update_every)) < st->last_collected_time.tv_sec)) { + info("Removing obsolete dimension '%s' (%s) of '%s' (%s).", rd->name, rd->id, st->name, st->id); - if(!last) { + if(unlikely(!last)) { st->dimensions = rd->next; rd->next = NULL; rrddim_free(st, rd); @@ -1211,13 +1215,16 @@ unsigned long long rrdset_done(RRDSET *st) rd = rd->next; } - if(!st->dimensions) st->enabled = 0; + if(unlikely(!st->dimensions)) { + info("Disabling chart %s (%s) since it does not have any dimensions", st->name, st->id); + st->enabled = 0; + } } } pthread_rwlock_unlock(&st->rwlock); - if(pthread_setcancelstate(oldstate, NULL) != 0) + if(unlikely(pthread_setcancelstate(oldstate, NULL) != 0)) error("Cannot set pthread cancel state to RESTORE (%d).", oldstate); return(st->usec_since_last_update); @@ -1227,7 +1234,7 @@ unsigned long long rrdset_done(RRDSET *st) // find the oldest entry in the data, skipping all empty slots time_t rrdset_first_entry_t(RRDSET *st) { - if(!st->first_entry_t) return st->last_updated.tv_sec; + if(unlikely(!st->first_entry_t)) return st->last_updated.tv_sec; return st->first_entry_t / 1000000; } diff --git a/src/storage_number.c b/src/storage_number.c index ccfff1e5..e3751299 100755 --- a/src/storage_number.c +++ b/src/storage_number.c @@ -2,6 +2,7 @@ #include #endif +#include "common.h" #include "log.h" #include "storage_number.h" diff --git a/src/unit_test.c b/src/unit_test.c index f5ccc8fe..ca5983a7 100755 --- a/src/unit_test.c +++ b/src/unit_test.c @@ -3,6 +3,7 @@ #include #include +#include "common.h" #include "storage_number.h" #include "rrd.h" #include "log.h" diff --git a/src/url.c b/src/url.c index a231534f..c8c09210 100755 --- a/src/url.c +++ b/src/url.c @@ -2,6 +2,7 @@ #include #include +#include "common.h" #include "log.h" #include "url.h"