src/util: Use make 4.0 assignment operator
[oweals/gnunet.git] / src / util / time.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2001-2013, 2018 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21 /**
22  * @file util/time.c
23  * @author Christian Grothoff
24  * @brief functions for handling time and time arithmetic
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #if __STDC_NO_ATOMICS__
29 #define ATOMIC
30 #else
31 #ifdef HAVE_STDATOMIC_H
32 #include <stdatomic.h>
33 #define ATOMIC _Atomic
34 #else
35 #define __STDC_NO_ATOMICS__ 1
36 #define ATOMIC
37 #endif
38 #endif
39
40 #define LOG(kind,...) GNUNET_log_from (kind, "util-time", __VA_ARGS__)
41
42 /**
43  * Variable used to simulate clock skew.  Used for testing, never in production.
44  */
45 static long long timestamp_offset;
46
47 /**
48  * Set the timestamp offset for this instance.
49  *
50  * @param offset the offset to skew the locale time by
51  */
52 void
53 GNUNET_TIME_set_offset (long long offset)
54 {
55   timestamp_offset = offset;
56 }
57
58
59 /**
60  * Get the timestamp offset for this instance.
61  *
62  * @return the offset we currently skew the locale time by
63  */
64 long long
65 GNUNET_TIME_get_offset ()
66 {
67   return timestamp_offset;
68 }
69
70
71 /**
72  * Round a time value so that it is suitable for transmission
73  * via JSON encodings.
74  *
75  * @param at time to round
76  * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
77  *         it was just now rounded
78  */
79 int
80 GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at)
81 {
82   if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
83     return GNUNET_OK;
84   if (0 == at->abs_value_us % 1000000)
85     return GNUNET_OK;
86   at->abs_value_us -= at->abs_value_us % 1000000;
87   return GNUNET_NO;
88 }
89
90
91 /**
92  * Round a time value so that it is suitable for transmission
93  * via JSON encodings.
94  *
95  * @param rt time to round
96  * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
97  *         it was just now rounded
98  */
99 int
100 GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt)
101 {
102   if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
103     return GNUNET_OK;
104   if (0 == rt->rel_value_us % 1000000)
105     return GNUNET_OK;
106   rt->rel_value_us -= rt->rel_value_us % 1000000;
107   return GNUNET_NO;
108 }
109
110
111 /**
112  * Get the current time (works just as "time", just that we use the
113  * unit of time that the cron-jobs use (and is 64 bit)).
114  *
115  * @return the current time
116  */
117 struct GNUNET_TIME_Absolute
118 GNUNET_TIME_absolute_get ()
119 {
120   struct GNUNET_TIME_Absolute ret;
121   struct timeval tv;
122
123   GETTIMEOFDAY (&tv, NULL);
124   ret.abs_value_us =
125       (uint64_t) (((uint64_t) tv.tv_sec * 1000LL * 1000LL) +
126                   ((uint64_t) tv.tv_usec)) + timestamp_offset;
127   return ret;
128 }
129
130
131 /**
132  * Return relative time of 0ms.
133  */
134 struct GNUNET_TIME_Relative
135 GNUNET_TIME_relative_get_zero_ ()
136 {
137   static struct GNUNET_TIME_Relative zero;
138
139   return zero;
140 }
141
142
143 /**
144  * Return absolute time of 0ms.
145  */
146 struct GNUNET_TIME_Absolute
147 GNUNET_TIME_absolute_get_zero_ ()
148 {
149   static struct GNUNET_TIME_Absolute zero;
150
151   return zero;
152 }
153
154
155 /**
156  * Return relative time of 1us.
157  */
158 struct GNUNET_TIME_Relative
159 GNUNET_TIME_relative_get_unit_ ()
160 {
161   static struct GNUNET_TIME_Relative one = { 1 };
162
163   return one;
164 }
165
166
167 /**
168  * Return relative time of 1ms.
169  */
170 struct GNUNET_TIME_Relative
171 GNUNET_TIME_relative_get_millisecond_ ()
172 {
173   static struct GNUNET_TIME_Relative one = { 1000 };
174
175   return one;
176 }
177
178
179 /**
180  * Return relative time of 1s.
181  */
182 struct GNUNET_TIME_Relative
183 GNUNET_TIME_relative_get_second_ ()
184 {
185   static struct GNUNET_TIME_Relative one = { 1000 * 1000LL };
186
187   return one;
188 }
189
190
191 /**
192  * Return relative time of 1 minute.
193  */
194 struct GNUNET_TIME_Relative
195 GNUNET_TIME_relative_get_minute_ ()
196 {
197   static struct GNUNET_TIME_Relative one = { 60 * 1000 * 1000LL };
198
199   return one;
200 }
201
202
203 /**
204  * Return relative time of 1 hour.
205  */
206 struct GNUNET_TIME_Relative
207 GNUNET_TIME_relative_get_hour_ ()
208 {
209   static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 * 1000LL };
210
211   return one;
212 }
213
214
215 /**
216  * Return "forever".
217  */
218 struct GNUNET_TIME_Relative
219 GNUNET_TIME_relative_get_forever_ ()
220 {
221   static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
222
223   return forever;
224 }
225
226
227 /**
228  * Return "forever".
229  */
230 struct GNUNET_TIME_Absolute
231 GNUNET_TIME_absolute_get_forever_ ()
232 {
233   static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
234   return forever;
235 }
236
237
238 /**
239  * Convert relative time to an absolute time in the
240  * future.
241  *
242  * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
243  */
244 struct GNUNET_TIME_Absolute
245 GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
246 {
247   struct GNUNET_TIME_Absolute ret;
248
249   if (rel.rel_value_us == UINT64_MAX)
250     return GNUNET_TIME_UNIT_FOREVER_ABS;
251   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
252
253   if (rel.rel_value_us + now.abs_value_us < rel.rel_value_us)
254   {
255     GNUNET_break (0);           /* overflow... */
256     return GNUNET_TIME_UNIT_FOREVER_ABS;
257   }
258   ret.abs_value_us = rel.rel_value_us + now.abs_value_us;
259   return ret;
260 }
261
262
263 /**
264  * Return the minimum of two relative time values.
265  *
266  * @param t1 first timestamp
267  * @param t2 other timestamp
268  * @return timestamp that is smaller
269  */
270 struct GNUNET_TIME_Relative
271 GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
272                           struct GNUNET_TIME_Relative t2)
273 {
274   return (t1.rel_value_us < t2.rel_value_us) ? t1 : t2;
275 }
276
277
278 /**
279  * Return the maximum of two relative time values.
280  *
281  * @param t1 first timestamp
282  * @param t2 other timestamp
283  * @return timestamp that is larger
284  */
285 struct GNUNET_TIME_Relative
286 GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
287                           struct GNUNET_TIME_Relative t2)
288 {
289   return (t1.rel_value_us > t2.rel_value_us) ? t1 : t2;
290 }
291
292
293
294 /**
295  * Return the minimum of two relative time values.
296  *
297  * @param t1 first timestamp
298  * @param t2 other timestamp
299  * @return timestamp that is smaller
300  */
301 struct GNUNET_TIME_Absolute
302 GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
303                           struct GNUNET_TIME_Absolute t2)
304 {
305   return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
306 }
307
308
309 /**
310  * Return the maximum of two relative time values.
311  *
312  * @param t1 first timestamp
313  * @param t2 other timestamp
314  * @return timestamp that is bigger
315  */
316 struct GNUNET_TIME_Absolute
317 GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
318                           struct GNUNET_TIME_Absolute t2)
319 {
320   return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
321 }
322
323
324 /**
325  * Given a timestamp in the future, how much time
326  * remains until then?
327  *
328  * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
329  */
330 struct GNUNET_TIME_Relative
331 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
332 {
333   struct GNUNET_TIME_Relative ret;
334
335   if (future.abs_value_us == UINT64_MAX)
336     return GNUNET_TIME_UNIT_FOREVER_REL;
337   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
338
339   if (now.abs_value_us > future.abs_value_us)
340     return GNUNET_TIME_UNIT_ZERO;
341   ret.rel_value_us = future.abs_value_us - now.abs_value_us;
342   return ret;
343 }
344
345 /**
346  * Compute the time difference between the given start and end times.
347  * Use this function instead of actual subtraction to ensure that
348  * "FOREVER" and overflows are handled correctly.
349  *
350  * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
351  */
352 struct GNUNET_TIME_Relative
353 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
354                                      struct GNUNET_TIME_Absolute end)
355 {
356   struct GNUNET_TIME_Relative ret;
357
358   if (end.abs_value_us == UINT64_MAX)
359     return GNUNET_TIME_UNIT_FOREVER_REL;
360   if (end.abs_value_us < start.abs_value_us)
361     return GNUNET_TIME_UNIT_ZERO;
362   ret.rel_value_us = end.abs_value_us - start.abs_value_us;
363   return ret;
364 }
365
366 /**
367  * Get the duration of an operation as the
368  * difference of the current time and the given start time "whence".
369  *
370  * @return 0 if whence > now, otherwise now-whence.
371  */
372 struct GNUNET_TIME_Relative
373 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
374 {
375   struct GNUNET_TIME_Absolute now;
376   struct GNUNET_TIME_Relative ret;
377
378   now = GNUNET_TIME_absolute_get ();
379   if (whence.abs_value_us > now.abs_value_us)
380     return GNUNET_TIME_UNIT_ZERO;
381   ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
382   return ret;
383 }
384
385
386 /**
387  * Add a given relative duration to the
388  * given start time.
389  *
390  * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
391  */
392 struct GNUNET_TIME_Absolute
393 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
394                           struct GNUNET_TIME_Relative duration)
395 {
396   struct GNUNET_TIME_Absolute ret;
397
398   if ((start.abs_value_us == UINT64_MAX) || (duration.rel_value_us == UINT64_MAX))
399     return GNUNET_TIME_UNIT_FOREVER_ABS;
400   if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
401   {
402     GNUNET_break (0);
403     return GNUNET_TIME_UNIT_FOREVER_ABS;
404   }
405   ret.abs_value_us = start.abs_value_us + duration.rel_value_us;
406   return ret;
407 }
408
409
410 /**
411  * Subtract a given relative duration from the
412  * given start time.
413  *
414  * @param start some absolute time
415  * @param duration some relative time to subtract
416  * @return ZERO if start <= duration, or FOREVER if start time is FOREVER; start-duration otherwise
417  */
418 struct GNUNET_TIME_Absolute
419 GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
420                                struct GNUNET_TIME_Relative duration)
421 {
422   struct GNUNET_TIME_Absolute ret;
423
424   if (start.abs_value_us <= duration.rel_value_us)
425     return GNUNET_TIME_UNIT_ZERO_ABS;
426   if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
427     return GNUNET_TIME_UNIT_FOREVER_ABS;
428   ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
429   return ret;
430 }
431
432
433 /**
434  * Multiply relative time by a given factor.
435  *
436  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
437  */
438 struct GNUNET_TIME_Relative
439 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
440                                unsigned long long factor)
441 {
442   struct GNUNET_TIME_Relative ret;
443
444   if (0 == factor)
445     return GNUNET_TIME_UNIT_ZERO;
446   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
447     return GNUNET_TIME_UNIT_FOREVER_REL;
448   ret.rel_value_us = rel.rel_value_us * factor;
449   if (ret.rel_value_us / factor != rel.rel_value_us)
450   {
451     GNUNET_break (0);
452     return GNUNET_TIME_UNIT_FOREVER_REL;
453   }
454   return ret;
455 }
456
457
458 /**
459  * Multiply relative time by a given floating-point factor.  The factor must be
460  * positive.
461  *
462  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
463  */
464 struct GNUNET_TIME_Relative
465 relative_multiply_double (struct GNUNET_TIME_Relative rel,
466                           double factor)
467 {
468   struct GNUNET_TIME_Relative out;
469   double m;
470
471   GNUNET_assert (0 <= factor);
472
473   if (0 == factor)
474     return GNUNET_TIME_UNIT_ZERO;
475   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
476     return GNUNET_TIME_UNIT_FOREVER_REL;
477
478   m = ((double) rel.rel_value_us) * factor;
479
480   if (m >= (double) (GNUNET_TIME_UNIT_FOREVER_REL).rel_value_us)
481   {
482     GNUNET_break (0);
483     return GNUNET_TIME_UNIT_FOREVER_REL;
484   }
485
486   out.rel_value_us = (uint64_t) m;
487   return out;
488 }
489
490
491 /**
492  * Saturating multiply relative time by a given factor.
493  *
494  * @param rel some duration
495  * @param factor integer to multiply with
496  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
497  */
498 struct GNUNET_TIME_Relative
499 GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
500                                           unsigned long long factor)
501 {
502   struct GNUNET_TIME_Relative ret;
503
504   if (0 == factor)
505     return GNUNET_TIME_UNIT_ZERO;
506   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
507     return GNUNET_TIME_UNIT_FOREVER_REL;
508   ret.rel_value_us = rel.rel_value_us * factor;
509   if (ret.rel_value_us / factor != rel.rel_value_us)
510   {
511     return GNUNET_TIME_UNIT_FOREVER_REL;
512   }
513   return ret;
514 }
515
516
517 /**
518  * Divide relative time by a given factor.
519  *
520  * @param rel some duration
521  * @param factor integer to divide by
522  * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
523  */
524 struct GNUNET_TIME_Relative
525 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
526                              unsigned long long factor)
527 {
528   struct GNUNET_TIME_Relative ret;
529
530   if ((0 == factor) ||
531       (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
532     return GNUNET_TIME_UNIT_FOREVER_REL;
533   ret.rel_value_us = rel.rel_value_us / factor;
534   return ret;
535 }
536
537
538 /**
539  * Calculate the estimate time of arrival/completion
540  * for an operation.
541  *
542  * @param start when did the operation start?
543  * @param finished how much has been done?
544  * @param total how much must be done overall (same unit as for "finished")
545  * @return remaining duration for the operation,
546  *        assuming it continues at the same speed
547  */
548 struct GNUNET_TIME_Relative
549 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
550                            uint64_t total)
551 {
552   struct GNUNET_TIME_Relative dur;
553   double exp;
554   struct GNUNET_TIME_Relative ret;
555
556   GNUNET_break (finished <= total);
557   if (finished >= total)
558     return GNUNET_TIME_UNIT_ZERO;
559   if (0 == finished)
560     return GNUNET_TIME_UNIT_FOREVER_REL;
561   dur = GNUNET_TIME_absolute_get_duration (start);
562   exp = ((double) dur.rel_value_us) * ((double) total) / ((double) finished);
563   ret.rel_value_us = ((uint64_t) exp) - dur.rel_value_us;
564   return ret;
565 }
566
567
568 /**
569  * Add relative times together.
570  *
571  * @param a1 first timestamp
572  * @param a2 second timestamp
573  * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
574  */
575 struct GNUNET_TIME_Relative
576 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
577                           struct GNUNET_TIME_Relative a2)
578 {
579   struct GNUNET_TIME_Relative ret;
580
581   if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
582     return GNUNET_TIME_UNIT_FOREVER_REL;
583   if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
584   {
585     GNUNET_break (0);
586     return GNUNET_TIME_UNIT_FOREVER_REL;
587   }
588   ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
589   return ret;
590 }
591
592
593 /**
594  * Subtract relative timestamp from the other.
595  *
596  * @param a1 first timestamp
597  * @param a2 second timestamp
598  * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise
599  */
600 struct GNUNET_TIME_Relative
601 GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
602                                struct GNUNET_TIME_Relative a2)
603 {
604   struct GNUNET_TIME_Relative ret;
605
606   if (a2.rel_value_us >= a1.rel_value_us)
607     return GNUNET_TIME_UNIT_ZERO;
608   if (a1.rel_value_us == UINT64_MAX)
609     return GNUNET_TIME_UNIT_FOREVER_REL;
610   ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
611   return ret;
612 }
613
614
615 /**
616  * Convert relative time to network byte order.
617  *
618  * @param a time to convert
619  * @return time in network byte order
620  */
621 struct GNUNET_TIME_RelativeNBO
622 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
623 {
624   struct GNUNET_TIME_RelativeNBO ret;
625
626   ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
627   return ret;
628 }
629
630
631 /**
632  * Convert relative time from network byte order.
633  *
634  * @param a time to convert
635  * @return time in host byte order
636  */
637 struct GNUNET_TIME_Relative
638 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
639 {
640   struct GNUNET_TIME_Relative ret;
641
642   ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
643   return ret;
644 }
645
646
647 /**
648  * Convert absolute time to network byte order.
649  *
650  * @param a time to convert
651  * @return time in network byte order
652  */
653 struct GNUNET_TIME_AbsoluteNBO
654 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
655 {
656   struct GNUNET_TIME_AbsoluteNBO ret;
657
658   ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
659   return ret;
660 }
661
662
663 /**
664  * Convert absolute time from network byte order.
665  *
666  * @param a time to convert
667  * @return time in host byte order
668  */
669 struct GNUNET_TIME_Absolute
670 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
671 {
672   struct GNUNET_TIME_Absolute ret;
673
674   ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
675   return ret;
676
677 }
678
679
680 /**
681  * Return the current year (i.e. '2011').
682  */
683 unsigned int
684 GNUNET_TIME_get_current_year ()
685 {
686   time_t tp;
687   struct tm *t;
688
689   tp = time (NULL);
690   t = gmtime (&tp);
691   if (t == NULL)
692     return 0;
693   return t->tm_year + 1900;
694 }
695
696
697 /**
698  * Convert an expiration time to the respective year (rounds)
699  *
700  * @param at absolute time
701  * @return year a year (after 1970), 0 on error
702  */
703 unsigned int
704 GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
705 {
706   struct tm *t;
707   time_t tp;
708
709   tp = at.abs_value_us / 1000LL / 1000LL;    /* microseconds to seconds */
710   t = gmtime (&tp);
711   if (t == NULL)
712     return 0;
713   return t->tm_year + 1900;
714
715 }
716
717
718 /**
719  * Convert a year to an expiration time of January 1st of that year.
720  *
721  * @param year a year (after 1970, please ;-)).
722  * @return absolute time for January 1st of that year.
723  */
724 struct GNUNET_TIME_Absolute
725 GNUNET_TIME_year_to_time (unsigned int year)
726 {
727   struct GNUNET_TIME_Absolute ret;
728   time_t tp;
729   struct tm t;
730
731   memset (&t, 0, sizeof (t));
732   if (year < 1900)
733   {
734     GNUNET_break (0);
735     return GNUNET_TIME_absolute_get (); /* now */
736   }
737   t.tm_year = year - 1900;
738   t.tm_mday = 1;
739   t.tm_mon = 0;
740   t.tm_wday = 1;
741   t.tm_yday = 1;
742   tp = mktime (&t);
743   GNUNET_break (tp != (time_t) - 1);
744   ret.abs_value_us = tp * 1000LL * 1000LL;  /* seconds to microseconds */
745   return ret;
746 }
747
748
749 /**
750  * Randomized exponential back-off, starting at 1 ms
751  * and going up by a factor of 2+r, where 0 <= r <= 0.5, up
752  * to a maximum of the given threshold.
753  *
754  * @param r current backoff time, initially zero
755  * @param threshold maximum value for backoff
756  * @return the next backoff time
757  */
758 struct GNUNET_TIME_Relative
759 GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt, struct GNUNET_TIME_Relative threshold)
760 {
761   double r = (rand() % 500) / 1000.0;
762   struct GNUNET_TIME_Relative t;
763
764   t = relative_multiply_double (GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS,
765                                                           rt),
766                                 2 + r);
767   return GNUNET_TIME_relative_min (threshold,
768                                    t);
769 }
770
771
772 /**
773  * Obtain the current time and make sure it is monotonically
774  * increasing.  Guards against systems without an RTC or
775  * clocks running backwards and other nasty surprises. Does
776  * not guarantee that the returned time is near the current
777  * time returned by #GNUNET_TIME_absolute_get().  Two
778  * subsequent calls (within a short time period) may return the
779  * same value. Persists the last returned time on disk to
780  * ensure that time never goes backwards. As a result, the
781  * resulting value can be used to check if a message is the
782  * "most recent" value and replays of older messages (from
783  * the same origin) would be discarded.
784  *
785  * @param cfg configuration, used to determine where to
786  *   store the time; user can also insist RTC is working
787  *   nicely and disable the feature
788  * @return monotonically increasing time
789  */
790 struct GNUNET_TIME_Absolute
791 GNUNET_TIME_absolute_get_monotonic (const struct GNUNET_CONFIGURATION_Handle *cfg)
792 {
793   static const struct GNUNET_CONFIGURATION_Handle *last_cfg;
794   static struct GNUNET_TIME_Absolute last_time;
795   static struct GNUNET_DISK_MapHandle *map_handle;
796   static ATOMIC volatile uint64_t *map;
797   struct GNUNET_TIME_Absolute now;
798
799   now = GNUNET_TIME_absolute_get ();
800   if (last_cfg != cfg)
801   {
802     char *filename;
803
804     if (NULL != map_handle)
805     {
806       GNUNET_DISK_file_unmap (map_handle);
807       map_handle = NULL;
808     }
809     map = NULL;
810
811     last_cfg = cfg;
812     if ( (NULL != cfg) &&
813          (GNUNET_OK ==
814           GNUNET_CONFIGURATION_get_value_filename (cfg,
815                                                    "util",
816                                                    "MONOTONIC_TIME_FILENAME",
817                                                    &filename)) )
818     {
819       struct GNUNET_DISK_FileHandle *fh;
820
821       fh = GNUNET_DISK_file_open (filename,
822                                   GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE,
823                                   GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_WRITE |
824                                   GNUNET_DISK_PERM_USER_READ  | GNUNET_DISK_PERM_GROUP_READ);
825       if (NULL == fh)
826       {
827         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
828                     _("Failed to map `%s', cannot assure monotonic time!\n"),
829                     filename);
830       }
831       else
832       {
833         off_t size;
834
835         size = 0;
836         GNUNET_break (GNUNET_OK ==
837                       GNUNET_DISK_file_handle_size (fh,
838                                                     &size));
839         if (size < sizeof (*map))
840         {
841           struct GNUNET_TIME_AbsoluteNBO o;
842
843           o = GNUNET_TIME_absolute_hton (now);
844           if (sizeof (o) !=
845               GNUNET_DISK_file_write (fh,
846                                       &o,
847                                       sizeof (o)))
848             size = 0;
849           else
850             size = sizeof (o);
851         }
852         if (size == sizeof (*map))
853         {
854           map = GNUNET_DISK_file_map (fh,
855                                       &map_handle,
856                                       GNUNET_DISK_MAP_TYPE_READWRITE,
857                                       sizeof (*map));
858           if (NULL == map)
859             GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
860                         _("Failed to map `%s', cannot assure monotonic time!\n"),
861                         filename);
862         }
863         else
864         {
865           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
866                       _("Failed to setup monotonic time file `%s', cannot assure monotonic time!\n"),
867                       filename);
868         }
869       }
870       GNUNET_DISK_file_close (fh);
871       GNUNET_free (filename);
872     }
873   }
874   if (NULL != map)
875   {
876     struct GNUNET_TIME_AbsoluteNBO mt;
877
878 #if __STDC_NO_ATOMICS__
879 #if __GNUC__
880     mt.abs_value_us__ = __sync_fetch_and_or (map, 0);
881 #else
882     mt.abs_value_us__ = *map; /* godspeed, pray this is atomic */
883 #endif
884 #else
885     mt.abs_value_us__ = atomic_load (map);
886 #endif
887     last_time = GNUNET_TIME_absolute_max (GNUNET_TIME_absolute_ntoh (mt),
888                                           last_time);
889   }
890   if (now.abs_value_us <= last_time.abs_value_us)
891     now.abs_value_us = last_time.abs_value_us+1;
892   last_time = now;
893   if (NULL != map)
894   {
895     uint64_t val = GNUNET_TIME_absolute_hton (now).abs_value_us__;
896 #if __STDC_NO_ATOMICS__
897 #if __GNUC__
898     (void) __sync_lock_test_and_set (map, val);
899 #else
900     *map = val;  /* godspeed, pray this is atomic */
901 #endif
902 #else
903     atomic_store (map,
904                   val);
905 #endif
906   }
907   return now;
908 }
909
910
911 /**
912  * Destructor
913  */
914 void __attribute__ ((destructor))
915 GNUNET_util_time_fini ()
916 {
917   (void) GNUNET_TIME_absolute_get_monotonic (NULL);
918 }
919
920 /* end of time.c */