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_t) - 1LL };
94 struct GNUNET_TIME_Absolute
95 GNUNET_TIME_absolute_get_forever ()
97 static struct GNUNET_TIME_Absolute forever = { (uint64_t) - 1LL };
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_t) - 1LL)
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_t) - 1LL)
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_t) - 1LL)
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_t) - 1LL);
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_t) - 1LL) ||
262 (duration.value == (uint64_t) - 1LL))
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;
274 * Multiply relative time by a given factor.
276 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
278 struct GNUNET_TIME_Relative
279 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
282 struct GNUNET_TIME_Relative ret;
284 return GNUNET_TIME_relative_get_zero ();
285 ret.value = rel.value * (unsigned long long) factor;
286 if (ret.value / factor != rel.value)
289 return GNUNET_TIME_relative_get_forever ();
296 * Divide relative time by a given factor.
298 * @param rel some duration
299 * @param factor integer to divide by
300 * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
302 struct GNUNET_TIME_Relative
303 GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
306 struct GNUNET_TIME_Relative ret;
307 if ( (factor == 0) ||
308 (rel.value == GNUNET_TIME_UNIT_FOREVER_REL.value) )
309 return GNUNET_TIME_UNIT_FOREVER_REL;
310 ret.value = rel.value / (unsigned long long) factor;
316 * Calculate the estimate time of arrival/completion
319 * @param start when did the operation start?
320 * @param finished how much has been done?
321 * @param total how much must be done overall (same unit as for "finished")
322 * @return remaining duration for the operation,
323 * assuming it continues at the same speed
325 struct GNUNET_TIME_Relative
326 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
327 uint64_t finished, uint64_t total)
329 struct GNUNET_TIME_Relative dur;
331 struct GNUNET_TIME_Relative ret;
333 GNUNET_break (finished <= total);
334 if (finished >= total)
335 return GNUNET_TIME_UNIT_ZERO;
337 return GNUNET_TIME_UNIT_FOREVER_REL;
338 dur = GNUNET_TIME_absolute_get_duration (start);
339 exp = ((double) dur.value) * ((double) total) / ((double) finished);
340 ret.value = ((uint64_t) exp) - dur.value;
346 * Add relative times together.
348 * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
350 struct GNUNET_TIME_Relative
351 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
352 struct GNUNET_TIME_Relative a2)
354 struct GNUNET_TIME_Relative ret;
356 if ((a1.value == (uint64_t) - 1LL) || (a2.value == (uint64_t) - 1LL))
357 return GNUNET_TIME_relative_get_forever ();
358 if (a1.value + a2.value < a1.value)
361 return GNUNET_TIME_relative_get_forever ();
363 ret.value = a1.value + a2.value;
369 * Convert relative time to network byte order.
371 struct GNUNET_TIME_RelativeNBO
372 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
374 struct GNUNET_TIME_RelativeNBO ret;
375 ret.value__ = GNUNET_htonll (a.value);
380 * Convert relative time from network byte order.
382 struct GNUNET_TIME_Relative
383 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
385 struct GNUNET_TIME_Relative ret;
386 ret.value = GNUNET_ntohll (a.value__);
392 * Convert absolute time to network byte order.
394 struct GNUNET_TIME_AbsoluteNBO
395 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
397 struct GNUNET_TIME_AbsoluteNBO ret;
398 ret.value__ = GNUNET_htonll (a.value);
403 * Convert absolute time from network byte order.
405 struct GNUNET_TIME_Absolute
406 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
408 struct GNUNET_TIME_Absolute ret;
409 ret.value = GNUNET_ntohll (a.value__);