-rps: logging
[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", __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   return one;
153 }
154
155
156 /**
157  * Return relative time of 1ms.
158  */
159 struct GNUNET_TIME_Relative
160 GNUNET_TIME_relative_get_millisecond_ ()
161 {
162   static struct GNUNET_TIME_Relative one = { 1000 };
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   return one;
175 }
176
177
178 /**
179  * Return relative time of 1 minute.
180  */
181 struct GNUNET_TIME_Relative
182 GNUNET_TIME_relative_get_minute_ ()
183 {
184   static struct GNUNET_TIME_Relative one = { 60 * 1000 * 1000LL };
185   return one;
186 }
187
188
189 /**
190  * Return relative time of 1 hour.
191  */
192 struct GNUNET_TIME_Relative
193 GNUNET_TIME_relative_get_hour_ ()
194 {
195   static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 * 1000LL };
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   return forever;
208 }
209
210 /**
211  * Return "forever".
212  */
213 struct GNUNET_TIME_Absolute
214 GNUNET_TIME_absolute_get_forever_ ()
215 {
216   static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
217   return forever;
218 }
219
220 /**
221  * Convert relative time to an absolute time in the
222  * future.
223  *
224  * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
225  */
226 struct GNUNET_TIME_Absolute
227 GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
228 {
229   struct GNUNET_TIME_Absolute ret;
230
231   if (rel.rel_value_us == UINT64_MAX)
232     return GNUNET_TIME_UNIT_FOREVER_ABS;
233   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
234
235   if (rel.rel_value_us + now.abs_value_us < rel.rel_value_us)
236   {
237     GNUNET_break (0);           /* overflow... */
238     return GNUNET_TIME_UNIT_FOREVER_ABS;
239   }
240   ret.abs_value_us = rel.rel_value_us + now.abs_value_us;
241   return ret;
242 }
243
244
245 /**
246  * Return the minimum of two relative time values.
247  *
248  * @param t1 first timestamp
249  * @param t2 other timestamp
250  * @return timestamp that is smaller
251  */
252 struct GNUNET_TIME_Relative
253 GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
254                           struct GNUNET_TIME_Relative t2)
255 {
256   return (t1.rel_value_us < t2.rel_value_us) ? t1 : t2;
257 }
258
259
260 /**
261  * Return the maximum of two relative time values.
262  *
263  * @param t1 first timestamp
264  * @param t2 other timestamp
265  * @return timestamp that is larger
266  */
267 struct GNUNET_TIME_Relative
268 GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
269                           struct GNUNET_TIME_Relative t2)
270 {
271   return (t1.rel_value_us > t2.rel_value_us) ? t1 : t2;
272 }
273
274
275
276 /**
277  * Return the minimum of two relative time values.
278  *
279  * @param t1 first timestamp
280  * @param t2 other timestamp
281  * @return timestamp that is smaller
282  */
283 struct GNUNET_TIME_Absolute
284 GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
285                           struct GNUNET_TIME_Absolute t2)
286 {
287   return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
288 }
289
290
291 /**
292  * Return the maximum of two relative time values.
293  *
294  * @param t1 first timestamp
295  * @param t2 other timestamp
296  * @return timestamp that is bigger
297  */
298 struct GNUNET_TIME_Absolute
299 GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
300                           struct GNUNET_TIME_Absolute t2)
301 {
302   return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
303 }
304
305
306 /**
307  * Given a timestamp in the future, how much time
308  * remains until then?
309  *
310  * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
311  */
312 struct GNUNET_TIME_Relative
313 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
314 {
315   struct GNUNET_TIME_Relative ret;
316
317   if (future.abs_value_us == UINT64_MAX)
318     return GNUNET_TIME_UNIT_FOREVER_REL;
319   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
320
321   if (now.abs_value_us > future.abs_value_us)
322     return GNUNET_TIME_UNIT_ZERO;
323   ret.rel_value_us = future.abs_value_us - now.abs_value_us;
324   return ret;
325 }
326
327 /**
328  * Compute the time difference between the given start and end times.
329  * Use this function instead of actual subtraction to ensure that
330  * "FOREVER" and overflows are handled correctly.
331  *
332  * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
333  */
334 struct GNUNET_TIME_Relative
335 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
336                                      struct GNUNET_TIME_Absolute end)
337 {
338   struct GNUNET_TIME_Relative ret;
339
340   if (end.abs_value_us == UINT64_MAX)
341     return GNUNET_TIME_UNIT_FOREVER_REL;
342   if (end.abs_value_us < start.abs_value_us)
343     return GNUNET_TIME_UNIT_ZERO;
344   ret.rel_value_us = end.abs_value_us - start.abs_value_us;
345   return ret;
346 }
347
348 /**
349  * Get the duration of an operation as the
350  * difference of the current time and the given start time "whence".
351  *
352  * @return 0 if whence > now, otherwise now-whence.
353  */
354 struct GNUNET_TIME_Relative
355 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
356 {
357   struct GNUNET_TIME_Absolute now;
358   struct GNUNET_TIME_Relative ret;
359
360   now = GNUNET_TIME_absolute_get ();
361   if (whence.abs_value_us > now.abs_value_us)
362     return GNUNET_TIME_UNIT_ZERO;
363   ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
364   return ret;
365 }
366
367
368 /**
369  * Add a given relative duration to the
370  * given start time.
371  *
372  * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
373  */
374 struct GNUNET_TIME_Absolute
375 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
376                           struct GNUNET_TIME_Relative duration)
377 {
378   struct GNUNET_TIME_Absolute ret;
379
380   if ((start.abs_value_us == UINT64_MAX) || (duration.rel_value_us == UINT64_MAX))
381     return GNUNET_TIME_UNIT_FOREVER_ABS;
382   if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
383   {
384     GNUNET_break (0);
385     return GNUNET_TIME_UNIT_FOREVER_ABS;
386   }
387   ret.abs_value_us = start.abs_value_us + duration.rel_value_us;
388   return ret;
389 }
390
391
392 /**
393  * Subtract a given relative duration from the
394  * given start time.
395  *
396  * @param start some absolute time
397  * @param duration some relative time to subtract
398  * @return ZERO if start <= duration, or FOREVER if start time is FOREVER; start-duration otherwise
399  */
400 struct GNUNET_TIME_Absolute
401 GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
402                                struct GNUNET_TIME_Relative duration)
403 {
404   struct GNUNET_TIME_Absolute ret;
405
406   if (start.abs_value_us <= duration.rel_value_us)
407     return GNUNET_TIME_UNIT_ZERO_ABS;
408   if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
409     return GNUNET_TIME_UNIT_FOREVER_ABS;
410   ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
411   return ret;
412 }
413
414
415 /**
416  * Multiply relative time by a given factor.
417  *
418  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
419  */
420 struct GNUNET_TIME_Relative
421 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
422                                unsigned int factor)
423 {
424   struct GNUNET_TIME_Relative ret;
425
426   if (0 == factor)
427     return GNUNET_TIME_UNIT_ZERO;
428   if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
429     return GNUNET_TIME_UNIT_FOREVER_REL;
430   ret.rel_value_us = rel.rel_value_us * (unsigned long long) factor;
431   if (ret.rel_value_us / factor != rel.rel_value_us)
432   {
433     GNUNET_break (0);
434     return GNUNET_TIME_UNIT_FOREVER_REL;
435   }
436   return ret;
437 }
438
439
440 /**
441  * Divide relative time by a given factor.
442  *
443  * @param rel some duration
444  * @param factor integer to divide by
445  * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
446  */
447 struct GNUNET_TIME_Relative
448 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
449                              unsigned int factor)
450 {
451   struct GNUNET_TIME_Relative ret;
452
453   if ((0 == factor) ||
454       (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
455     return GNUNET_TIME_UNIT_FOREVER_REL;
456   ret.rel_value_us = rel.rel_value_us / (unsigned long long) factor;
457   return ret;
458 }
459
460
461 /**
462  * Calculate the estimate time of arrival/completion
463  * for an operation.
464  *
465  * @param start when did the operation start?
466  * @param finished how much has been done?
467  * @param total how much must be done overall (same unit as for "finished")
468  * @return remaining duration for the operation,
469  *        assuming it continues at the same speed
470  */
471 struct GNUNET_TIME_Relative
472 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
473                            uint64_t total)
474 {
475   struct GNUNET_TIME_Relative dur;
476   double exp;
477   struct GNUNET_TIME_Relative ret;
478
479   GNUNET_break (finished <= total);
480   if (finished >= total)
481     return GNUNET_TIME_UNIT_ZERO;
482   if (0 == finished)
483     return GNUNET_TIME_UNIT_FOREVER_REL;
484   dur = GNUNET_TIME_absolute_get_duration (start);
485   exp = ((double) dur.rel_value_us) * ((double) total) / ((double) finished);
486   ret.rel_value_us = ((uint64_t) exp) - dur.rel_value_us;
487   return ret;
488 }
489
490
491 /**
492  * Add relative times together.
493  *
494  * @param a1 first timestamp
495  * @param a2 second timestamp
496  * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
497  */
498 struct GNUNET_TIME_Relative
499 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
500                           struct GNUNET_TIME_Relative a2)
501 {
502   struct GNUNET_TIME_Relative ret;
503
504   if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
505     return GNUNET_TIME_UNIT_FOREVER_REL;
506   if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
507   {
508     GNUNET_break (0);
509     return GNUNET_TIME_UNIT_FOREVER_REL;
510   }
511   ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
512   return ret;
513 }
514
515
516 /**
517  * Subtract relative timestamp from the other.
518  *
519  * @param a1 first timestamp
520  * @param a2 second timestamp
521  * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise
522  */
523 struct GNUNET_TIME_Relative
524 GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
525                                struct GNUNET_TIME_Relative a2)
526 {
527   struct GNUNET_TIME_Relative ret;
528
529   if (a2.rel_value_us >= a1.rel_value_us)
530     return GNUNET_TIME_UNIT_ZERO;
531   if (a1.rel_value_us == UINT64_MAX)
532     return GNUNET_TIME_UNIT_FOREVER_REL;
533   ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
534   return ret;
535 }
536
537
538 /**
539  * Convert relative time to network byte order.
540  *
541  * @param a time to convert
542  * @return time in network byte order
543  */
544 struct GNUNET_TIME_RelativeNBO
545 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
546 {
547   struct GNUNET_TIME_RelativeNBO ret;
548
549   ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
550   return ret;
551 }
552
553
554 /**
555  * Convert relative time from network byte order.
556  *
557  * @param a time to convert
558  * @return time in host byte order
559  */
560 struct GNUNET_TIME_Relative
561 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
562 {
563   struct GNUNET_TIME_Relative ret;
564
565   ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
566   return ret;
567
568 }
569
570
571 /**
572  * Convert absolute time to network byte order.
573  *
574  * @param a time to convert
575  * @return time in network byte order
576  */
577 struct GNUNET_TIME_AbsoluteNBO
578 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
579 {
580   struct GNUNET_TIME_AbsoluteNBO ret;
581
582   ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
583   return ret;
584 }
585
586
587 /**
588  * Convert absolute time from network byte order.
589  *
590  * @param a time to convert
591  * @return time in host byte order
592  */
593 struct GNUNET_TIME_Absolute
594 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
595 {
596   struct GNUNET_TIME_Absolute ret;
597
598   ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
599   return ret;
600
601 }
602
603
604 /**
605  * Return the current year (i.e. '2011').
606  */
607 unsigned int
608 GNUNET_TIME_get_current_year ()
609 {
610   time_t tp;
611   struct tm *t;
612
613   tp = time (NULL);
614   t = gmtime (&tp);
615   if (t == NULL)
616     return 0;
617   return t->tm_year + 1900;
618 }
619
620
621 /**
622  * Convert an expiration time to the respective year (rounds)
623  *
624  * @param at absolute time
625  * @return year a year (after 1970), 0 on error
626  */
627 unsigned int
628 GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
629 {
630   struct tm *t;
631   time_t tp;
632
633   tp = at.abs_value_us / 1000LL / 1000LL;    /* microseconds to seconds */
634   t = gmtime (&tp);
635   if (t == NULL)
636     return 0;
637   return t->tm_year + 1900;
638
639 }
640
641
642 /**
643  * Convert a year to an expiration time of January 1st of that year.
644  *
645  * @param year a year (after 1970, please ;-)).
646  * @return absolute time for January 1st of that year.
647  */
648 struct GNUNET_TIME_Absolute
649 GNUNET_TIME_year_to_time (unsigned int year)
650 {
651   struct GNUNET_TIME_Absolute ret;
652   time_t tp;
653   struct tm t;
654
655   memset (&t, 0, sizeof (t));
656   if (year < 1900)
657   {
658     GNUNET_break (0);
659     return GNUNET_TIME_absolute_get (); /* now */
660   }
661   t.tm_year = year - 1900;
662   t.tm_mday = 1;
663   t.tm_mon = 1;
664   t.tm_wday = 1;
665   t.tm_yday = 1;
666   tp = mktime (&t);
667   GNUNET_break (tp != (time_t) - 1);
668   ret.abs_value_us = tp * 1000LL * 1000LL;  /* seconds to microseconds */
669   return ret;
670 }
671
672
673
674 /* end of time.c */