first step to remove plibc
[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 = (uint64_t) (((uint64_t) tv.tv_sec * 1000LL * 1000LL) +
125                                  ((uint64_t) tv.tv_usec)) +
126                      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  * Return the minimum of two relative time values.
295  *
296  * @param t1 first timestamp
297  * @param t2 other timestamp
298  * @return timestamp that is smaller
299  */
300 struct GNUNET_TIME_Absolute
301 GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
302                           struct GNUNET_TIME_Absolute t2)
303 {
304   return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
305 }
306
307
308 /**
309  * Return the maximum of two relative time values.
310  *
311  * @param t1 first timestamp
312  * @param t2 other timestamp
313  * @return timestamp that is bigger
314  */
315 struct GNUNET_TIME_Absolute
316 GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
317                           struct GNUNET_TIME_Absolute t2)
318 {
319   return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
320 }
321
322
323 /**
324  * Given a timestamp in the future, how much time
325  * remains until then?
326  *
327  * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
328  */
329 struct GNUNET_TIME_Relative
330 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
331 {
332   struct GNUNET_TIME_Relative ret;
333
334   if (future.abs_value_us == UINT64_MAX)
335     return GNUNET_TIME_UNIT_FOREVER_REL;
336   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
337
338   if (now.abs_value_us > future.abs_value_us)
339     return GNUNET_TIME_UNIT_ZERO;
340   ret.rel_value_us = future.abs_value_us - now.abs_value_us;
341   return ret;
342 }
343
344 /**
345  * Compute the time difference between the given start and end times.
346  * Use this function instead of actual subtraction to ensure that
347  * "FOREVER" and overflows are handled correctly.
348  *
349  * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
350  */
351 struct GNUNET_TIME_Relative
352 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
353                                      struct GNUNET_TIME_Absolute end)
354 {
355   struct GNUNET_TIME_Relative ret;
356
357   if (end.abs_value_us == UINT64_MAX)
358     return GNUNET_TIME_UNIT_FOREVER_REL;
359   if (end.abs_value_us < start.abs_value_us)
360     return GNUNET_TIME_UNIT_ZERO;
361   ret.rel_value_us = end.abs_value_us - start.abs_value_us;
362   return ret;
363 }
364
365 /**
366  * Get the duration of an operation as the
367  * difference of the current time and the given start time "whence".
368  *
369  * @return 0 if whence > now, otherwise now-whence.
370  */
371 struct GNUNET_TIME_Relative
372 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
373 {
374   struct GNUNET_TIME_Absolute now;
375   struct GNUNET_TIME_Relative ret;
376
377   now = GNUNET_TIME_absolute_get ();
378   if (whence.abs_value_us > now.abs_value_us)
379     return GNUNET_TIME_UNIT_ZERO;
380   ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
381   return ret;
382 }
383
384
385 /**
386  * Add a given relative duration to the
387  * given start time.
388  *
389  * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
390  */
391 struct GNUNET_TIME_Absolute
392 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
393                           struct GNUNET_TIME_Relative duration)
394 {
395   struct GNUNET_TIME_Absolute ret;
396
397   if ((start.abs_value_us == UINT64_MAX) ||
398       (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, double factor)
466 {
467   struct GNUNET_TIME_Relative out;
468   double m;
469
470   GNUNET_assert (0 <= factor);
471
472   if (0 == factor)
473     return GNUNET_TIME_UNIT_ZERO;
474   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
475     return GNUNET_TIME_UNIT_FOREVER_REL;
476
477   m = ((double) rel.rel_value_us) * factor;
478
479   if (m >= (double) (GNUNET_TIME_UNIT_FOREVER_REL).rel_value_us)
480   {
481     GNUNET_break (0);
482     return GNUNET_TIME_UNIT_FOREVER_REL;
483   }
484
485   out.rel_value_us = (uint64_t) m;
486   return out;
487 }
488
489
490 /**
491  * Saturating multiply relative time by a given factor.
492  *
493  * @param rel some duration
494  * @param factor integer to multiply with
495  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
496  */
497 struct GNUNET_TIME_Relative
498 GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
499                                           unsigned long long factor)
500 {
501   struct GNUNET_TIME_Relative ret;
502
503   if (0 == factor)
504     return GNUNET_TIME_UNIT_ZERO;
505   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
506     return GNUNET_TIME_UNIT_FOREVER_REL;
507   ret.rel_value_us = rel.rel_value_us * factor;
508   if (ret.rel_value_us / factor != rel.rel_value_us)
509   {
510     return GNUNET_TIME_UNIT_FOREVER_REL;
511   }
512   return ret;
513 }
514
515
516 /**
517  * Divide relative time by a given factor.
518  *
519  * @param rel some duration
520  * @param factor integer to divide by
521  * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
522  */
523 struct GNUNET_TIME_Relative
524 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
525                              unsigned long long factor)
526 {
527   struct GNUNET_TIME_Relative ret;
528
529   if ((0 == factor) ||
530       (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
531     return GNUNET_TIME_UNIT_FOREVER_REL;
532   ret.rel_value_us = rel.rel_value_us / factor;
533   return ret;
534 }
535
536
537 /**
538  * Calculate the estimate time of arrival/completion
539  * for an operation.
540  *
541  * @param start when did the operation start?
542  * @param finished how much has been done?
543  * @param total how much must be done overall (same unit as for "finished")
544  * @return remaining duration for the operation,
545  *        assuming it continues at the same speed
546  */
547 struct GNUNET_TIME_Relative
548 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
549                            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  * Return the current year (i.e. '2011').
681  */
682 unsigned int
683 GNUNET_TIME_get_current_year ()
684 {
685   time_t tp;
686   struct tm *t;
687
688   tp = time (NULL);
689   t = gmtime (&tp);
690   if (t == NULL)
691     return 0;
692   return t->tm_year + 1900;
693 }
694
695
696 /**
697  * Convert an expiration time to the respective year (rounds)
698  *
699  * @param at absolute time
700  * @return year a year (after 1970), 0 on error
701  */
702 unsigned int
703 GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
704 {
705   struct tm *t;
706   time_t tp;
707
708   tp = at.abs_value_us / 1000LL / 1000LL; /* microseconds to seconds */
709   t = gmtime (&tp);
710   if (t == NULL)
711     return 0;
712   return t->tm_year + 1900;
713 }
714
715
716 /**
717  * Convert a year to an expiration time of January 1st of that year.
718  *
719  * @param year a year (after 1970, please ;-)).
720  * @return absolute time for January 1st of that year.
721  */
722 struct GNUNET_TIME_Absolute
723 GNUNET_TIME_year_to_time (unsigned int year)
724 {
725   struct GNUNET_TIME_Absolute ret;
726   time_t tp;
727   struct tm t;
728
729   memset (&t, 0, sizeof (t));
730   if (year < 1900)
731   {
732     GNUNET_break (0);
733     return GNUNET_TIME_absolute_get (); /* now */
734   }
735   t.tm_year = year - 1900;
736   t.tm_mday = 1;
737   t.tm_mon = 0;
738   t.tm_wday = 1;
739   t.tm_yday = 1;
740   tp = mktime (&t);
741   GNUNET_break (tp != (time_t) -1);
742   ret.abs_value_us = tp * 1000LL * 1000LL; /* seconds to microseconds */
743   return ret;
744 }
745
746
747 /**
748  * Randomized exponential back-off, starting at 1 ms
749  * and going up by a factor of 2+r, where 0 <= r <= 0.5, up
750  * to a maximum of the given threshold.
751  *
752  * @param r current backoff time, initially zero
753  * @param threshold maximum value for backoff
754  * @return the next backoff time
755  */
756 struct GNUNET_TIME_Relative
757 GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt,
758                                 struct GNUNET_TIME_Relative threshold)
759 {
760   double r = (rand () % 500) / 1000.0;
761   struct GNUNET_TIME_Relative t;
762
763   t = relative_multiply_double (
764     GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, rt),
765     2 + r);
766   return GNUNET_TIME_relative_min (threshold, t);
767 }
768
769
770 /**
771  * Return a random time value between 0.5*r and 1.5*r.
772  *
773  * @param r input time for scaling
774  * @return randomized time
775  */
776 struct GNUNET_TIME_Relative
777 GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r)
778 {
779   double d = ((rand () % 1001) - 500) / 1000.0;
780
781   return relative_multiply_double (r, d);
782 }
783
784
785 /**
786  * Obtain the current time and make sure it is monotonically
787  * increasing.  Guards against systems without an RTC or
788  * clocks running backwards and other nasty surprises. Does
789  * not guarantee that the returned time is near the current
790  * time returned by #GNUNET_TIME_absolute_get().  Two
791  * subsequent calls (within a short time period) may return the
792  * same value. Persists the last returned time on disk to
793  * ensure that time never goes backwards. As a result, the
794  * resulting value can be used to check if a message is the
795  * "most recent" value and replays of older messages (from
796  * the same origin) would be discarded.
797  *
798  * @param cfg configuration, used to determine where to
799  *   store the time; user can also insist RTC is working
800  *   nicely and disable the feature
801  * @return monotonically increasing time
802  */
803 struct GNUNET_TIME_Absolute
804 GNUNET_TIME_absolute_get_monotonic (
805   const struct GNUNET_CONFIGURATION_Handle *cfg)
806 {
807   static const struct GNUNET_CONFIGURATION_Handle *last_cfg;
808   static struct GNUNET_TIME_Absolute last_time;
809   static struct GNUNET_DISK_MapHandle *map_handle;
810   static ATOMIC volatile uint64_t *map;
811   struct GNUNET_TIME_Absolute now;
812
813   now = GNUNET_TIME_absolute_get ();
814   if (last_cfg != cfg)
815   {
816     char *filename;
817
818     if (NULL != map_handle)
819     {
820       GNUNET_DISK_file_unmap (map_handle);
821       map_handle = NULL;
822     }
823     map = NULL;
824
825     last_cfg = cfg;
826     if ((NULL != cfg) &&
827         (GNUNET_OK ==
828          GNUNET_CONFIGURATION_get_value_filename (cfg,
829                                                   "util",
830                                                   "MONOTONIC_TIME_FILENAME",
831                                                   &filename)))
832     {
833       struct GNUNET_DISK_FileHandle *fh;
834
835       fh = GNUNET_DISK_file_open (filename,
836                                   GNUNET_DISK_OPEN_READWRITE |
837                                     GNUNET_DISK_OPEN_CREATE,
838                                   GNUNET_DISK_PERM_USER_WRITE |
839                                     GNUNET_DISK_PERM_GROUP_WRITE |
840                                     GNUNET_DISK_PERM_USER_READ |
841                                     GNUNET_DISK_PERM_GROUP_READ);
842       if (NULL == fh)
843       {
844         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
845                     _ ("Failed to map `%s', cannot assure monotonic time!\n"),
846                     filename);
847       }
848       else
849       {
850         off_t size;
851
852         size = 0;
853         GNUNET_break (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &size));
854         if (size < (off_t) sizeof (*map))
855         {
856           struct GNUNET_TIME_AbsoluteNBO o;
857
858           o = GNUNET_TIME_absolute_hton (now);
859           if (sizeof (o) != GNUNET_DISK_file_write (fh, &o, sizeof (o)))
860             size = 0;
861           else
862             size = sizeof (o);
863         }
864         if (size == sizeof (*map))
865         {
866           map = GNUNET_DISK_file_map (fh,
867                                       &map_handle,
868                                       GNUNET_DISK_MAP_TYPE_READWRITE,
869                                       sizeof (*map));
870           if (NULL == map)
871             GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
872                         _ (
873                           "Failed to map `%s', cannot assure monotonic time!\n"),
874                         filename);
875         }
876         else
877         {
878           GNUNET_log (
879             GNUNET_ERROR_TYPE_WARNING,
880             _ (
881               "Failed to setup monotonic time file `%s', cannot assure monotonic time!\n"),
882             filename);
883         }
884       }
885       GNUNET_DISK_file_close (fh);
886       GNUNET_free (filename);
887     }
888   }
889   if (NULL != map)
890   {
891     struct GNUNET_TIME_AbsoluteNBO mt;
892
893 #if __STDC_NO_ATOMICS__
894 #if __GNUC__
895     mt.abs_value_us__ = __sync_fetch_and_or (map, 0);
896 #else
897     mt.abs_value_us__ = *map; /* godspeed, pray this is atomic */
898 #endif
899 #else
900     mt.abs_value_us__ = atomic_load (map);
901 #endif
902     last_time =
903       GNUNET_TIME_absolute_max (GNUNET_TIME_absolute_ntoh (mt), last_time);
904   }
905   if (now.abs_value_us <= last_time.abs_value_us)
906     now.abs_value_us = last_time.abs_value_us + 1;
907   last_time = now;
908   if (NULL != map)
909   {
910     uint64_t val = GNUNET_TIME_absolute_hton (now).abs_value_us__;
911 #if __STDC_NO_ATOMICS__
912 #if __GNUC__
913     (void) __sync_lock_test_and_set (map, val);
914 #else
915     *map = val; /* godspeed, pray this is atomic */
916 #endif
917 #else
918     atomic_store (map, val);
919 #endif
920   }
921   return now;
922 }
923
924
925 /**
926  * Destructor
927  */
928 void __attribute__ ((destructor)) GNUNET_util_time_fini ()
929 {
930   (void) GNUNET_TIME_absolute_get_monotonic (NULL);
931 }
932
933 /* end of time.c */