ee90eb8ae552ff9dd677e5100cf4ec776a5466ec
[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  * Saturating multiply relative time by a given factor.
448  *
449  * @param rel some duration
450  * @param factor integer to multiply with
451  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
452  */
453 struct GNUNET_TIME_Relative
454 GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
455                                           unsigned long long factor)
456 {
457   struct GNUNET_TIME_Relative ret;
458
459   if (0 == factor)
460     return GNUNET_TIME_UNIT_ZERO;
461   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
462     return GNUNET_TIME_UNIT_FOREVER_REL;
463   ret.rel_value_us = rel.rel_value_us * factor;
464   if (ret.rel_value_us / factor != rel.rel_value_us)
465   {
466     return GNUNET_TIME_UNIT_FOREVER_REL;
467   }
468   return ret;
469 }
470
471
472 /**
473  * Divide relative time by a given factor.
474  *
475  * @param rel some duration
476  * @param factor integer to divide by
477  * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
478  */
479 struct GNUNET_TIME_Relative
480 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
481                              unsigned long long factor)
482 {
483   struct GNUNET_TIME_Relative ret;
484
485   if ((0 == factor) ||
486       (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
487     return GNUNET_TIME_UNIT_FOREVER_REL;
488   ret.rel_value_us = rel.rel_value_us / factor;
489   return ret;
490 }
491
492
493 /**
494  * Calculate the estimate time of arrival/completion
495  * for an operation.
496  *
497  * @param start when did the operation start?
498  * @param finished how much has been done?
499  * @param total how much must be done overall (same unit as for "finished")
500  * @return remaining duration for the operation,
501  *        assuming it continues at the same speed
502  */
503 struct GNUNET_TIME_Relative
504 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
505                            uint64_t total)
506 {
507   struct GNUNET_TIME_Relative dur;
508   double exp;
509   struct GNUNET_TIME_Relative ret;
510
511   GNUNET_break (finished <= total);
512   if (finished >= total)
513     return GNUNET_TIME_UNIT_ZERO;
514   if (0 == finished)
515     return GNUNET_TIME_UNIT_FOREVER_REL;
516   dur = GNUNET_TIME_absolute_get_duration (start);
517   exp = ((double) dur.rel_value_us) * ((double) total) / ((double) finished);
518   ret.rel_value_us = ((uint64_t) exp) - dur.rel_value_us;
519   return ret;
520 }
521
522
523 /**
524  * Add relative times together.
525  *
526  * @param a1 first timestamp
527  * @param a2 second timestamp
528  * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
529  */
530 struct GNUNET_TIME_Relative
531 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
532                           struct GNUNET_TIME_Relative a2)
533 {
534   struct GNUNET_TIME_Relative ret;
535
536   if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
537     return GNUNET_TIME_UNIT_FOREVER_REL;
538   if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
539   {
540     GNUNET_break (0);
541     return GNUNET_TIME_UNIT_FOREVER_REL;
542   }
543   ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
544   return ret;
545 }
546
547
548 /**
549  * Subtract relative timestamp from the other.
550  *
551  * @param a1 first timestamp
552  * @param a2 second timestamp
553  * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise
554  */
555 struct GNUNET_TIME_Relative
556 GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
557                                struct GNUNET_TIME_Relative a2)
558 {
559   struct GNUNET_TIME_Relative ret;
560
561   if (a2.rel_value_us >= a1.rel_value_us)
562     return GNUNET_TIME_UNIT_ZERO;
563   if (a1.rel_value_us == UINT64_MAX)
564     return GNUNET_TIME_UNIT_FOREVER_REL;
565   ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
566   return ret;
567 }
568
569
570 /**
571  * Convert relative time to network byte order.
572  *
573  * @param a time to convert
574  * @return time in network byte order
575  */
576 struct GNUNET_TIME_RelativeNBO
577 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
578 {
579   struct GNUNET_TIME_RelativeNBO ret;
580
581   ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
582   return ret;
583 }
584
585
586 /**
587  * Convert relative time from network byte order.
588  *
589  * @param a time to convert
590  * @return time in host byte order
591  */
592 struct GNUNET_TIME_Relative
593 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
594 {
595   struct GNUNET_TIME_Relative ret;
596
597   ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
598   return ret;
599 }
600
601
602 /**
603  * Convert absolute time to network byte order.
604  *
605  * @param a time to convert
606  * @return time in network byte order
607  */
608 struct GNUNET_TIME_AbsoluteNBO
609 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
610 {
611   struct GNUNET_TIME_AbsoluteNBO ret;
612
613   ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
614   return ret;
615 }
616
617
618 /**
619  * Convert absolute time from network byte order.
620  *
621  * @param a time to convert
622  * @return time in host byte order
623  */
624 struct GNUNET_TIME_Absolute
625 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
626 {
627   struct GNUNET_TIME_Absolute ret;
628
629   ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
630   return ret;
631
632 }
633
634
635 /**
636  * Return the current year (i.e. '2011').
637  */
638 unsigned int
639 GNUNET_TIME_get_current_year ()
640 {
641   time_t tp;
642   struct tm *t;
643
644   tp = time (NULL);
645   t = gmtime (&tp);
646   if (t == NULL)
647     return 0;
648   return t->tm_year + 1900;
649 }
650
651
652 /**
653  * Convert an expiration time to the respective year (rounds)
654  *
655  * @param at absolute time
656  * @return year a year (after 1970), 0 on error
657  */
658 unsigned int
659 GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
660 {
661   struct tm *t;
662   time_t tp;
663
664   tp = at.abs_value_us / 1000LL / 1000LL;    /* microseconds to seconds */
665   t = gmtime (&tp);
666   if (t == NULL)
667     return 0;
668   return t->tm_year + 1900;
669
670 }
671
672
673 /**
674  * Convert a year to an expiration time of January 1st of that year.
675  *
676  * @param year a year (after 1970, please ;-)).
677  * @return absolute time for January 1st of that year.
678  */
679 struct GNUNET_TIME_Absolute
680 GNUNET_TIME_year_to_time (unsigned int year)
681 {
682   struct GNUNET_TIME_Absolute ret;
683   time_t tp;
684   struct tm t;
685
686   memset (&t, 0, sizeof (t));
687   if (year < 1900)
688   {
689     GNUNET_break (0);
690     return GNUNET_TIME_absolute_get (); /* now */
691   }
692   t.tm_year = year - 1900;
693   t.tm_mday = 1;
694   t.tm_mon = 0;
695   t.tm_wday = 1;
696   t.tm_yday = 1;
697   tp = mktime (&t);
698   GNUNET_break (tp != (time_t) - 1);
699   ret.abs_value_us = tp * 1000LL * 1000LL;  /* seconds to microseconds */
700   return ret;
701 }
702
703
704
705 /* end of time.c */