Sometimes it's OK if multiplication overflows
authorDavid Barksdale <amatus@amatus.name>
Fri, 18 Nov 2016 05:24:43 +0000 (23:24 -0600)
committerDavid Barksdale <amatus@amatus.name>
Fri, 18 Nov 2016 05:24:43 +0000 (23:24 -0600)
15 files changed:
src/ats/plugin_ats_ril.c
src/cadet/gnunet-service-cadet_channel.c
src/cadet/gnunet-service-cadet_connection.c
src/fragmentation/defragmentation.c
src/fragmentation/fragmentation.c
src/fs/fs_api.c
src/fs/fs_search.c
src/fs/gnunet-auto-share.c
src/fs/gnunet-service-fs_pr.c
src/include/gnunet_time_lib.h
src/regex/gnunet-regex-profiler.c
src/rps/gnunet-service-rps.c
src/util/bandwidth.c
src/util/time.c
src/vpn/vpn_api.c

index a3bdf200c5ebe580dc9cd6df193a771bb4373a68..ea79207790872c58a9b0357d984ceebf978b8d71 100644 (file)
@@ -1835,7 +1835,7 @@ ril_step_schedule_next (struct GAS_RIL_Handle *solver)
   GNUNET_assert(y <= (double) solver->parameters.step_time_max.rel_value_us);
   GNUNET_assert(y >= (double) solver->parameters.step_time_min.rel_value_us);
 
-  time_next = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, (unsigned long long) y);
+  time_next = GNUNET_TIME_relative_saturating_multiply (GNUNET_TIME_UNIT_MICROSECONDS, (unsigned long long) y);
 
 //  LOG (GNUNET_ERROR_TYPE_INFO, "ratio: %f, factor: %f, offset: %f, y: %f\n",
 //      used_ratio,
index 0e9b7a3af4644a3d0abd5fdf0ea222d4188ef051..22349aa80c5cf26acb979750eb58ca680be54e77 100644 (file)
@@ -819,8 +819,8 @@ ch_message_sent (void *cls,
         if (0 != rel->expected_delay.rel_value_us)
         {
           rel->retry_timer =
-              GNUNET_TIME_relative_multiply (rel->expected_delay,
-                                             CADET_RETRANSMIT_MARGIN);
+              GNUNET_TIME_relative_saturating_multiply (rel->expected_delay,
+                                                        CADET_RETRANSMIT_MARGIN);
         }
         else
         {
@@ -2110,8 +2110,8 @@ GCCH_handle_data_ack (struct CadetChannel *ch,
         struct GNUNET_TIME_Absolute new_target;
         struct GNUNET_TIME_Relative delay;
 
-        delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
-                                               CADET_RETRANSMIT_MARGIN);
+        delay = GNUNET_TIME_relative_saturating_multiply (rel->retry_timer,
+                                                          CADET_RETRANSMIT_MARGIN);
         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
                                                delay);
         delay = GNUNET_TIME_absolute_get_remaining (new_target);
index face765e4fc59d7d4a794409f9ca23246303e882..1c500f716bfcd09654bc88126244ab78bfc79d83 100644 (file)
@@ -1318,8 +1318,8 @@ schedule_next_keepalive (struct CadetConnection *c, int fwd)
   {
     if (1 > c->create_retry)
       c->create_retry = 1;
-    delay = GNUNET_TIME_relative_multiply (create_connection_time,
-                                           c->create_retry);
+    delay = GNUNET_TIME_relative_saturating_multiply (create_connection_time,
+                                                      c->create_retry);
     if (c->create_retry < 64) // TODO make configurable
       c->create_retry *= 2;
   }
@@ -1548,7 +1548,7 @@ connection_reset_timeout (struct CadetConnection *c, int fwd)
 
     if (NULL != *ti)
       GNUNET_SCHEDULER_cancel (*ti);
-    delay = GNUNET_TIME_relative_multiply (refresh_connection_time, 4);
+    delay = GNUNET_TIME_relative_saturating_multiply (refresh_connection_time, 4);
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "  timing out in %s\n",
          GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_NO));
@@ -1681,7 +1681,7 @@ schedule_check_duplicates (struct CadetConnection *c)
 
   if (NULL != c->check_duplicates_task)
     return;
-  delay = GNUNET_TIME_relative_multiply (refresh_connection_time, 5);
+  delay = GNUNET_TIME_relative_saturating_multiply (refresh_connection_time, 5);
   c->check_duplicates_task = GNUNET_SCHEDULER_add_delayed (delay,
                                                            &check_duplicates,
                                                            c);
index bc401435e29f0edd8b339c8df78ab96368a8e002..cc0f5a8c5434f7e102f840c7773ee4f25f01273e 100644 (file)
@@ -564,8 +564,8 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
   {
     dc->latency = estimate_latency (mc);
   }
-  delay = GNUNET_TIME_relative_multiply (dc->latency,
-                                         bc + 1);
+  delay = GNUNET_TIME_relative_saturating_multiply (dc->latency,
+                                                    bc + 1);
   if ( (last + fid == num_fragments) ||
        (0 == mc->bits) ||
        (GNUNET_YES == duplicate) )
