Merge branch 'master' into ff/subsecond
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sun, 31 Oct 2010 16:15:06 +0000 (17:15 +0100)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sun, 31 Oct 2010 16:15:06 +0000 (17:15 +0100)
1  2 
src/collectd.h
src/network.c
src/perl.c
src/plugin.c
src/plugin.h
src/rrdtool.c

diff --combined src/collectd.h
  #if HAVE_STDINT_H
  # include <stdint.h>
  #endif
- #if HAVE_STDBOOL_H
- # include <stdbool.h>
- #else
- # ifndef HAVE__BOOL
- #  ifdef __cplusplus
- typedef bool _Bool;
- #  else
- #   define _Bool signed char
- #  endif
- # endif
- # define bool _Bool
- # define false 0
- # define true 1
- # define __bool_true_false_are_defined 1
- #endif
  #if HAVE_UNISTD_H
  # include <unistd.h>
  #endif
  # endif
  #endif
  
 +/* Type for time as used by "utils_time.h" */
 +typedef uint64_t cdtime_t;
 +
  extern char hostname_g[];
  extern int  interval_g;
  extern int  timeout_g;
diff --combined src/network.c
@@@ -319,30 -319,30 +319,30 @@@ static _Bool check_receive_okay (const 
    /* This is a value we already sent. Don't allow it to be received again in
     * order to avoid looping. */
    if ((status == 0) && (time_sent >= ((uint64_t) vl->time)))
-     return (false);
+     return (0);
  
-   return (true);
+   return (1);
  } /* }}} _Bool check_receive_okay */
  
  static _Bool check_send_okay (const value_list_t *vl) /* {{{ */
  {
-   _Bool received = false;
+   _Bool received = 0;
    int status;
  
    if (network_config_forward != 0)
-     return (true);
+     return (1);
  
    if (vl->meta == NULL)
-     return (true);
+     return (1);
  
    status = meta_data_get_boolean (vl->meta, "network:received", &received);
    if (status == -ENOENT)
-     return (true);
+     return (1);
    else if (status != 0)
    {
      ERROR ("network plugin: check_send_okay: meta_data_get_boolean failed "
        "with status %i.", status);
-     return (true);
+     return (1);
    }
  
    /* By default, only *send* value lists that were not *received* by the
@@@ -383,7 -383,7 +383,7 @@@ static int network_dispatch_values (val
      return (-ENOMEM);
    }
  
-   status = meta_data_add_boolean (vl->meta, "network:received", true);
+   status = meta_data_add_boolean (vl->meta, "network:received", 1);
    if (status != 0)
    {
      ERROR ("network plugin: meta_data_add_boolean failed.");
@@@ -1377,8 -1377,8 +1377,8 @@@ static int parse_packet (sockent_t *se
                                        &tmp);
                        if (status == 0)
                        {
 -                              vl.time = (time_t) tmp;
 -                              n.time = (time_t) tmp;
 +                              vl.time = TIME_T_TO_CDTIME_T (tmp);
 +                              n.time = TIME_T_TO_CDTIME_T (tmp);
                        }
                }
                else if (pkg_type == TYPE_INTERVAL)
@@@ -2583,9 -2583,8 +2583,9 @@@ static int add_to_buffer (char *buffer
  
        if (vl_def->time != vl->time)
        {
 +              time_t tmp = CDTIME_T_TO_TIME_T (vl->time);
                if (write_part_number (&buffer, &buffer_size, TYPE_TIME,
 -                                      (uint64_t) vl->time))
 +                                      (uint64_t) tmp))
                        return (-1);
                vl_def->time = vl->time;
        }
@@@ -3071,14 -3070,12 +3071,14 @@@ static int network_notification (const 
    char *buffer_ptr = buffer;
    int   buffer_free = sizeof (buffer);
    int   status;
 +  time_t tmp;
  
    memset (buffer, '\0', sizeof (buffer));
  
  
 +  tmp = CDTIME_T_TO_TIME_T (n->time);
    status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME,
 -      (uint64_t) n->time);
 +      (uint64_t) tmp);
    if (status != 0)
      return (-1);
  
@@@ -3259,13 -3256,13 +3259,13 @@@ static int network_stats_read (void) /
  
  static int network_init (void)
  {
-       static _Bool have_init = false;
+       static _Bool have_init = 0;
  
        /* Check if we were already initialized. If so, just return - there's
         * nothing more to do (for now, that is). */
        if (have_init)
                return (0);
-       have_init = true;
+       have_init = 1;
  
  #if HAVE_LIBGCRYPT
        gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
   * just send the buffer if `flush'  is called - if the requested value was in
   * there, good. If not, well, then there is nothing to flush.. -octo
   */
 -static int network_flush (int timeout,
 -              const char __attribute__((unused)) *identifier,
 -              user_data_t __attribute__((unused)) *user_data)
 +static int network_flush (__attribute__((unused)) cdtime_t timeout,
 +              __attribute__((unused)) const char *identifier,
 +              __attribute__((unused)) user_data_t *user_data)
  {
        pthread_mutex_lock (&send_buffer_lock);
  
diff --combined src/perl.c
  
  #include "configfile.h"
  
+ #if HAVE_STDBOOL_H
+ # include <stdbool.h>
+ #endif
  #include <EXTERN.h>
  #include <perl.h>
  
@@@ -393,10 -397,7 +397,10 @@@ static int hv2value_list (pTHX_ HV *has
        }
  
        if (NULL != (tmp = hv_fetch (hash, "time", 4, 0)))
 -              vl->time = (time_t)SvIV (*tmp);
 +      {
 +              double t = SvNV (*tmp);
 +              vl->time = DOUBLE_TO_CDTIME_T (t);
 +      }
  
        if (NULL != (tmp = hv_fetch (hash, "interval", 8, 0)))
                vl->interval = SvIV (*tmp);
@@@ -551,12 -552,9 +555,12 @@@ static int hv2notification (pTHX_ HV *h
                n->severity = NOTIF_FAILURE;
  
        if (NULL != (tmp = hv_fetch (hash, "time", 4, 0)))
 -              n->time = (time_t)SvIV (*tmp);
 +      {
 +              double t = SvNV (*tmp);
 +              n->time = DOUBLE_TO_CDTIME_T (t);
 +      }
        else
 -              n->time = time (NULL);
 +              n->time = cdtime ();
  
        if (NULL != (tmp = hv_fetch (hash, "message", 7, 0)))
                sstrncpy (n->message, SvPV_nolen (*tmp), sizeof (n->message));
@@@ -674,11 -672,8 +678,11 @@@ static int value_list2hv (pTHX_ value_l
                return -1;
  
        if (0 != vl->time)
 -              if (NULL == hv_store (hash, "time", 4, newSViv (vl->time), 0))
 +      {
 +              double t = CDTIME_T_TO_DOUBLE (vl->time);
 +              if (NULL == hv_store (hash, "time", 4, newSVnv (t), 0))
                        return -1;
 +      }
  
        if (NULL == hv_store (hash, "interval", 8, newSViv (vl->interval), 0))
                return -1;
@@@ -759,11 -754,8 +763,11 @@@ static int notification2hv (pTHX_ notif
                return -1;
  
        if (0 != n->time)
 -              if (NULL == hv_store (hash, "time", 4, newSViv (n->time), 0))
 +      {
 +              double t = CDTIME_T_TO_DOUBLE (n->time);
 +              if (NULL == hv_store (hash, "time", 4, newSVnv (t), 0))
                        return -1;
 +      }
  
        if ('\0' != *n->message)
                if (NULL == hv_store (hash, "message", 7, newSVpv (n->message, 0), 0))
@@@ -1114,15 -1106,11 +1118,15 @@@ static int pplugin_call_all (pTHX_ int 
                XPUSHs (sv_2mortal (newRV_noinc ((SV *)notif)));
        }
        else if (PLUGIN_FLUSH == type) {
 +              cdtime_t timeout;
 +
                /*
                 * $_[0] = $timeout;
                 * $_[1] = $identifier;
                 */
 -              XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
 +              timeout = va_arg (ap, cdtime_t);
 +
 +              XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
                XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
        }
  
@@@ -1998,7 -1986,7 +2002,7 @@@ static int perl_notify (const notificat
        return pplugin_call_all (aTHX_ PLUGIN_NOTIF, notif);
  } /* static int perl_notify (const notification_t *) */
  
 -static int perl_flush (int timeout, const char *identifier,
 +static int perl_flush (cdtime_t timeout, const char *identifier,
                user_data_t __attribute__((unused)) *user_data)
  {
        dTHX;
diff --combined src/plugin.c
@@@ -1251,7 -1251,7 +1251,7 @@@ int plugin_write (const char *plugin, /
    return (status);
  } /* }}} int plugin_write */
  
 -int plugin_flush (const char *plugin, int timeout, const char *identifier)
 +int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier)
  {
    llentry_t *le;
  
@@@ -1384,16 -1384,16 +1384,16 @@@ int plugin_dispatch_values (value_list_
        }
  
        if (vl->time == 0)
 -              vl->time = time (NULL);
 +              vl->time = cdtime ();
  
        if (vl->interval <= 0)
                vl->interval = interval_g;
  
 -      DEBUG ("plugin_dispatch_values: time = %u; interval = %i; "
 +      DEBUG ("plugin_dispatch_values: time = %.3f; interval = %i; "
                        "host = %s; "
                        "plugin = %s; plugin_instance = %s; "
                        "type = %s; type_instance = %s;",
 -                      (unsigned int) vl->time, vl->interval,
 +                      CDTIME_T_TO_DOUBLE (vl->time), vl->interval,
                        vl->host,
                        vl->plugin, vl->plugin_instance,
                        vl->type, vl->type_instance);
@@@ -1518,9 -1518,9 +1518,9 @@@ int plugin_dispatch_notification (cons
        /* Possible TODO: Add flap detection here */
  
        DEBUG ("plugin_dispatch_notification: severity = %i; message = %s; "
 -                      "time = %u; host = %s;",
 +                      "time = %.3f; host = %s;",
                        notif->severity, notif->message,
 -                      (unsigned int) notif->time, notif->host);
 +                      CDTIME_T_TO_DOUBLE (notif->time), notif->host);
  
        /* Nobody cares for notifications */
        if (list_notification == NULL)
@@@ -1654,7 -1654,7 +1654,7 @@@ static int plugin_notification_meta_ad
      }
      case NM_TYPE_BOOLEAN:
      {
-       meta->nm_value.nm_boolean = *((bool *) value);
+       meta->nm_value.nm_boolean = *((_Bool *) value);
        break;
      }
      default:
@@@ -1708,7 -1708,7 +1708,7 @@@ int plugin_notification_meta_add_doubl
  
  int plugin_notification_meta_add_boolean (notification_t *n,
      const char *name,
-     bool value)
+     _Bool value)
  {
    return (plugin_notification_meta_add (n, name, NM_TYPE_BOOLEAN, &value));
  }
diff --combined src/plugin.h
@@@ -25,7 -25,6 +25,7 @@@
  #include "collectd.h"
  #include "configfile.h"
  #include "meta_data.h"
 +#include "utils_time.h"
  
  #define PLUGIN_FLAGS_GLOBAL 0x0001
  
@@@ -86,7 -85,7 +86,7 @@@ struct value_list_
  {
        value_t *values;
        int      values_len;
 -      time_t   time;
 +      cdtime_t time;
        int      interval;
        char     host[DATA_MAX_NAME_LEN];
        char     plugin[DATA_MAX_NAME_LEN];
@@@ -136,7 -135,7 +136,7 @@@ typedef struct notification_meta_
                int64_t nm_signed_int;
                uint64_t nm_unsigned_int;
                double nm_double;
-               bool nm_boolean;
+               _Bool nm_boolean;
        } nm_value;
        struct notification_meta_s *next;
  } notification_meta_t;
  typedef struct notification_s
  {
        int    severity;
 -      time_t time;
 +      cdtime_t time;
        char   message[NOTIF_MAX_MSG_LEN];
        char   host[DATA_MAX_NAME_LEN];
        char   plugin[DATA_MAX_NAME_LEN];
@@@ -168,7 -167,7 +168,7 @@@ typedef int (*plugin_init_cb) (void)
  typedef int (*plugin_read_cb) (user_data_t *);
  typedef int (*plugin_write_cb) (const data_set_t *, const value_list_t *,
                user_data_t *);
 -typedef int (*plugin_flush_cb) (int timeout, const char *identifier,
 +typedef int (*plugin_flush_cb) (cdtime_t timeout, const char *identifier,
                user_data_t *);
  typedef void (*plugin_log_cb) (int severity, const char *message,
                user_data_t *);
@@@ -249,7 -248,7 +249,7 @@@ void plugin_shutdown_all (void)
  int plugin_write (const char *plugin,
      const data_set_t *ds, const value_list_t *vl);
  
 -int plugin_flush (const char *plugin, int timeout, const char *identifier);
 +int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier);
  
  /*
   * The `plugin_register_*' functions are used to make `config', `init',
@@@ -341,7 -340,7 +341,7 @@@ int plugin_notification_meta_add_doubl
      double value);
  int plugin_notification_meta_add_boolean (notification_t *n,
      const char *name,
-     bool value);
+     _Bool value);
  
  int plugin_notification_meta_copy (notification_t *dst,
      const notification_t *src);
diff --combined src/rrdtool.c
   */
  struct rrd_cache_s
  {
 -      int    values_num;
 -      char **values;
 -      time_t first_value;
 -      time_t last_value;
 -      int random_variation;
 +      int      values_num;
 +      char   **values;
 +      cdtime_t first_value;
 +      cdtime_t last_value;
 +      int64_t  random_variation;
        enum
        {
                FLAG_NONE   = 0x00,
@@@ -107,10 -107,10 +107,10 @@@ static rrdcreate_config_t rrdcreate_con
  
  /* XXX: If you need to lock both, cache_lock and queue_lock, at the same time,
   * ALWAYS lock `cache_lock' first! */
 -static int         cache_timeout = 0;
 -static int         cache_flush_timeout = 0;
 -static int         random_timeout = 1;
 -static time_t      cache_flush_last;
 +static cdtime_t    cache_timeout = 0;
 +static cdtime_t    cache_flush_timeout = 0;
 +static cdtime_t    random_timeout = TIME_T_TO_CDTIME_T (1);
 +static cdtime_t    cache_flush_last;
  static c_avl_tree_t *cache = NULL;
  static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
  
@@@ -199,13 -199,11 +199,13 @@@ static int value_list_to_string (char *
  {
        int offset;
        int status;
 +      time_t tt;
        int i;
  
        memset (buffer, '\0', buffer_len);
  
 -      status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) vl->time);
 +      tt = CDTIME_T_TO_TIME_T (vl->time);
 +      status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) tt);
        if ((status < 1) || (status >= buffer_len))
                return (-1);
        offset = status;
