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