#!/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
return 0
}
+# _create is called once, to create the charts
example_create() {
-# create the chart with 3 dimensions
-cat <<EOF
+ # create the chart with 3 dimensions
+ cat <<EOF
CHART example.random '' "Random Numbers Stacked Chart" "% of random numbers" random random stacked 5000 $example_update_every
DIMENSION random1 '' percentage-of-absolute-row 1 1
DIMENSION random2 '' percentage-of-absolute-row 1 1
return 0
}
+# _update is called continiously, to collect the values
example_update() {
# the first argument to this function is the microseconds since last update
# pass this parameter to the BEGIN statement (see bellow).
# for each dimension
# remember: KEEP IT SIMPLE AND SHORT
- # 1. wget the counters page from squid
- # 2. sed to remove spaces; replace . with _; remove spaces around =; prepend each line with: local squid_
- # 3. egrep lines starting with:
- # local squid_client_http_ then one or more of these a-z 0-9 _ then = and one of more of 0-9
- # local squid_server_all_ then one or more of these a-z 0-9 _ then = and one of more of 0-9
- # 4. then execute this as a script with the eval
- #
- # be very carefull with eval:
- # prepare the script and always grep at the end the lines that are usefull, so that
- # even if something goes wrong, no other code can be executed
-
local cpuTemp=$(cat /sys/class/thermal/thermal_zone0/temp)
local cpuSpeed=$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq)
squid_update_every=5
squid_get_stats() {
-nc $squid_host $squid_port <<EOF
+ nc $squid_host $squid_port <<EOF
GET $squid_url HTTP/1.0
Host: $squid_host:$squid_port
Accept: */*
# for each dimension
# remember: KEEP IT SIMPLE AND SHORT
- # 1. wget the counters page from squid
+ # 1. get the counters page from squid
# 2. sed to remove spaces; replace . with _; remove spaces around =; prepend each line with: local squid_
# 3. egrep lines starting with:
# local squid_client_http_ then one or more of these a-z 0-9 _ then = and one of more of 0-9
if [ -f "$chartsd/$1.chart.sh" ]
then
debug=1
- chart_only="`echo $1.chart.sh | sed "s/\.chart\.sh$//g"`"
+ chart_only="$( echo $1.chart.sh | sed "s/\.chart\.sh$//g" )"
shift
continue
fi
if [ -f "$chartsd/$1" ]
then
debug=1
- chart_only="`echo $1 | sed "s/\.chart\.sh$//g"`"
+ chart_only="$( echo $1 | sed "s/\.chart\.sh$//g" )"
shift
continue
fi
if [ -f "$1" ]
then
debug=1
- chart_only="`basename "$1" | sed "s/\.chart\.sh$//g"`"
+ chart_only="$( basename "$1" | sed "s/\.chart\.sh$//g" )"
shift
continue
fi
}
# if found and included, this file overwrites loopsleepms()
# with a high resolution timer function for precise looping.
-. "`dirname $0`/loopsleepms.sh.inc"
+. "$( dirname $0 )/loopsleepms.sh.inc"
# -----------------------------------------------------------------------------
# find all enabled charts
- for chart in `all_charts`
+ for chart in $( all_charts )
do
eval "enabled=\$$chart"
if [ "$enabled" = "yes" ]
for chart in $charts
do
# check the enabled charts
- local check="`cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_check()"`"
+ local check="$( cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_check()" )"
if [ -z "$check" ]
then
echo >&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."
# 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
suffix_update_every="_update_every"
active_charts=
-for chart in `all_enabled_charts`
+for chart in $( all_enabled_charts )
do
. "$chartsd/$chart.chart.sh"
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
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 */
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);
}
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)) {
#include <pthread.h>
+#include "common.h"
#include "global_statistics.h"
struct global_statistics global_statistics = { 0ULL, 0ULL, 0ULL, 0ULL };
#include <stdlib.h>
#include "log.h"
+#include "common.h"
+
// ----------------------------------------------------------------------------
// LOG
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)
#include <sys/types.h>
#include <sys/wait.h>
+#include "common.h"
#include "log.h"
#include "daemon.h"
#include "web_server.h"
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
}
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;
}
}
// terminate the words
- while(i < max_words) words[i++] = NULL;
+ while(likely(i < max_words)) words[i++] = NULL;
}
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;
}
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;
}
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:"<nothing>", value?value:"<nothing>");
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);
}
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];
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);
}
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:""
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];
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);
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:""
);
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;
}
// 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;
}
// 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;
}
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;
}
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);
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);
}
#include "log.h"
#include "popen.h"
+#include "common.h"
+
/*
struct mypopen {
pid_t pid;
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <string.h>
#include <ctype.h>
+#include "common.h"
#include "config.h"
#include "procfile.h"
#include "rrd.h"
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <stdio.h>
#include <stdlib.h>
+#include "common.h"
#include "config.h"
#include "procfile.h"
#include "rrd.h"
#include <stdio.h>
#include <stdlib.h>
+#include "common.h"
#include "config.h"
#include "procfile.h"
#include "rrd.h"
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <stdio.h>
#include <stdlib.h>
+#include "common.h"
#include "config.h"
#include "procfile.h"
#include "rrd.h"
#include <string.h>
#include <unistd.h>
+#include "common.h"
#include "log.h"
#include "config.h"
#include "procfile.h"
#include <sys/stat.h>
#include <sys/mman.h>
+#include "common.h"
#include "log.h"
#include "procfile.h"
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;
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;
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;
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;
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);
}
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;
*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++;
*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++;
// 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;
}
}
- 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++;
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;
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;
}
}
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;
}
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);
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;
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;
}
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;
}
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;
}
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);
}
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;
}
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;
}
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);
}
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;
}
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;
}
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;
}
{
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;
}
{
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);
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);
// 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
// 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;
// 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);
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;
// 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
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 ")"
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
* (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
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
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
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
// 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
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) {
/ (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
+ 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 ")"
, (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"
);
}
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);
// 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;
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;
// 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;
// --------------------------------------------------------------------
// 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);
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);
// 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;
}
#include <math.h>
#endif
+#include "common.h"
#include "log.h"
#include "storage_number.h"
#include <string.h>
#include <sys/resource.h>
+#include "common.h"
#include "storage_number.h"
#include "rrd.h"
#include "log.h"
#include <string.h>
#include <ctype.h>
+#include "common.h"
#include "log.h"
#include "url.h"