@@@ -305,7 -303,7 +305,7 @@@ static void *rrd_queue_thread (void __a
  
                  pthread_mutex_lock (&queue_lock);
                  /* Wait for values to arrive */
-                 while (true)
+                 while (42)
                  {
                    struct timespec ts_wait;
  
                        &ts_wait);
                    if (status == ETIMEDOUT)
                      break;
-                 } /* while (true) */
+                 } /* while (42) */
  
                  /* XXX: If you need to lock both, cache_lock and queue_lock, at
                   * the same time, ALWAYS lock `cache_lock' first! */
@@@ -512,11 -510,10 +512,11 @@@ static int rrd_queue_dequeue (const cha
    return (0);
  } /* int rrd_queue_dequeue */
  
 -static void rrd_cache_flush (int timeout)
 +/* XXX: You must hold "cache_lock" when calling this function! */
 +static void rrd_cache_flush (cdtime_t timeout)
  {
        rrd_cache_t *rc;
 -      time_t       now;
 +      cdtime_t     now;
  
        char **keys = NULL;
        int    keys_num = 0;
        c_avl_iterator_t *iter;
        int i;
  
 -      DEBUG ("rrdtool plugin: Flushing cache, timeout = %i", timeout);
 +      DEBUG ("rrdtool plugin: Flushing cache, timeout = %.3f",
 +                      CDTIME_T_TO_DOUBLE (timeout));
  
 -      now = time (NULL);
 +      now = cdtime ();
 +      timeout = TIME_T_TO_CDTIME_T (timeout);
  
        /* Build a list of entries to be flushed */
        iter = c_avl_get_iterator (cache);
        {
                if (rc->flags != FLAG_NONE)
                        continue;
 -              else if ((now - rc->first_value) < timeout)
 +              /* timeout == 0  =>  flush everything */
 +              else if ((timeout != 0)
 +                              && ((now - rc->first_value) < timeout))
                        continue;
                else if (rc->values_num > 0)
                {
        cache_flush_last = now;
  } /* void rrd_cache_flush */
  
 -static int rrd_cache_flush_identifier (int timeout, const char *identifier)
 +static int rrd_cache_flush_identifier (cdtime_t timeout,
 +    const char *identifier)
  {
    rrd_cache_t *rc;
 -  time_t now;
 +  cdtime_t now;
    int status;
    char key[2048];
  
      return (0);
    }
  
 -  now = time (NULL);
 +  now = cdtime ();
  
    if (datadir == NULL)
      snprintf (key, sizeof (key), "%s.rrd",
    return (status);
  } /* int rrd_cache_flush_identifier */
  
 +static int64_t rrd_get_random_variation (void)
 +{
 +  double dbl_timeout;
 +  cdtime_t ctm_timeout;
 +  double rand_fact;
 +  _Bool negative;
 +  int64_t ret;
 +
 +  if (random_timeout <= 0)
 +    return (0);
 +
 +  /* This seems a bit complicated, but "random_timeout" is likely larger than
 +   * RAND_MAX, so we can't simply use modulo here. */
 +  dbl_timeout = CDTIME_T_TO_DOUBLE (random_timeout);
 +  rand_fact = ((double) random ())
 +    / ((double) RAND_MAX);
 +  negative = (_Bool) (random () % 2);
 +
 +  ctm_timeout = DOUBLE_TO_CDTIME_T (dbl_timeout * rand_fact);
 +
 +  ret = (int64_t) ctm_timeout;
 +  if (negative)
 +    ret *= -1;
 +
 +  return (ret);
 +} /* int64_t rrd_get_random_variation */
 +
  static int rrd_cache_insert (const char *filename,
 -              const char *value, time_t value_time)
 +              const char *value, cdtime_t value_time)
  {
        rrd_cache_t *rc = NULL;
        int new_rc = 0;
  
        if (rc == NULL)
        {
 -              rc = (rrd_cache_t *) malloc (sizeof (rrd_cache_t));
 +              rc = malloc (sizeof (*rc));
                if (rc == NULL)
                        return (-1);
                rc->values_num = 0;
                rc->values = NULL;
                rc->first_value = 0;
                rc->last_value = 0;
 -              rc->random_variation = 0;
 +              rc->random_variation = rrd_get_random_variation ();
                rc->flags = FLAG_NONE;
                new_rc = 1;
        }
        if (rc->last_value >= value_time)
        {
                pthread_mutex_unlock (&cache_lock);
 -              DEBUG ("rrdtool plugin: (rc->last_value = %u) >= (value_time = %u)",
 -                              (unsigned int) rc->last_value,
 -                              (unsigned int) value_time);
 +              DEBUG ("rrdtool plugin: (rc->last_value = %"PRIu64") "
 +                              ">= (value_time = %"PRIu64")",
 +                              rc->last_value, value_time);
                return (-1);
        }
  
        }
  
        DEBUG ("rrdtool plugin: rrd_cache_insert: file = %s; "
 -                      "values_num = %i; age = %lu;",
 +                      "values_num = %i; age = %.3f;",
                        filename, rc->values_num,
 -                      (unsigned long)(rc->last_value - rc->first_value));
 +                      CDTIME_T_TO_DOUBLE (rc->last_value - rc->first_value));
  
 -      if ((rc->last_value + rc->random_variation - rc->first_value) >= cache_timeout)
 +      if ((rc->last_value - rc->first_value) >= (cache_timeout + rc->random_variation))
        {
                /* XXX: If you need to lock both, cache_lock and queue_lock, at
                 * the same time, ALWAYS lock `cache_lock' first! */
                        if (status == 0)
                                rc->flags = FLAG_QUEUED;
  
 -                      /* Update the jitter value. Negative values are
 -                       * slightly preferred. */
 -                      if (random_timeout > 0)
 -                      {
 -                              rc->random_variation = (rand () % (2 * random_timeout))
 -                                      - random_timeout;
 -                      }
 -                      else
 -                      {
 -                              rc->random_variation = 0;
 -                      }
 +                        rc->random_variation = rrd_get_random_variation ();
                }
                else
                {
        }
  
        if ((cache_timeout > 0) &&
 -                      ((time (NULL) - cache_flush_last) > cache_flush_timeout))
 +                      ((cdtime () - cache_flush_last) > cache_flush_timeout))
                rrd_cache_flush (cache_flush_timeout);
  
        pthread_mutex_unlock (&cache_lock);
