Returns now GNUNET_SYSERR
[oweals/gnunet.git] / src / util / time.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2006, 2009 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 2, 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_time_lib.h"
28
29
30 /**
31  * Get the current time (works just as "time", just that we use the
32  * unit of time that the cron-jobs use (and is 64 bit)).
33  *
34  * @return the current time
35  */
36 struct GNUNET_TIME_Absolute
37 GNUNET_TIME_absolute_get ()
38 {
39   struct GNUNET_TIME_Absolute ret;
40   struct timeval tv;
41
42   GETTIMEOFDAY (&tv, NULL);
43   ret.abs_value =
44     (uint64_t) (((uint64_t) tv.tv_sec * 1000LL) +
45                 ((uint64_t) tv.tv_usec / 1000LL));
46   return ret;
47 }
48
49
50 /**
51  * Return relative time of 0ms.
52  */
53 struct GNUNET_TIME_Relative
54 GNUNET_TIME_relative_get_zero ()
55 {
56   static struct GNUNET_TIME_Relative zero;
57   return zero;
58 }
59
60
61 /**
62  * Return absolute time of 0ms.
63  */
64 struct GNUNET_TIME_Absolute
65 GNUNET_TIME_absolute_get_zero ()
66 {
67   static struct GNUNET_TIME_Absolute zero;
68   return zero;
69 }
70
71 /**
72  * Return relative time of 1ms.
73  */
74 struct GNUNET_TIME_Relative
75 GNUNET_TIME_relative_get_unit ()
76 {
77   static struct GNUNET_TIME_Relative one = { 1 };
78   return one;
79 }
80
81 /**
82  * Return "forever".
83  */
84 struct GNUNET_TIME_Relative
85 GNUNET_TIME_relative_get_forever ()
86 {
87   static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
88   return forever;
89 }
90
91 /**
92  * Return "forever".
93  */
94 struct GNUNET_TIME_Absolute
95 GNUNET_TIME_absolute_get_forever ()
96 {
97   static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
98   return forever;
99 }
100
101 /**
102  * Convert relative time to an absolute time in the
103  * future.
104  *
105  * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
106  */
107 struct GNUNET_TIME_Absolute
108 GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
109 {
110   struct GNUNET_TIME_Absolute ret;
111   if (rel.rel_value == UINT64_MAX)
112     return GNUNET_TIME_absolute_get_forever ();
113   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
114   if (rel.rel_value + now.abs_value < rel.rel_value)
115     {
116       GNUNET_break (0);         /* overflow... */
117       return GNUNET_TIME_absolute_get_forever ();
118     }
119   ret.abs_value = rel.rel_value + now.abs_value;
120   return ret;
121 }
122
123
124 /**
125  * Return the minimum of two relative time values.
126  *
127  * @param t1 first timestamp
128  * @param t2 other timestamp
129  * @return timestamp that is smaller
130  */
131 struct GNUNET_TIME_Relative
132 GNUNET_TIME_relative_min (struct
133                           GNUNET_TIME_Relative
134                           t1, struct GNUNET_TIME_Relative t2)
135 {
136   return (t1.rel_value < t2.rel_value) ? t1 : t2;
137 }
138
139
140 /**
141  * Return the maximum of two relative time values.
142  *
143  * @param t1 first timestamp
144  * @param t2 other timestamp
145  * @return timestamp that is larger
146  */
147 struct GNUNET_TIME_Relative
148 GNUNET_TIME_relative_max (struct
149                           GNUNET_TIME_Relative
150                           t1, struct GNUNET_TIME_Relative t2)
151 {
152   return (t1.rel_value > t2.rel_value) ? t1 : t2;
153 }
154
155
156
157 /**
158  * Return the minimum of two relative time values.
159  *
160  * @param t1 first timestamp
161  * @param t2 other timestamp
162  * @return timestamp that is smaller
163  */
164 struct GNUNET_TIME_Absolute
165 GNUNET_TIME_absolute_min (struct
166                           GNUNET_TIME_Absolute
167                           t1, struct GNUNET_TIME_Absolute t2)
168 {
169   return (t1.abs_value < t2.abs_value) ? t1 : t2;
170 }
171
172
173 /**
174  * Return the maximum of two relative time values.
175  *
176  * @param t1 first timestamp
177  * @param t2 other timestamp
178  * @return timestamp that is smaller
179  */
180 struct GNUNET_TIME_Absolute
181 GNUNET_TIME_absolute_max (struct
182                           GNUNET_TIME_Absolute
183                           t1, struct GNUNET_TIME_Absolute t2)
184 {
185   return (t1.abs_value > t2.abs_value) ? t1 : t2;
186 }
187
188
189 /**
190  * Given a timestamp in the future, how much time
191  * remains until then?
192  *
193  * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
194  */
195 struct GNUNET_TIME_Relative
196 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
197 {
198   struct GNUNET_TIME_Relative ret;
199   if (future.abs_value == UINT64_MAX)
200     return GNUNET_TIME_relative_get_forever ();
201   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
202   if (now.abs_value > future.abs_value)
203     return GNUNET_TIME_relative_get_zero ();
204   ret.rel_value = future.abs_value - now.abs_value;
205   return ret;
206 }
207
208 /**
209  * Compute the time difference between the given start and end times.
210  * Use this function instead of actual subtraction to ensure that
211  * "FOREVER" and overflows are handeled correctly.
212  *
213  * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
214  */
215 struct GNUNET_TIME_Relative
216 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
217                                      struct GNUNET_TIME_Absolute end)
218 {
219   struct GNUNET_TIME_Relative ret;
220   if (end.abs_value == UINT64_MAX)
221     return GNUNET_TIME_relative_get_forever ();
222   if (end.abs_value < start.abs_value)
223     return GNUNET_TIME_relative_get_zero ();
224   ret.rel_value = end.abs_value - start.abs_value;
225   return ret;
226 }
227
228 /**
229  * Get the duration of an operation as the
230  * difference of the current time and the given start time "hence".
231  *
232  * @return aborts if hence==FOREVER, 0 if hence > now, otherwise now-hence.
233  */
234 struct GNUNET_TIME_Relative
235 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute hence)
236 {
237   struct GNUNET_TIME_Absolute now;
238   struct GNUNET_TIME_Relative ret;
239
240   now = GNUNET_TIME_absolute_get ();
241   GNUNET_assert (hence.abs_value != UINT64_MAX);
242   if (hence.abs_value > now.abs_value)
243     return GNUNET_TIME_relative_get_zero ();
244   ret.rel_value = now.abs_value - hence.abs_value;
245   return ret;
246 }
247
248
249 /**
250  * Add a given relative duration to the
251  * given start time.
252  *
253  * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
254  */
255 struct GNUNET_TIME_Absolute
256 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
257                           struct GNUNET_TIME_Relative duration)
258 {
259   struct GNUNET_TIME_Absolute ret;
260
261   if ((start.abs_value == UINT64_MAX) ||
262       (duration.rel_value == UINT64_MAX))
263     return GNUNET_TIME_absolute_get_forever ();
264   if (start.abs_value + duration.rel_value < start.abs_value)
265     {
266       GNUNET_break (0);
267       return GNUNET_TIME_absolute_get_forever ();
268     }
269   ret.abs_value = start.abs_value + duration.rel_value;
270   return ret;
271 }
272
273
274 /**
275  * Subtract a given relative duration from the
276  * given start time.
277  *
278  * @param start some absolute time
279  * @param duration some relative time to subtract
280  * @return ZERO if start <= duration, or FOREVER if start time is FOREVER; start-duration otherwise
281  */
282 struct GNUNET_TIME_Absolute 
283 GNUNET_TIME_absolute_subtract (struct
284                                GNUNET_TIME_Absolute
285                                start,
286                                struct
287                                GNUNET_TIME_Relative
288                                duration)
289 {
290   struct GNUNET_TIME_Absolute ret;
291   if (start.abs_value <= duration.rel_value)
292     return GNUNET_TIME_UNIT_ZERO_ABS;
293   if (start.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
294     return GNUNET_TIME_UNIT_FOREVER_ABS;
295   ret.abs_value = start.abs_value - duration.rel_value;
296   return ret;
297 }
298
299
300 /**
301  * Multiply relative time by a given factor.
302  *
303  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
304  */
305 struct GNUNET_TIME_Relative
306 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
307                                unsigned int factor)
308 {
309   struct GNUNET_TIME_Relative ret;
310   if (factor == 0)
311     return GNUNET_TIME_relative_get_zero ();
312   ret.rel_value = rel.rel_value * (unsigned long long) factor;
313   if (ret.rel_value / factor != rel.rel_value)
314     {
315       GNUNET_break (0);
316       return GNUNET_TIME_relative_get_forever ();
317     }
318   return ret;
319 }
320
321
322 /**
323  * Divide relative time by a given factor.
324  *
325  * @param rel some duration
326  * @param factor integer to divide by
327  * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
328  */
329 struct GNUNET_TIME_Relative
330 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
331                              unsigned int factor)
332 {
333   struct GNUNET_TIME_Relative ret;
334   if ( (factor == 0) ||
335        (rel.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value) )
336     return GNUNET_TIME_UNIT_FOREVER_REL;
337   ret.rel_value = rel.rel_value / (unsigned long long) factor;
338   return ret;
339 }
340
341
342 /**
343  * Calculate the estimate time of arrival/completion 
344  * for an operation.
345  *
346  * @param start when did the operation start?
347  * @param finished how much has been done?
348  * @param total how much must be done overall (same unit as for "finished")
349  * @return remaining duration for the operation,
350  *        assuming it continues at the same speed
351  */
352 struct GNUNET_TIME_Relative
353 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
354                            uint64_t finished, uint64_t total)
355 {
356   struct GNUNET_TIME_Relative dur;
357   double exp;
358   struct GNUNET_TIME_Relative ret;
359
360   GNUNET_break (finished <= total);
361   if (finished >= total)
362     return GNUNET_TIME_UNIT_ZERO;
363   if (finished == 0)
364     return GNUNET_TIME_UNIT_FOREVER_REL;
365   dur = GNUNET_TIME_absolute_get_duration (start);
366   exp = ((double) dur.rel_value) * ((double) total) / ((double) finished);
367   ret.rel_value = ((uint64_t) exp) - dur.rel_value;
368   return ret;
369 }
370
371
372 /**
373  * Add relative times together.
374  *
375  * @param a1 first timestamp
376  * @param a2 second timestamp
377  * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
378  */
379 struct GNUNET_TIME_Relative
380 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
381                           struct GNUNET_TIME_Relative a2)
382 {
383   struct GNUNET_TIME_Relative ret;
384
385   if ((a1.rel_value == UINT64_MAX) || (a2.rel_value == UINT64_MAX))
386     return GNUNET_TIME_relative_get_forever ();
387   if (a1.rel_value + a2.rel_value < a1.rel_value)
388     {
389       GNUNET_break (0);
390       return GNUNET_TIME_relative_get_forever ();
391     }
392   ret.rel_value = a1.rel_value + a2.rel_value;
393   return ret;
394 }
395
396
397 /**
398  * Subtract relative timestamp from the other.
399  *
400  * @param a1 first timestamp
401  * @param a2 second timestamp
402  * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise
403  */
404 struct GNUNET_TIME_Relative
405 GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
406                                struct GNUNET_TIME_Relative a2)
407 {
408   struct GNUNET_TIME_Relative ret;
409
410   if (a2.rel_value >= a1.rel_value)
411     return GNUNET_TIME_relative_get_zero ();
412   if (a1.rel_value == UINT64_MAX) 
413     return GNUNET_TIME_relative_get_forever ();
414   ret.rel_value = a1.rel_value - a2.rel_value;
415   return ret;
416 }
417
418
419 /**
420  * Convert relative time to network byte order.
421  *
422  * @param a time to convert
423  * @return time in network byte order
424  */
425 struct GNUNET_TIME_RelativeNBO
426 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
427 {
428   struct GNUNET_TIME_RelativeNBO ret;
429   ret.rel_value__ = GNUNET_htonll (a.rel_value);
430   return ret;
431 }
432
433 /**
434  * Convert relative time from network byte order.
435  *
436  * @param a time to convert
437  * @return time in host byte order
438  */
439 struct GNUNET_TIME_Relative
440 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
441 {
442   struct GNUNET_TIME_Relative ret;
443   ret.rel_value = GNUNET_ntohll (a.rel_value__);
444   return ret;
445
446 }
447
448 /**
449  * Convert absolute time to network byte order.
450  *
451  * @param a time to convert
452  * @return time in network byte order
453  */
454 struct GNUNET_TIME_AbsoluteNBO
455 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
456 {
457   struct GNUNET_TIME_AbsoluteNBO ret;
458   ret.abs_value__ = GNUNET_htonll (a.abs_value);
459   return ret;
460 }
461
462 /**
463  * Convert absolute time from network byte order.
464  *
465  * @param a time to convert
466  * @return time in host byte order
467  */
468 struct GNUNET_TIME_Absolute
469 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
470 {
471   struct GNUNET_TIME_Absolute ret;
472   ret.abs_value = GNUNET_ntohll (a.abs_value__);
473   return ret;
474
475 }
476
477
478
479 /* end of time.c */