2 This file is part of GNUnet.
3 (C) 2001, 2002, 2006, 2009 Christian Grothoff (and other contributing authors)
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.
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.
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.
23 * @author Christian Grothoff
24 * @brief functions for handling time and time arithmetic
27 #include "gnunet_time_lib.h"
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)).
34 * @return the current time
36 struct GNUNET_TIME_Absolute
37 GNUNET_TIME_absolute_get ()
39 struct GNUNET_TIME_Absolute ret;
42 GETTIMEOFDAY (&tv, NULL);
44 (uint64_t) (((uint64_t) tv.tv_sec * 1000LL) +
45 ((uint64_t) tv.tv_usec / 1000LL));
51 * Return relative time of 0ms.
53 struct GNUNET_TIME_Relative
54 GNUNET_TIME_relative_get_zero ()
56 static struct GNUNET_TIME_Relative zero;
62 * Return absolute time of 0ms.
64 struct GNUNET_TIME_Absolute
65 GNUNET_TIME_absolute_get_zero ()
67 static struct GNUNET_TIME_Absolute zero;
72 * Return relative time of 1ms.
74 struct GNUNET_TIME_Relative
75 GNUNET_TIME_relative_get_unit ()
77 static struct GNUNET_TIME_Relative one = { 1 };
84 struct GNUNET_TIME_Relative
85 GNUNET_TIME_relative_get_forever ()
87 static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
94 struct GNUNET_TIME_Absolute
95 GNUNET_TIME_absolute_get_forever ()
97 static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
102 * Convert relative time to an absolute time in the
105 * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
107 struct GNUNET_TIME_Absolute
108 GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
110 struct GNUNET_TIME_Absolute ret;
111 if (rel.value == UINT64_MAX)
112 return GNUNET_TIME_absolute_get_forever ();
113 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
114 if (rel.value + now.value < rel.value)
116 GNUNET_break (0); /* overflow... */
117 return GNUNET_TIME_absolute_get_forever ();
119 ret.value = rel.value + now.value;
125 * Return the minimum of two relative time values.
127 * @param t1 first timestamp
128 * @param t2 other timestamp
129 * @return timestamp that is smaller
131 struct GNUNET_TIME_Relative
132 GNUNET_TIME_relative_min (struct
134 t1, struct GNUNET_TIME_Relative t2)
136 return (t1.value < t2.value) ? t1 : t2;
141 * Return the maximum of two relative time values.
143 * @param t1 first timestamp
144 * @param t2 other timestamp
145 * @return timestamp that is larger
147 struct GNUNET_TIME_Relative
148 GNUNET_TIME_relative_max (struct
150 t1, struct GNUNET_TIME_Relative t2)
152 return (t1.value > t2.value) ? t1 : t2;
158 * Return the minimum of two relative time values.
160 * @param t1 first timestamp
161 * @param t2 other timestamp
162 * @return timestamp that is smaller
164 struct GNUNET_TIME_Absolute
165 GNUNET_TIME_absolute_min (struct
167 t1, struct GNUNET_TIME_Absolute t2)
169 return (t1.value < t2.value) ? t1 : t2;
174 * Return the maximum of two relative time values.
176 * @param t1 first timestamp
177 * @param t2 other timestamp
178 * @return timestamp that is smaller
180 struct GNUNET_TIME_Absolute
181 GNUNET_TIME_absolute_max (struct
183 t1, struct GNUNET_TIME_Absolute t2)
185 return (t1.value > t2.value) ? t1 : t2;
190 * Given a timestamp in the future, how much time
191 * remains until then?
193 * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
195 struct GNUNET_TIME_Relative
196 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
198 struct GNUNET_TIME_Relative ret;
199 if (future.value == UINT64_MAX)
200 return GNUNET_TIME_relative_get_forever ();
201 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
202 if (now.value > future.value)
203 return GNUNET_TIME_relative_get_zero ();
204 ret.value = future.value - now.value;
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.
213 * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
215 struct GNUNET_TIME_Relative
216 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
217 struct GNUNET_TIME_Absolute end)
219 struct GNUNET_TIME_Relative ret;
220 if (end.value == UINT64_MAX)
221 return GNUNET_TIME_relative_get_forever ();
222 if (end.value < start.value)
223 return GNUNET_TIME_relative_get_zero ();
224 ret.value = end.value - start.value;
229 * Get the duration of an operation as the
230 * difference of the current time and the given start time "hence".
232 * @return aborts if hence==FOREVER, 0 if hence > now, otherwise now-hence.
234 struct GNUNET_TIME_Relative
235 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute hence)
237 struct GNUNET_TIME_Absolute now;
238 struct GNUNET_TIME_Relative ret;
240 now = GNUNET_TIME_absolute_get ();
241 GNUNET_assert (hence.value != UINT64_MAX);
242 if (hence.value > now.value)
243 return GNUNET_TIME_relative_get_zero ();
244 ret.value = now.value - hence.value;
250 * Add a given relative duration to the
253 * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
255 struct GNUNET_TIME_Absolute
256 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
257 struct GNUNET_TIME_Relative duration)
259 struct GNUNET_TIME_Absolute ret;
261 if ((start.value == UINT64_MAX) ||
262 (duration.value == UINT64_MAX))
263 return GNUNET_TIME_absolute_get_forever ();
264 if (start.value + duration.value < start.value)
267 return GNUNET_TIME_absolute_get_forever ();
269 ret.value = start.value + duration.value;
275 * Subtract a given relative duration from the
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
282 struct GNUNET_TIME_Absolute
283 GNUNET_TIME_absolute_subtract (struct
290 struct GNUNET_TIME_Absolute ret;
291 if (start.value <= duration.value)
292 return GNUNET_TIME_UNIT_ZERO_ABS;
293 if (start.value == GNUNET_TIME_UNIT_FOREVER_ABS.value)
294 return GNUNET_TIME_UNIT_FOREVER_ABS;
295 ret.value = start.value - duration.value;
301 * Multiply relative time by a given factor.
303 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
305 struct GNUNET_TIME_Relative
306 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
309 struct GNUNET_TIME_Relative ret;
311 return GNUNET_TIME_relative_get_zero ();
312 ret.value = rel.value * (unsigned long long) factor;
313 if (ret.value / factor != rel.value)
316 return GNUNET_TIME_relative_get_forever ();
323 * Divide relative time by a given factor.
325 * @param rel some duration
326 * @param factor integer to divide by
327 * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
329 struct GNUNET_TIME_Relative
330 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
333 struct GNUNET_TIME_Relative ret;
334 if ( (factor == 0) ||
335 (rel.value == GNUNET_TIME_UNIT_FOREVER_REL.value) )
336 return GNUNET_TIME_UNIT_FOREVER_REL;
337 ret.value = rel.value / (unsigned long long) factor;
343 * Calculate the estimate time of arrival/completion
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
352 struct GNUNET_TIME_Relative
353 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
354 uint64_t finished, uint64_t total)
356 struct GNUNET_TIME_Relative dur;
358 struct GNUNET_TIME_Relative ret;
360 GNUNET_break (finished <= total);
361 if (finished >= total)
362 return GNUNET_TIME_UNIT_ZERO;
364 return GNUNET_TIME_UNIT_FOREVER_REL;
365 dur = GNUNET_TIME_absolute_get_duration (start);
366 exp = ((double) dur.value) * ((double) total) / ((double) finished);
367 ret.value = ((uint64_t) exp) - dur.value;
373 * Add relative times together.
375 * @param a1 first timestamp
376 * @param a2 second timestamp
377 * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
379 struct GNUNET_TIME_Relative
380 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
381 struct GNUNET_TIME_Relative a2)
383 struct GNUNET_TIME_Relative ret;
385 if ((a1.value == UINT64_MAX) || (a2.value == UINT64_MAX))
386 return GNUNET_TIME_relative_get_forever ();
387 if (a1.value + a2.value < a1.value)
390 return GNUNET_TIME_relative_get_forever ();
392 ret.value = a1.value + a2.value;
398 * Subtract relative timestamp from the other.
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
404 struct GNUNET_TIME_Relative
405 GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
406 struct GNUNET_TIME_Relative a2)
408 struct GNUNET_TIME_Relative ret;
410 if (a2.value >= a1.value)
411 return GNUNET_TIME_relative_get_zero ();
412 if (a1.value == UINT64_MAX)
413 return GNUNET_TIME_relative_get_forever ();
414 ret.value = a1.value - a2.value;
420 * Convert relative time to network byte order.
422 * @param a time to convert
423 * @return time in network byte order
425 struct GNUNET_TIME_RelativeNBO
426 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
428 struct GNUNET_TIME_RelativeNBO ret;
429 ret.value__ = GNUNET_htonll (a.value);
434 * Convert relative time from network byte order.
436 * @param a time to convert
437 * @return time in host byte order
439 struct GNUNET_TIME_Relative
440 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
442 struct GNUNET_TIME_Relative ret;
443 ret.value = GNUNET_ntohll (a.value__);
449 * Convert absolute time to network byte order.
451 * @param a time to convert
452 * @return time in network byte order
454 struct GNUNET_TIME_AbsoluteNBO
455 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
457 struct GNUNET_TIME_AbsoluteNBO ret;
458 ret.value__ = GNUNET_htonll (a.value);
463 * Convert absolute time from network byte order.
465 * @param a time to convert
466 * @return time in host byte order
468 struct GNUNET_TIME_Absolute
469 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
471 struct GNUNET_TIME_Absolute ret;
472 ret.value = GNUNET_ntohll (a.value__);