randomized exponential backoff
authorFlorian Dold <florian.dold@gmail.com>
Wed, 26 Sep 2018 15:34:51 +0000 (17:34 +0200)
committerFlorian Dold <florian.dold@gmail.com>
Wed, 26 Sep 2018 15:34:51 +0000 (17:34 +0200)
src/include/gnunet_time_lib.h
src/util/time.c

index 2fc20d2cd96bb0536298ae0eae1bcf03d75848a9..41840e9a38b2dc0673a8343f6885dadfca93989d 100644 (file)
@@ -173,6 +173,19 @@ GNUNET_NETWORK_STRUCT_END
 #define GNUNET_TIME_STD_BACKOFF(r) GNUNET_TIME_relative_min (GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD, \
    GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, (r)), 2));
 
+
+/**
+ * Randomized exponential back-off, starting at 1 ms
+ * and going up by a factor of 2+r, where 0 <= r <= 0.5, up
+ * to a maximum of 15 m.
+ *
+ * @param r current backoff time, initially zero
+ * @return the next backoff time
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt);
+
+
 /**
  * Return relative time of 0ms.
  */
index ee90eb8ae552ff9dd677e5100cf4ec776a5466ec..0c177c381ef581f0854d76dde6ead9ff91cfb72a 100644 (file)
@@ -443,6 +443,39 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
 }
 
 
+/**
+ * Multiply relative time by a given floating-point factor.  The factor must be
+ * positive.
+ *
+ * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
+ */
+struct GNUNET_TIME_Relative
+relative_multiply_double (struct GNUNET_TIME_Relative rel,
+                          double factor)
+{
+  struct GNUNET_TIME_Relative out;
+  double m;
+
+  GNUNET_assert (0 <= factor);
+
+  if (0 == factor)
+    return GNUNET_TIME_UNIT_ZERO;
+  if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
+    return GNUNET_TIME_UNIT_FOREVER_REL;
+
+  m = ((double) rel.rel_value_us) * factor;
+
+  if (m >= (double) (GNUNET_TIME_UNIT_FOREVER_REL).rel_value_us)
+  {
+    GNUNET_break (0);
+    return GNUNET_TIME_UNIT_FOREVER_REL;
+  }
+
+  out.rel_value_us = (uint64_t) m;
+  return out;
+}
+
+
 /**
  * Saturating multiply relative time by a given factor.
  *
@@ -701,5 +734,26 @@ GNUNET_TIME_year_to_time (unsigned int year)
 }
 
 
+/**
+ * Randomized exponential back-off, starting at 1 ms
+ * and going up by a factor of 2+r, where 0 <= r <= 0.5, up
+ * to a maximum of 15 m.
+ *
+ * @param r current backoff time, initially zero
+ * @return the next backoff time
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt)
+{
+  double r = (rand() % 500) / 1000.0;
+  struct GNUNET_TIME_Relative t;
+
+  t = relative_multiply_double (GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS,
+                                                          rt),
+                                2 + r);
+  return GNUNET_TIME_relative_min (GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD,
+                                   t);
+}
+
 
 /* end of time.c */