2 This file is part of GNUnet.
3 Copyright (C) 2001-2013 GNUnet e.V.
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.
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.
18 * @author Christian Grothoff
19 * @brief functions for handling time and time arithmetic
22 #include "gnunet_crypto_lib.h"
23 #include "gnunet_time_lib.h"
25 #define LOG(kind,...) GNUNET_log_from (kind, "util-time", __VA_ARGS__)
28 * Variable used to simulate clock skew. Used for testing, never in production.
30 static long long timestamp_offset;
33 * Set the timestamp offset for this instance.
35 * @param offset the offset to skew the locale time by
38 GNUNET_TIME_set_offset (long long offset)
40 timestamp_offset = offset;
45 * Get the timestamp offset for this instance.
47 * @return the offset we currently skew the locale time by
50 GNUNET_TIME_get_offset ()
52 return timestamp_offset;
57 * Round a time value so that it is suitable for transmission
60 * @param at time to round
61 * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
62 * it was just now rounded
65 GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at)
67 if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
69 if (0 == at->abs_value_us % 1000000)
71 at->abs_value_us -= at->abs_value_us % 1000000;
77 * Round a time value so that it is suitable for transmission
80 * @param rt time to round
81 * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
82 * it was just now rounded
85 GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt)
87 if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
89 if (0 == rt->rel_value_us % 1000000)
91 rt->rel_value_us -= rt->rel_value_us % 1000000;
97 * Get the current time (works just as "time", just that we use the
98 * unit of time that the cron-jobs use (and is 64 bit)).
100 * @return the current time
102 struct GNUNET_TIME_Absolute
103 GNUNET_TIME_absolute_get ()
105 struct GNUNET_TIME_Absolute ret;
108 GETTIMEOFDAY (&tv, NULL);
110 (uint64_t) (((uint64_t) tv.tv_sec * 1000LL * 1000LL) +
111 ((uint64_t) tv.tv_usec)) + timestamp_offset;
117 * Return relative time of 0ms.
119 struct GNUNET_TIME_Relative
120 GNUNET_TIME_relative_get_zero_ ()
122 static struct GNUNET_TIME_Relative zero;
129 * Return absolute time of 0ms.
131 struct GNUNET_TIME_Absolute
132 GNUNET_TIME_absolute_get_zero_ ()
134 static struct GNUNET_TIME_Absolute zero;
141 * Return relative time of 1us.
143 struct GNUNET_TIME_Relative
144 GNUNET_TIME_relative_get_unit_ ()
146 static struct GNUNET_TIME_Relative one = { 1 };
153 * Return relative time of 1ms.
155 struct GNUNET_TIME_Relative
156 GNUNET_TIME_relative_get_millisecond_ ()
158 static struct GNUNET_TIME_Relative one = { 1000 };
165 * Return relative time of 1s.
167 struct GNUNET_TIME_Relative
168 GNUNET_TIME_relative_get_second_ ()
170 static struct GNUNET_TIME_Relative one = { 1000 * 1000LL };
177 * Return relative time of 1 minute.
179 struct GNUNET_TIME_Relative
180 GNUNET_TIME_relative_get_minute_ ()
182 static struct GNUNET_TIME_Relative one = { 60 * 1000 * 1000LL };
189 * Return relative time of 1 hour.
191 struct GNUNET_TIME_Relative
192 GNUNET_TIME_relative_get_hour_ ()
194 static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 * 1000LL };
203 struct GNUNET_TIME_Relative
204 GNUNET_TIME_relative_get_forever_ ()
206 static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
215 struct GNUNET_TIME_Absolute
216 GNUNET_TIME_absolute_get_forever_ ()
218 static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
224 * Convert relative time to an absolute time in the
227 * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
229 struct GNUNET_TIME_Absolute
230 GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
232 struct GNUNET_TIME_Absolute ret;
234 if (rel.rel_value_us == UINT64_MAX)
235 return GNUNET_TIME_UNIT_FOREVER_ABS;
236 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
238 if (rel.rel_value_us + now.abs_value_us < rel.rel_value_us)
240 GNUNET_break (0); /* overflow... */
241 return GNUNET_TIME_UNIT_FOREVER_ABS;
243 ret.abs_value_us = rel.rel_value_us + now.abs_value_us;
249 * Return the minimum of two relative time values.
251 * @param t1 first timestamp
252 * @param t2 other timestamp
253 * @return timestamp that is smaller
255 struct GNUNET_TIME_Relative
256 GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
257 struct GNUNET_TIME_Relative t2)
259 return (t1.rel_value_us < t2.rel_value_us) ? t1 : t2;
264 * Return the maximum of two relative time values.
266 * @param t1 first timestamp
267 * @param t2 other timestamp
268 * @return timestamp that is larger
270 struct GNUNET_TIME_Relative
271 GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
272 struct GNUNET_TIME_Relative t2)
274 return (t1.rel_value_us > t2.rel_value_us) ? t1 : t2;
280 * Return the minimum of two relative time values.
282 * @param t1 first timestamp
283 * @param t2 other timestamp
284 * @return timestamp that is smaller
286 struct GNUNET_TIME_Absolute
287 GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
288 struct GNUNET_TIME_Absolute t2)
290 return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
295 * Return the maximum of two relative time values.
297 * @param t1 first timestamp
298 * @param t2 other timestamp
299 * @return timestamp that is bigger
301 struct GNUNET_TIME_Absolute
302 GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
303 struct GNUNET_TIME_Absolute t2)
305 return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
310 * Given a timestamp in the future, how much time
311 * remains until then?
313 * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
315 struct GNUNET_TIME_Relative
316 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
318 struct GNUNET_TIME_Relative ret;
320 if (future.abs_value_us == UINT64_MAX)
321 return GNUNET_TIME_UNIT_FOREVER_REL;
322 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
324 if (now.abs_value_us > future.abs_value_us)
325 return GNUNET_TIME_UNIT_ZERO;
326 ret.rel_value_us = future.abs_value_us - now.abs_value_us;
331 * Compute the time difference between the given start and end times.
332 * Use this function instead of actual subtraction to ensure that
333 * "FOREVER" and overflows are handled correctly.
335 * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
337 struct GNUNET_TIME_Relative
338 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
339 struct GNUNET_TIME_Absolute end)
341 struct GNUNET_TIME_Relative ret;
343 if (end.abs_value_us == UINT64_MAX)
344 return GNUNET_TIME_UNIT_FOREVER_REL;
345 if (end.abs_value_us < start.abs_value_us)
346 return GNUNET_TIME_UNIT_ZERO;
347 ret.rel_value_us = end.abs_value_us - start.abs_value_us;
352 * Get the duration of an operation as the
353 * difference of the current time and the given start time "whence".
355 * @return 0 if whence > now, otherwise now-whence.
357 struct GNUNET_TIME_Relative
358 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
360 struct GNUNET_TIME_Absolute now;
361 struct GNUNET_TIME_Relative ret;
363 now = GNUNET_TIME_absolute_get ();
364 if (whence.abs_value_us > now.abs_value_us)
365 return GNUNET_TIME_UNIT_ZERO;
366 ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
372 * Add a given relative duration to the
375 * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
377 struct GNUNET_TIME_Absolute
378 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
379 struct GNUNET_TIME_Relative duration)
381 struct GNUNET_TIME_Absolute ret;
383 if ((start.abs_value_us == UINT64_MAX) || (duration.rel_value_us == UINT64_MAX))
384 return GNUNET_TIME_UNIT_FOREVER_ABS;
385 if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
388 return GNUNET_TIME_UNIT_FOREVER_ABS;
390 ret.abs_value_us = start.abs_value_us + duration.rel_value_us;
396 * Subtract a given relative duration from the
399 * @param start some absolute time
400 * @param duration some relative time to subtract
401 * @return ZERO if start <= duration, or FOREVER if start time is FOREVER; start-duration otherwise
403 struct GNUNET_TIME_Absolute
404 GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
405 struct GNUNET_TIME_Relative duration)
407 struct GNUNET_TIME_Absolute ret;
409 if (start.abs_value_us <= duration.rel_value_us)
410 return GNUNET_TIME_UNIT_ZERO_ABS;
411 if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
412 return GNUNET_TIME_UNIT_FOREVER_ABS;
413 ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
419 * Multiply relative time by a given factor.
421 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
423 struct GNUNET_TIME_Relative
424 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
425 unsigned long long factor)
427 struct GNUNET_TIME_Relative ret;
430 return GNUNET_TIME_UNIT_ZERO;
431 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
432 return GNUNET_TIME_UNIT_FOREVER_REL;
433 ret.rel_value_us = rel.rel_value_us * factor;
434 if (ret.rel_value_us / factor != rel.rel_value_us)
437 return GNUNET_TIME_UNIT_FOREVER_REL;
444 * Saturating multiply relative time by a given factor.
446 * @param rel some duration
447 * @param factor integer to multiply with
448 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
450 struct GNUNET_TIME_Relative
451 GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
452 unsigned long long factor)
454 struct GNUNET_TIME_Relative ret;
457 return GNUNET_TIME_UNIT_ZERO;
458 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
459 return GNUNET_TIME_UNIT_FOREVER_REL;
460 ret.rel_value_us = rel.rel_value_us * factor;
461 if (ret.rel_value_us / factor != rel.rel_value_us)
463 return GNUNET_TIME_UNIT_FOREVER_REL;
470 * Divide relative time by a given factor.
472 * @param rel some duration
473 * @param factor integer to divide by
474 * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
476 struct GNUNET_TIME_Relative
477 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
478 unsigned long long factor)
480 struct GNUNET_TIME_Relative ret;
483 (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
484 return GNUNET_TIME_UNIT_FOREVER_REL;
485 ret.rel_value_us = rel.rel_value_us / factor;
491 * Calculate the estimate time of arrival/completion
494 * @param start when did the operation start?
495 * @param finished how much has been done?
496 * @param total how much must be done overall (same unit as for "finished")
497 * @return remaining duration for the operation,
498 * assuming it continues at the same speed
500 struct GNUNET_TIME_Relative
501 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
504 struct GNUNET_TIME_Relative dur;
506 struct GNUNET_TIME_Relative ret;
508 GNUNET_break (finished <= total);
509 if (finished >= total)
510 return GNUNET_TIME_UNIT_ZERO;
512 return GNUNET_TIME_UNIT_FOREVER_REL;
513 dur = GNUNET_TIME_absolute_get_duration (start);
514 exp = ((double) dur.rel_value_us) * ((double) total) / ((double) finished);
515 ret.rel_value_us = ((uint64_t) exp) - dur.rel_value_us;
521 * Add relative times together.
523 * @param a1 first timestamp
524 * @param a2 second timestamp
525 * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
527 struct GNUNET_TIME_Relative
528 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
529 struct GNUNET_TIME_Relative a2)
531 struct GNUNET_TIME_Relative ret;
533 if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
534 return GNUNET_TIME_UNIT_FOREVER_REL;
535 if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
538 return GNUNET_TIME_UNIT_FOREVER_REL;
540 ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
546 * Subtract relative timestamp from the other.
548 * @param a1 first timestamp
549 * @param a2 second timestamp
550 * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise
552 struct GNUNET_TIME_Relative
553 GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
554 struct GNUNET_TIME_Relative a2)
556 struct GNUNET_TIME_Relative ret;
558 if (a2.rel_value_us >= a1.rel_value_us)
559 return GNUNET_TIME_UNIT_ZERO;
560 if (a1.rel_value_us == UINT64_MAX)
561 return GNUNET_TIME_UNIT_FOREVER_REL;
562 ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
568 * Convert relative time to network byte order.
570 * @param a time to convert
571 * @return time in network byte order
573 struct GNUNET_TIME_RelativeNBO
574 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
576 struct GNUNET_TIME_RelativeNBO ret;
578 ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
584 * Convert relative time from network byte order.
586 * @param a time to convert
587 * @return time in host byte order
589 struct GNUNET_TIME_Relative
590 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
592 struct GNUNET_TIME_Relative ret;
594 ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
600 * Convert absolute time to network byte order.
602 * @param a time to convert
603 * @return time in network byte order
605 struct GNUNET_TIME_AbsoluteNBO
606 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
608 struct GNUNET_TIME_AbsoluteNBO ret;
610 ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
616 * Convert absolute time from network byte order.
618 * @param a time to convert
619 * @return time in host byte order
621 struct GNUNET_TIME_Absolute
622 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
624 struct GNUNET_TIME_Absolute ret;
626 ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
633 * Return the current year (i.e. '2011').
636 GNUNET_TIME_get_current_year ()
645 return t->tm_year + 1900;
650 * Convert an expiration time to the respective year (rounds)
652 * @param at absolute time
653 * @return year a year (after 1970), 0 on error
656 GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
661 tp = at.abs_value_us / 1000LL / 1000LL; /* microseconds to seconds */
665 return t->tm_year + 1900;
671 * Convert a year to an expiration time of January 1st of that year.
673 * @param year a year (after 1970, please ;-)).
674 * @return absolute time for January 1st of that year.
676 struct GNUNET_TIME_Absolute
677 GNUNET_TIME_year_to_time (unsigned int year)
679 struct GNUNET_TIME_Absolute ret;
683 memset (&t, 0, sizeof (t));
687 return GNUNET_TIME_absolute_get (); /* now */
689 t.tm_year = year - 1900;
695 GNUNET_break (tp != (time_t) - 1);
696 ret.abs_value_us = tp * 1000LL * 1000LL; /* seconds to microseconds */