summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amatus.name>2016-11-17 23:24:43 -0600
committerDavid Barksdale <amatus@amatus.name>2016-11-17 23:24:43 -0600
commit12597da2a33fe196a785a656136cba7675a06e21 (patch)
treec189c7fb7f2835f8219622400d83c453a91dbb69
parentcdeb1253bfda209def1ef48b436ff09cf7ab8be6 (diff)
Sometimes it's OK if multiplication overflows
-rw-r--r--src/ats/plugin_ats_ril.c2
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c8
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c8
-rw-r--r--src/fragmentation/defragmentation.c4
-rw-r--r--src/fragmentation/fragmentation.c12
-rw-r--r--src/fs/fs_api.c4
-rw-r--r--src/fs/fs_search.c4
-rw-r--r--src/fs/gnunet-auto-share.c12
-rw-r--r--src/fs/gnunet-service-fs_pr.c2
-rw-r--r--src/include/gnunet_time_lib.h12
-rw-r--r--src/regex/gnunet-regex-profiler.c2
-rw-r--r--src/rps/gnunet-service-rps.c4
-rw-r--r--src/util/bandwidth.c4
-rw-r--r--src/util/time.c26
-rw-r--r--src/vpn/vpn_api.c2
15 files changed, 72 insertions, 34 deletions
diff --git a/src/ats/plugin_ats_ril.c b/src/ats/plugin_ats_ril.c
index a3bdf200c..ea7920779 100644
--- a/src/ats/plugin_ats_ril.c
+++ b/src/ats/plugin_ats_ril.c
@@ -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,
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c
index 0e9b7a3af..22349aa80 100644
--- a/src/cadet/gnunet-service-cadet_channel.c
+++ b/src/cadet/gnunet-service-cadet_channel.c
@@ -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);
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index face765e4..1c500f716 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -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);
diff --git a/src/fragmentation/defragmentation.c b/src/fragmentation/defragmentation.c
index bc401435e..cc0f5a8c5 100644
--- a/src/fragmentation/defragmentation.c
+++ b/src/fragmentation/defragmentation.c
@@ -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) )
diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c
index eb0bad675..02444cf14 100644
--- a/src/fragmentation/fragmentation.c
+++ b/src/fragmentation/fragmentation.c
@@ -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);
}
diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c
index 1e8af23c5..7e769483b 100644
--- a/src/fs/fs_api.c
+++ b/src/fs/fs_api.c
@@ -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)
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 7874bb6e0..198577b08 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -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,
diff --git a/src/fs/gnunet-auto-share.c b/src/fs/gnunet-auto-share.c
index 96f86bf5d..cc0111111 100644
--- a/src/fs/gnunet-auto-share.c
+++ b/src/fs/gnunet-auto-share.c
@@ -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);
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c
index f8a7b61f0..63462f7dc 100644
--- a/src/fs/gnunet-service-fs_pr.c
+++ b/src/fs/gnunet-service-fs_pr.c
@@ -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,
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h
index 64c5769c6..224edc03e 100644
--- a/src/include/gnunet_time_lib.h
+++ b/src/include/gnunet_time_lib.h
@@ -421,6 +421,18 @@ 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);
+
+
+/**
* Divide relative time by a given factor.
*
* @param rel some duration
diff --git a/src/regex/gnunet-regex-profiler.c b/src/regex/gnunet-regex-profiler.c
index c5ecf3b4d..dfbcd388a 100644
--- a/src/regex/gnunet-regex-profiler.c
+++ b/src/regex/gnunet-regex-profiler.c
@@ -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,
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 90aab93fd..9de1f8d3a 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -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);
diff --git a/src/util/bandwidth.c b/src/util/bandwidth.c
index 980af764a..a059fc738 100644
--- a/src/util/bandwidth.c
+++ b/src/util/bandwidth.c
@@ -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",
diff --git a/src/util/time.c b/src/util/time.c
index eb168d531..89b0c2d44 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -446,6 +446,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.
*
* @param rel some duration
diff --git a/src/vpn/vpn_api.c b/src/vpn/vpn_api.c
index b22b805cd..4add41ce4 100644
--- a/src/vpn/vpn_api.c
+++ b/src/vpn/vpn_api.c
@@ -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,