index eb0bad67509e2957f719e01cfc1947b79c8f862d..02444cf14f9706e9039cf8a5337dff92ba12bb70 100644 (file)
@@ -260,7 +260,7 @@ transmit_next (void *cls)
     delay = GNUNET_TIME_UNIT_ZERO;
   if (fc->num_rounds < 64)
     delay = GNUNET_TIME_relative_max (delay,
-                                      GNUNET_TIME_relative_multiply
+                                      GNUNET_TIME_relative_saturating_multiply
                                       (fc->msg_delay,
                                        (1ULL << fc->num_rounds)));
   else
@@ -269,7 +269,7 @@ transmit_next (void *cls)
   {
     /* full round transmitted wait 2x delay for ACK before going again */
     fc->num_rounds++;
-    delay = GNUNET_TIME_relative_multiply (fc->ack_delay, 2);
+    delay = GNUNET_TIME_relative_saturating_multiply (fc->ack_delay, 2);
     /* never use zero, need some time for ACK always */
     delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay);
     fc->wack = GNUNET_YES;
@@ -432,8 +432,8 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
     if (0 == ack_cnt)
     {
       /* complete loss */
-      fc->msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay,
-                                                    snd_cnt);
+      fc->msg_delay = GNUNET_TIME_relative_saturating_multiply (fc->msg_delay,
+                                                                snd_cnt);
     }
     else if (snd_cnt > ack_cnt)
     {
@@ -515,8 +515,8 @@ GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc,
   if (NULL != ack_delay)
     *ack_delay = fc->ack_delay;
   if (NULL != msg_delay)
-    *msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay,
-                                               fc->num_rounds);
+    *msg_delay = GNUNET_TIME_relative_saturating_multiply (fc->msg_delay,
+                                                           fc->num_rounds);
   GNUNET_free (fc);
 }
 
index 1e8af23c536c950108971e9ac352febebe50f45d..7e769483b874e6087e63ce6020bd3c9b18c855f2 100644 (file)
@@ -178,8 +178,8 @@ process_job_queue (void *cls)
       break;
     case GNUNET_FS_QUEUE_PRIORITY_NORMAL:
       run_time =
-        GNUNET_TIME_relative_multiply (h->avg_block_latency,
-                                       qe->blocks * qe->start_times);
+        GNUNET_TIME_relative_saturating_multiply (h->avg_block_latency,
+                                                  qe->blocks * qe->start_times);
       end_time = GNUNET_TIME_absolute_add (qe->start_time, run_time);
       rst = GNUNET_TIME_absolute_get_remaining (end_time);
       if (0 == rst.rel_value_us)
index 7874bb6e075342d5497095237f033c48c908f26a..198577b08ecb76ec2ab58b5ce40a8188300a46ff 100644 (file)
@@ -458,8 +458,8 @@ GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr)
              (unsigned long long) off,
              sr);
   sr->remaining_probe_time =
-      GNUNET_TIME_relative_multiply (sr->h->avg_block_latency,
-                                     2 * (1 + sr->availability_trials));
+      GNUNET_TIME_relative_saturating_multiply (sr->h->avg_block_latency,
+                                                2 * (1 + sr->availability_trials));
   sr->probe_ctx =
       GNUNET_FS_download_start (sr->h, sr->uri, sr->meta, NULL, NULL, off,
                                 len, sr->anonymity,
index 96f86bf5d43c3347ed01b44ce8336dcd4026859c..cc0111111e98915d21e674ce33f26bb2450be205 100644 (file)
@@ -29,9 +29,9 @@
 #include "platform.h"
 #include "gnunet_util_lib.h"
 
-#define MIN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
+#define MAX_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
 
-#define MAX_FREQUENCY GNUNET_TIME_UNIT_MINUTES
+#define MIN_DELAY GNUNET_TIME_UNIT_MINUTES
 
 
 /**
@@ -672,11 +672,11 @@ schedule_next_task ()
     /* delay by at most 4h, at least 1s, and otherwise in between depending
        on how long it took to scan */
     delay = GNUNET_TIME_absolute_get_duration (start_time);
-    delay = GNUNET_TIME_relative_min (MIN_FREQUENCY,
-                                     GNUNET_TIME_relative_multiply (delay,
-                                                                    100));
+    delay = GNUNET_TIME_relative_saturating_multiply (delay, 100);
+    delay = GNUNET_TIME_relative_min (delay,
+                                      MAX_DELAY);
     delay = GNUNET_TIME_relative_max (delay,
-                                     MAX_FREQUENCY);
+                                      MIN_DELAY);
     run_task = GNUNET_SCHEDULER_add_delayed (delay,
                                             &scan,
                                             NULL);
