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