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