use enum
[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.value = (uint64_t) (((uint64_t) tv.tv_sec * 1000LL) + ((uint64_t) tv.tv_usec / 1000LL));
44   return ret;
45 }
46
47
48 /**
49  * Return relative time of 0ms.
50  */
51 struct GNUNET_TIME_Relative
52 GNUNET_TIME_relative_get_zero ()
53 {
54   static struct GNUNET_TIME_Relative zero;
55   return zero;
56 }
57
58
59 /**
60  * Return absolute time of 0ms.
61  */
62 struct GNUNET_TIME_Absolute
63 GNUNET_TIME_absolute_get_zero ()
64 {
65   static struct GNUNET_TIME_Absolute zero;
66   return zero;
67 }
68
69 /**
70  * Return relative time of 1ms.
71  */
72 struct GNUNET_TIME_Relative
73 GNUNET_TIME_relative_get_unit ()
74 {
75   static struct GNUNET_TIME_Relative one = { 1 };
76   return one;
77 }
78
79 /**
80  * Return "forever".
81  */
82 struct GNUNET_TIME_Relative
83 GNUNET_TIME_relative_get_forever ()
84 {
85   static struct GNUNET_TIME_Relative forever = { (uint64_t) - 1LL };
86   return forever;
87 }
88
89 /**
90  * Return "forever".
91  */
92 struct GNUNET_TIME_Absolute
93 GNUNET_TIME_absolute_get_forever ()
94 {
95   static struct GNUNET_TIME_Absolute forever = { (uint64_t) - 1LL };
96   return forever;
97 }
98
99 /**
100  * Convert relative time to an absolute time in the
101  * future.
102  *
103  * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
104  */
105 struct GNUNET_TIME_Absolute
106 GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
107 {
108   struct GNUNET_TIME_Absolute ret;
109   if (rel.value == (uint64_t) -1LL)
110     return GNUNET_TIME_absolute_get_forever ();
111   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
112   if (rel.value + now.value < rel.value)
113     {
114       GNUNET_break (0);         /* overflow... */
115       return GNUNET_TIME_absolute_get_forever ();
116     }
117   ret.value = rel.value + now.value;
118   return ret;
119 }
120
121
122 /**
123  * Return the minimum of two relative time values.
124  *
125  * @param t1 first timestamp
126  * @param t2 other timestamp
127  * @return timestamp that is smaller
128  */
129 struct GNUNET_TIME_Relative GNUNET_TIME_relative_min (struct
130                                                       GNUNET_TIME_Relative
131                                                       t1,
132                                                       struct
133                                                       GNUNET_TIME_Relative t2)
134 {
135   return (t1.value < t2.value) ? t1 : t2;
136 }
137
138
139
140 /**
141  * Return the minimum of two relative time values.
142  *
143  * @param t1 first timestamp
144  * @param t2 other timestamp
145  * @return timestamp that is smaller
146  */
147 struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_min (struct
148                                                       GNUNET_TIME_Absolute
149                                                       t1,
150                                                       struct
151                                                       GNUNET_TIME_Absolute t2)
152 {
153   return (t1.value < t2.value) ? t1 : t2;
154 }
155
156 /**
157  * Given a timestamp in the future, how much time
158  * remains until then?
159  *
160  * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
161  */
162 struct GNUNET_TIME_Relative
163 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
164 {
165   struct GNUNET_TIME_Relative ret;
166   if (future.value == (uint64_t) - 1LL)
167     return GNUNET_TIME_relative_get_forever ();
168   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
169   if (now.value > future.value)
170     return GNUNET_TIME_relative_get_zero ();
171   ret.value = future.value - now.value;
172   return ret;
173 }
174
175 /**
176  * Compute the time difference between the given start and end times.
177  * Use this function instead of actual subtraction to ensure that
178  * "FOREVER" and overflows are handeled correctly.
179  *
180  * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
181  */
182 struct GNUNET_TIME_Relative
183 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
184                                      struct GNUNET_TIME_Absolute end)
185 {
186   struct GNUNET_TIME_Relative ret;
187   if (end.value == (uint64_t) - 1LL)
188     return GNUNET_TIME_relative_get_forever ();
189   if (end.value < start.value)
190     return GNUNET_TIME_relative_get_zero ();
191   ret.value = end.value - start.value;
192   return ret;
193 }
194
195 /**
196  * Get the duration of an operation as the
197  * difference of the current time and the given start time "hence".
198  *
199  * @return aborts if hence==FOREVER, 0 if hence > now, otherwise now-hence.
200  */
201 struct GNUNET_TIME_Relative
202 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute hence)
203 {
204   struct GNUNET_TIME_Absolute now;
205   struct GNUNET_TIME_Relative ret;
206
207   now = GNUNET_TIME_absolute_get ();
208   GNUNET_assert (hence.value != (uint64_t) - 1LL);
209   if (hence.value > now.value)
210     return GNUNET_TIME_relative_get_zero ();
211   ret.value = now.value - hence.value;
212   return ret;
213 }
214
215
216 /**
217  * Add a given relative duration to the
218  * given start time.
219  *
220  * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
221  */
222 struct GNUNET_TIME_Absolute
223 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
224                           struct GNUNET_TIME_Relative duration)
225 {
226   struct GNUNET_TIME_Absolute ret;
227
228   if ((start.value == (uint64_t) - 1LL) ||
229       (duration.value == (uint64_t) - 1LL))
230     return GNUNET_TIME_absolute_get_forever ();
231   if (start.value + duration.value < start.value)
232     {
233       GNUNET_break (0);
234       return GNUNET_TIME_absolute_get_forever ();
235     }
236   ret.value = start.value + duration.value;
237   return ret;
238 }
239
240 /**
241  * Multiply relative time by a given factor.
242  *
243  * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
244  */
245 struct GNUNET_TIME_Relative
246 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
247                                unsigned int factor)
248 {
249   struct GNUNET_TIME_Relative ret;
250   if (factor == 0)
251     return GNUNET_TIME_relative_get_zero ();
252   ret.value = rel.value * (unsigned long long) factor;
253   if (ret.value / factor != rel.value)
254     {
255       GNUNET_break (0);
256       return GNUNET_TIME_relative_get_forever ();
257     }  
258   return ret;
259 }
260
261
262 /**
263  * Calculate the estimate time of arrival/completion 
264  * for an operation.
265  *
266  * @param start when did the operation start?
267  * @param finished how much has been done?
268  * @param total how much must be done overall (same unit as for "finished")
269  * @return remaining duration for the operation,
270  *        assuming it continues at the same speed
271  */
272 struct GNUNET_TIME_Relative GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
273                                                        uint64_t finished,
274                                                        uint64_t total)
275 {
276   struct GNUNET_TIME_Relative dur;
277   double exp;
278   struct GNUNET_TIME_Relative ret;
279
280   GNUNET_break (finished > total);
281   if (finished >= total)
282     return GNUNET_TIME_UNIT_ZERO;
283   if (finished == 0)
284     return GNUNET_TIME_UNIT_FOREVER_REL;
285   dur = GNUNET_TIME_absolute_get_duration (start);
286   exp = ((double)dur.value) * ((double) total) / ((double)finished);
287   ret.value = ((uint64_t) exp) - dur.value;
288   return ret;
289 }
290
291
292 /**
293  * Add relative times together.
294  *
295  * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
296  */
297 struct GNUNET_TIME_Relative
298 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
299                           struct GNUNET_TIME_Relative a2)
300 {
301   struct GNUNET_TIME_Relative ret;
302
303   if ((a1.value == (uint64_t) - 1LL) || (a2.value == (uint64_t) - 1LL))
304     return GNUNET_TIME_relative_get_forever ();
305   if (a1.value + a2.value < a1.value)
306     {
307       GNUNET_break (0);
308       return GNUNET_TIME_relative_get_forever ();
309     }
310   ret.value = a1.value + a2.value;
311   return ret;
312 }
313
314
315 /**
316  * Convert relative time to network byte order.
317  */
318 struct GNUNET_TIME_RelativeNBO
319 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
320 {
321   struct GNUNET_TIME_RelativeNBO ret;
322   ret.value__ = GNUNET_htonll (a.value);
323   return ret;
324 }
325
326 /**
327  * Convert relative time from network byte order.
328  */
329 struct GNUNET_TIME_Relative
330 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
331 {
332   struct GNUNET_TIME_Relative ret;
333   ret.value = GNUNET_ntohll (a.value__);
334   return ret;
335
336 }
337
338 /**
339  * Convert absolute time to network byte order.
340  */
341 struct GNUNET_TIME_AbsoluteNBO
342 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
343 {
344   struct GNUNET_TIME_AbsoluteNBO ret;
345   ret.value__ = GNUNET_htonll (a.value);
346   return ret;
347 }
348
349 /**
350  * Convert absolute time from network byte order.
351  */
352 struct GNUNET_TIME_Absolute
353 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
354 {
355   struct GNUNET_TIME_Absolute ret;
356   ret.value = GNUNET_ntohll (a.value__);
357   return ret;
358
359 }
360
361
362
363 /* end of time.c */