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