@@@ -924,8 -899,8 +924,8 @@@ static int rrd_write (const data_set_t 
        return (status);
  } /* int rrd_write */
  
 -static int rrd_flush (int timeout, const char *identifier,
 -              user_data_t __attribute__((unused)) *user_data)
 +static int rrd_flush (cdtime_t timeout, const char *identifier,
 +              __attribute__((unused)) user_data_t *user_data)
  {
        pthread_mutex_lock (&cache_lock);
  
@@@ -944,7 -919,7 +944,7 @@@ static int rrd_config (const char *key
  {
        if (strcasecmp ("CacheTimeout", key) == 0)
        {
 -              int tmp = atoi (value);
 +              double tmp = atof (value);
                if (tmp < 0)
                {
                        fprintf (stderr, "rrdtool: `CacheTimeout' must "
                                        "be greater than 0.\n");
                        return (1);
                }
 -              cache_timeout = tmp;
 +              cache_timeout = DOUBLE_TO_CDTIME_T (tmp);
        }
        else if (strcasecmp ("CacheFlush", key) == 0)
        {
        }
        else if (strcasecmp ("RandomTimeout", key) == 0)
          {
 -              int tmp;
 +              double tmp;
  
 -              tmp = atoi (value);
 -              if (tmp < 0)
 +              tmp = atof (value);
 +              if (tmp < 0.0)
                {
                        fprintf (stderr, "rrdtool: `RandomTimeout' must "
                                        "be greater than or equal to zero.\n");
                }
                else
                {
 -                      random_timeout = tmp;
 +                      random_timeout = DOUBLE_TO_CDTIME_T (tmp);
                }
        }
        else
  static int rrd_shutdown (void)
  {
        pthread_mutex_lock (&cache_lock);
 -      rrd_cache_flush (-1);
 +      rrd_cache_flush (0);
        pthread_mutex_unlock (&cache_lock);
  
        pthread_mutex_lock (&queue_lock);
@@@ -1179,9 -1154,10 +1179,9 @@@ static int rrd_init (void
                return (-1);
        }
  
 -      cache_flush_last = time (NULL);
 -      if (cache_timeout < 2)
 +      cache_flush_last = cdtime ();
 +      if (cache_timeout == 0)
        {
 -              cache_timeout = 0;
                cache_flush_timeout = 0;
        }
        else if (cache_flush_timeout < cache_timeout)