index f8a7b61f0fc1119fde9d70dd673f9bb87eb51194..63462f7dcd216b009714d6bc2eb246d1ed50ef53 100644 (file)
@@ -1036,7 +1036,7 @@ put_migration_continuation (void *cls, int success,
                                                       ppd->migration_delay);
       mig_pause.rel_value_us = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
                                                         ppd->migration_delay.rel_value_us);
-      ppd->migration_delay = GNUNET_TIME_relative_multiply (ppd->migration_delay, 2);
+      ppd->migration_delay = GNUNET_TIME_relative_saturating_multiply (ppd->migration_delay, 2);
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Replicated content already exists locally, asking to stop migration for %s\n",
                  GNUNET_STRINGS_relative_time_to_string (mig_pause,
index 64c5769c62af422dd14f2b40aad98c553bcab4ea..224edc03e94920568786aaabd587a778020bfdd0 100644 (file)
@@ -420,6 +420,18 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
                                unsigned long long factor);
 
 
+/**
+ * Saturating multiply relative time by a given factor.
+ *
+ * @param rel some duration
+ * @param factor integer to multiply with
+ * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
+                                          unsigned long long factor);
+
+
 /**
  * Divide relative time by a given factor.
  *
index c5ecf3b4d958af58303c3dc97523d9206892d7c1..dfbcd388a9cd0791370a7b94bfb663660eb1fb4f 100644 (file)
@@ -950,7 +950,7 @@ daemon_started (void *cls,
   }
   peers[search_peer].search_str = search_strings[peer->id];
   peers[search_peer].search_str_matched = GNUNET_NO;
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_saturating_multiply(
                                   reannounce_period_max,
                                   2),
                                 &find_string,
index 90aab93fdd848f80e46355bb07ec1772163b6e86..9de1f8d3a895f2f9e7be6d0951b5ae9c0f1595de 100644 (file)
@@ -1508,7 +1508,7 @@ compute_rand_delay (struct GNUNET_TIME_Relative mean,
    * via multiplying round_interval with a 'fraction' (0 to value)/value
    */
   rand_delay = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, max_rand_delay);
-  ret = GNUNET_TIME_relative_multiply (mean,  rand_delay);
+  ret = GNUNET_TIME_relative_saturating_multiply (mean,  rand_delay);
   ret = GNUNET_TIME_relative_divide   (ret, max_rand_delay);
   ret = GNUNET_TIME_relative_add      (ret, half_interval);
 
@@ -2394,7 +2394,7 @@ run (void *cls,
   struct GNUNET_TIME_Relative half_round_interval;
   struct GNUNET_TIME_Relative  max_round_interval;
 
-  half_round_interval = GNUNET_TIME_relative_multiply (round_interval, .5);
+  half_round_interval = GNUNET_TIME_relative_divide (round_interval, 2);
   max_round_interval = GNUNET_TIME_relative_add (round_interval, half_round_interval);
 
   prot_sampler =   RPS_sampler_init     (sampler_size_est_need, max_round_interval);
index 980af764a0638aa954ba0f2b06c6c513368c8f4a..a059fc73808d517e0955b325d48e35b4bb1fd647 100644 (file)
@@ -204,8 +204,8 @@ update_excess (struct GNUNET_BANDWIDTH_Tracker *av)
   else
   {
     double factor = 1.0 * left_bytes / (double) av->available_bytes_per_s__; 
-    delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
-                                           (unsigned long long) factor);
+    delay = GNUNET_TIME_relative_saturating_multiply (GNUNET_TIME_UNIT_SECONDS,
+                                                      (unsigned long long) factor);
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "At %llu bps it will take us %s for %lld bytes to reach excess threshold\n",
index eb168d531120a3f1266957e30de06a55be748ee8..89b0c2d446098a3e4e4c5f9c416d9697388bbdb2 100644 (file)
@@ -445,6 +445,32 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
 }
 
 
+/**
+ * Saturating multiply relative time by a given factor.
+ *
+ * @param rel some duration
+ * @param factor integer to multiply with
+ * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
+                                          unsigned long long factor)
+{
+  struct GNUNET_TIME_Relative ret;
+
+  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;
+  ret.rel_value_us = rel.rel_value_us * factor;
+  if (ret.rel_value_us / factor != rel.rel_value_us)
+  {
+    return GNUNET_TIME_UNIT_FOREVER_REL;
+  }
+  return ret;
+}
+
+
 /**
  * Divide relative time by a given factor.
  *
index b22b805cdc2d832a1189ae4ae9860c42635d3156..4add41ce4d58e5ca4ecaaf326cd80c55fab614db 100644 (file)
@@ -352,7 +352,7 @@ reconnect (struct GNUNET_VPN_Handle *vh)
   for (rr = vh->rr_head; NULL != rr; rr = rr->next)
     rr->request_id = 0;
   vh->backoff = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS,
-                                         GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply (vh->backoff, 2),
+                                         GNUNET_TIME_relative_min (GNUNET_TIME_relative_saturating_multiply (vh->backoff, 2),
                                                                    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)));
   vh->rt = GNUNET_SCHEDULER_add_delayed (vh->backoff,
                                         &connect_task,