Merge branch 'master' of git+ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / util / time.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2001-2013 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
19 /**
20  * @file util/time.c
21  * @author Christian Grothoff
22  * @brief functions for handling time and time arithmetic
23  */
24 #include "platform.h"
25 #include "gnunet_crypto_lib.h"
26 #include "gnunet_time_lib.h"
27
28 #define LOG(kind,...) GNUNET_log_from (kind, "util-time", __VA_ARGS__)
29
30 /**
31  * Variable used to simulate clock skew.  Used for testing, never in production.
32  */
33 static long long timestamp_offset;
34
35 /**
36  * Set the timestamp offset for this instance.
37  *
38  * @param offset the offset to skew the locale time by
39  */
40 void
41 GNUNET_TIME_set_offset (long long offset)
42 {
43   timestamp_offset = offset;
44 }
45
46
47 /**
48  * Get the timestamp offset for this instance.
49  *
50  * @return the offset we currently skew the locale time by
51  */
52 long long
53 GNUNET_TIME_get_offset ()
54 {
55   return timestamp_offset;
56 }
57
58
59 /**
60  * Round a time value so that it is suitable for transmission
61  * via JSON encodings.
62  *
63  * @param at time to round
64  * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
65  *         it was just now rounded
66  */
67 int
68 GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at)
69 {
70   if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
71     return GNUNET_OK;
72   if (0 == at->abs_value_us % 1000000)
73     return GNUNET_OK;
74   at->abs_value_us -= at->abs_value_us % 1000000;
75   return GNUNET_NO;
76 }
77
78
79 /**
80  * Round a time value so that it is suitable for transmission
81  * via JSON encodings.
82  *
83  * @param rt time to round
84  * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
85  *         it was just now rounded
86  */
87 int
88 GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt)
89 {
90   if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
91     return GNUNET_OK;
92   if (0 == rt->rel_value_us % 1000000)
93     return GNUNET_OK;
94   rt->rel_value_us -= rt->rel_value_us % 1000000;
95   return GNUNET_NO;
96 }
97
98
99 /**
100  * Get the current time (works just as "time", just that we use the
101  * unit of time that the cron-jobs use (and is 64 bit)).
102  *
103  * @return the current time
104  */
105 struct GNUNET_TIME_Absolute
106 GNUNET_TIME_absolute_get ()
107 {
108   struct GNUNET_TIME_Absolute ret;
109   struct timeval tv;
110
111   GETTIMEOFDAY (&tv, NULL);
112   ret.abs_value_us =
113       (uint64_t) (((uint64_t) tv.tv_sec * 1000LL * 1000LL) +
114                   ((uint64_t) tv.tv_usec)) + timestamp_offset;
115   return ret;
116 }
117
118
119 /**
120  * Return relative time of 0ms.
121  */
122 struct GNUNET_TIME_Relative
123 GNUNET_TIME_relative_get_zero_ ()
124 {
125   static struct GNUNET_TIME_Relative zero;
126
127   return zero;
128 }
129
130
131 /**
132  * Return absolute time of 0ms.
133  */
134 struct GNUNET_TIME_Absolute
135 GNUNET_TIME_absolute_get_zero_ ()
136 {
137   static struct GNUNET_TIME_Absolute zero;
138
139   return zero;
140 }
141
142
143 /**
144  * Return relative time of 1us.
145  */
146 struct GNUNET_TIME_Relative
147 GNUNET_TIME_relative_get_unit_ ()
148 {
149   static struct GNUNET_TIME_Relative one = { 1 };
150
151   return one;
152 }
153
154
155 /**
156  * Return relative time of 1ms.
157  */
158 struct GNUNET_TIME_Relative
159 GNUNET_TIME_relative_get_millisecond_ ()
160 {
161   static struct GNUNET_TIME_Relative one = { 1000 };
162
163   return one;
164 }
165
166
167 /**
168  * Return relative time of 1s.
169  */
170 struct GNUNET_TIME_Relative
171 GNUNET_TIME_relative_get_second_ ()
172 {
173   static struct GNUNET_TIME_Relative one = { 1000 * 1000LL };
174
175   return one;
176 }
177
178
179 /**
180  * Return relative time of 1 minute.
181  */
182 struct GNUNET_TIME_Relative
183 GNUNET_TIME_relative_get_minute_ ()
184 {
185   static struct GNUNET_TIME_Relative one = { 60 * 1000 * 1000LL };
186
187   return one;
188 }
189
190
191 /**
192  * Return relative time of 1 hour.
193  */
194 struct GNUNET_TIME_Relative
195 GNUNET_TIME_relative_get_hour_ ()
196 {
197   static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 * 1000LL };
198
199   return one;
200 }
201
202
203 /**
204  * Return "forever".
205  */
206 struct GNUNET_TIME_Relative
207 GNUNET_TIME_relative_get_forever_ ()
208 {
209   static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
210
211   return forever;
212 }
213
214
215 /**
216  * Return "forever".
217  */
218 struct GNUNET_TIME_Absolute
219 GNUNET_TIME_absolute_get_forever_ ()
220 {
221   static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
222   return forever;
223 }
224
225
226 /**
227  * Convert relative time to an absolute time in the
228  * future.
229  *
230  * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
231  */
232 struct GNUNET_TIME_Absolute
233 GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
234 {
235   struct GNUNET_TIME_Absolute ret;
236
237   if (rel.rel_value_us == UINT64_MAX)
238     return GNUNET_TIME_UNIT_FOREVER_ABS;
239   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
240
241   if (rel.rel_value_us + now.abs_value_us < rel.rel_value_us)
242   {
243     GNUNET_break (0);           /* overflow... */
244     return GNUNET_TIME_UNIT_FOREVER_ABS;
245   }
246   ret.abs_value_us = rel.rel_value_us + now.abs_value_us;
247   return ret;
248 }
249
250
251 /**
252  * Return the minimum of two relative time values.
253  *
254  * @param t1 first timestamp
255  * @param t2 other timestamp
256  * @return timestamp that is smaller
257  */
258 struct GNUNET_TIME_Relative
259 GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
260                           struct GNUNET_TIME_Relative t2)
261 {
262   return (t1.rel_value_us < t2.rel_value_us) ? t1 : t2;
263 }
264
265
266 /**
267  * Return the maximum of two relative time values.
268  *
269  * @param t1 first timestamp
270  * @param t2 other timestamp
271  * @return timestamp that is larger
272  */
273 struct GNUNET_TIME_Relative
274 GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
275                           struct GNUNET_TIME_Relative t2)
276 {
277   return (t1.rel_value_us > t2.rel_value_us) ? t1 : t2;
278 }
279
280
281
282 /**
283  * Return the minimum of two relative time values.
284  *
285  * @param t1 first timestamp
286  * @param t2 other timestamp
287  * @return timestamp that is smaller
288  */
289 struct GNUNET_TIME_Absolute
290 GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
291                           struct GNUNET_TIME_Absolute t2)
292 {
293   return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
294 }
295
296
297 /**
298  * Return the maximum of two relative time values.
299  *
300  * @param t1 first timestamp
301  * @param t2 other timestamp
302  * @return timestamp that is bigger
303  */
304 struct GNUNET_TIME_Absolute
305 GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
306                           struct GNUNET_TIME_Absolute t2)
307 {
308   return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
309 }
310
311
312 /**
313  * Given a timestamp in the future, how much time
314  * remains until then?
315  *
316  * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
317  */
318 struct GNUNET_TIME_Relative
319 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
320 {
321   struct GNUNET_TIME_Relative ret;
322
323   if (future.abs_value_us == UINT64_MAX)
324     return GNUNET_TIME_UNIT_FOREVER_REL;
325   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
326
327   if (now.abs_value_us > future.abs_value_us)
328     return GNUNET_TIME_UNIT_ZERO;
329   ret.rel_value_us = future.abs_value_us - now.abs_value_us;
330   return ret;
331 }
332
333 /**
334  * Compute the time difference between the given start and end times.
335  * Use this function instead of actual subtraction to ensure that
336  * "FOREVER" and overflows are handled correctly.
337  *
338  * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
339  */
340 struct GNUNET_TIME_Relative
341 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
342                                      struct GNUNET_TIME_Absolute end)
343 {
344   struct GNUNET_TIME_Relative ret;
345
346   if (end.abs_value_us == UINT64_MAX)
347     return GNUNET_TIME_UNIT_FOREVER_REL;
348   if (end.abs_value_us < start.abs_value_us)
349     return GNUNET_TIME_UNIT_ZERO;
350   ret.rel_value_us = end.abs_value_us - start.abs_value_us;
351   return ret;
352 }
353
354 /**
355  * Get the duration of an operation as the
356  * difference of the current time and the given start time "whence".
357  *
358  * @return 0 if whence > now, otherwise now-whence.
359  */
360 struct GNUNET_TIME_Relative
361 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
362 {
363   struct GNUNET_TIME_Absolute now;
364   struct GNUNET_TIME_Relative ret;
365
366   now = GNUNET_TIME_absolute_get ();
367   if (whence.abs_value_us > now.abs_value_us)
368     return GNUNET_TIME_UNIT_ZERO;
369   ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
370   return ret;
371 }
372
373
374 /**
375  * Add a given relative duration to the
376  * given start time.
377  *
378  * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
379  */
380 struct GNUNET_TIME_Absolute
381 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
382                           struct GNUNET_TIME_Relative duration)
383 {
384   struct GNUNET_TIME_Absolute ret;
385
386   if ((start.abs_value_us == UINT64_MAX) || (duration.rel_value_us == UINT64_MAX))
387     return GNUNET_TIME_UNIT_FOREVER_ABS;
388   if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
389   {
390     GNUNET_break (0);
391     return GNUNET_TIME_UNIT_FOREVER_ABS;
392   }
393   ret.abs_value_us = start.abs_value_us + duration.rel_value_us;
394   return ret;
395 }
396
397
398 /**
399  * Subtract a given relative duration from the
400  * given start time.
401  *
402  * @param start some absolute time
403  * @param duration some relative time to subtract
404  * @return ZERO if start <= duration, or FOREVER if start time is FOREVER; start-duration otherwise
405  */
406 struct GNUNET_TIME_Absolute
407 GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
408                                struct GNUNET_TIME_Relative duration)
409 {
410   struct GNUNET_TIME_Absolute ret;
411
412   if (start.abs_value_us <= duration.rel_value_us)
413     return GNUNET_TIME_UNIT_ZERO_ABS;
414   if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
415     return GNUNET_TIME_UNIT_FOREVER_ABS;
416   ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
417   return ret;
418 }
419
420
421 /**
422  * Multiply relative time by a given factor.
423  *
424  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
425  */
426 struct GNUNET_TIME_Relative
427 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
428                                unsigned long long factor)
429 {
430   struct GNUNET_TIME_Relative ret;
431
432   if (0 == factor)
433     return GNUNET_TIME_UNIT_ZERO;
434   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
435     return GNUNET_TIME_UNIT_FOREVER_REL;
436   ret.rel_value_us = rel.rel_value_us * factor;
437   if (ret.rel_value_us / factor != rel.rel_value_us)
438   {
439     GNUNET_break (0);
440     return GNUNET_TIME_UNIT_FOREVER_REL;
441   }
442   return ret;
443 }
444
445
446 /**
447  * Multiply relative time by a given floating-point factor.  The factor must be
448  * positive.
449  *
450  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
451  */
452 struct GNUNET_TIME_Relative
453 relative_multiply_double (struct GNUNET_TIME_Relative rel,
454                           double factor)
455 {
456   struct GNUNET_TIME_Relative out;
457   double m;
458
459   GNUNET_assert (0 <= factor);
460
461   if (0 == factor)
462     return GNUNET_TIME_UNIT_ZERO;
463   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
464     return GNUNET_TIME_UNIT_FOREVER_REL;
465
466   m = ((double) rel.rel_value_us) * factor;
467
468   if (m >= (double) (GNUNET_TIME_UNIT_FOREVER_REL).rel_value_us)
469   {
470     GNUNET_break (0);
471     return GNUNET_TIME_UNIT_FOREVER_REL;
472   }
473
474   out.rel_value_us = (uint64_t) m;
475   return out;
476 }
477
478
479 /**
480  * Saturating multiply relative time by a given factor.
481  *
482  * @param rel some duration
483  * @param factor integer to multiply with
484  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
485  */
486 struct GNUNET_TIME_Relative
487 GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
488                                           unsigned long long factor)
489 {
490   struct GNUNET_TIME_Relative ret;
491
492   if (0 == factor)
493     return GNUNET_TIME_UNIT_ZERO;
494   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
495     return GNUNET_TIME_UNIT_FOREVER_REL;
496   ret.rel_value_us = rel.rel_value_us * factor;
497   if (ret.rel_value_us / factor != rel.rel_value_us)
498   {
499     return GNUNET_TIME_UNIT_FOREVER_REL;
500   }
501   return ret;
502 }
503
504
505 /**
506  * Divide relative time by a given factor.
507  *
508  * @param rel some duration
509  * @param factor integer to divide by
510  * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
511  */
512 struct GNUNET_TIME_Relative
513 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
514                              unsigned long long factor)
515 {
516   struct GNUNET_TIME_Relative ret;
517
518   if ((0 == factor) ||
519       (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
520     return GNUNET_TIME_UNIT_FOREVER_REL;
521   ret.rel_value_us = rel.rel_value_us / factor;
522   return ret;
523 }
524
525
526 /**
527  * Calculate the estimate time of arrival/completion
528  * for an operation.
529  *
530  * @param start when did the operation start?
531  * @param finished how much has been done?
532  * @param total how much must be done overall (same unit as for "finished")
533  * @return remaining duration for the operation,
534  *        assuming it continues at the same speed
535  */
536 struct GNUNET_TIME_Relative
537 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
538                            uint64_t total)
539 {
540   struct GNUNET_TIME_Relative dur;
541   double exp;
542   struct GNUNET_TIME_Relative ret;
543
544   GNUNET_break (finished <= total);
545   if (finished >= total)
546     return GNUNET_TIME_UNIT_ZERO;
547   if (0 == finished)
548     return GNUNET_TIME_UNIT_FOREVER_REL;
549   dur = GNUNET_TIME_absolute_get_duration (start);
550   exp = ((double) dur.rel_value_us) * ((double) total) / ((double) finished);
551   ret.rel_value_us = ((uint64_t) exp) - dur.rel_value_us;
552   return ret;
553 }
554
555
556 /**
557  * Add relative times together.
558  *
559  * @param a1 first timestamp
560  * @param a2 second timestamp
561  * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
562  */
563 struct GNUNET_TIME_Relative
564 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
565                           struct GNUNET_TIME_Relative a2)
566 {
567   struct GNUNET_TIME_Relative ret;
568
569   if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
570     return GNUNET_TIME_UNIT_FOREVER_REL;
571   if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
572   {
573     GNUNET_break (0);
574     return GNUNET_TIME_UNIT_FOREVER_REL;
575   }
576   ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
577   return ret;
578 }
579
580
581 /**
582  * Subtract relative timestamp from the other.
583  *
584  * @param a1 first timestamp
585  * @param a2 second timestamp
586  * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise
587  */
588 struct GNUNET_TIME_Relative
589 GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
590                                struct GNUNET_TIME_Relative a2)
591 {
592   struct GNUNET_TIME_Relative ret;
593
594   if (a2.rel_value_us >= a1.rel_value_us)
595     return GNUNET_TIME_UNIT_ZERO;
596   if (a1.rel_value_us == UINT64_MAX)
597     return GNUNET_TIME_UNIT_FOREVER_REL;
598   ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
599   return ret;
600 }
601
602
603 /**
604  * Convert relative time to network byte order.
605  *
606  * @param a time to convert
607  * @return time in network byte order
608  */
609 struct GNUNET_TIME_RelativeNBO
610 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
611 {
612   struct GNUNET_TIME_RelativeNBO ret;
613
614   ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
615   return ret;
616 }
617
618
619 /**
620  * Convert relative time from network byte order.
621  *
622  * @param a time to convert
623  * @return time in host byte order
624  */
625 struct GNUNET_TIME_Relative
626 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
627 {
628   struct GNUNET_TIME_Relative ret;
629
630   ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
631   return ret;
632 }
633
634
635 /**
636  * Convert absolute time to network byte order.
637  *
638  * @param a time to convert
639  * @return time in network byte order
640  */
641 struct GNUNET_TIME_AbsoluteNBO
642 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
643 {
644   struct GNUNET_TIME_AbsoluteNBO ret;
645
646   ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
647   return ret;
648 }
649
650
651 /**
652  * Convert absolute time from network byte order.
653  *
654  * @param a time to convert
655  * @return time in host byte order
656  */
657 struct GNUNET_TIME_Absolute
658 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
659 {
660   struct GNUNET_TIME_Absolute ret;
661
662   ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
663   return ret;
664
665 }
666
667
668 /**
669  * Return the current year (i.e. '2011').
670  */
671 unsigned int
672 GNUNET_TIME_get_current_year ()
673 {
674   time_t tp;
675   struct tm *t;
676
677   tp = time (NULL);
678   t = gmtime (&tp);
679   if (t == NULL)
680     return 0;
681   return t->tm_year + 1900;
682 }
683
684
685 /**
686  * Convert an expiration time to the respective year (rounds)
687  *
688  * @param at absolute time
689  * @return year a year (after 1970), 0 on error
690  */
691 unsigned int
692 GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
693 {
694   struct tm *t;
695   time_t tp;
696
697   tp = at.abs_value_us / 1000LL / 1000LL;    /* microseconds to seconds */
698   t = gmtime (&tp);
699   if (t == NULL)
700     return 0;
701   return t->tm_year + 1900;
702
703 }
704
705
706 /**
707  * Convert a year to an expiration time of January 1st of that year.
708  *
709  * @param year a year (after 1970, please ;-)).
710  * @return absolute time for January 1st of that year.
711  */
712 struct GNUNET_TIME_Absolute
713 GNUNET_TIME_year_to_time (unsigned int year)
714 {
715   struct GNUNET_TIME_Absolute ret;
716   time_t tp;
717   struct tm t;
718
719   memset (&t, 0, sizeof (t));
720   if (year < 1900)
721   {
722     GNUNET_break (0);
723     return GNUNET_TIME_absolute_get (); /* now */
724   }
725   t.tm_year = year - 1900;
726   t.tm_mday = 1;
727   t.tm_mon = 0;
728   t.tm_wday = 1;
729   t.tm_yday = 1;
730   tp = mktime (&t);
731   GNUNET_break (tp != (time_t) - 1);
732   ret.abs_value_us = tp * 1000LL * 1000LL;  /* seconds to microseconds */
733   return ret;
734 }
735
736
737 /**
738  * Randomized exponential back-off, starting at 1 ms
739  * and going up by a factor of 2+r, where 0 <= r <= 0.5, up
740  * to a maximum of the given threshold.
741  *
742  * @param r current backoff time, initially zero
743  * @param threshold maximum value for backoff
744  * @return the next backoff time
745  */
746 struct GNUNET_TIME_Relative
747 GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt, struct GNUNET_TIME_Relative threshold)
748 {
749   double r = (rand() % 500) / 1000.0;
750   struct GNUNET_TIME_Relative t;
751
752   t = relative_multiply_double (GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS,
753                                                           rt),
754                                 2 + r);
755   return GNUNET_TIME_relative_min (threshold,
756                                    t);
757 }
758
759
760
761
762 /* end of time.c */