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;
142 * Return the minimum of two relative time values.
144 * @param t1 first timestamp
145 * @param t2 other timestamp
146 * @return timestamp that is smaller
148 struct GNUNET_TIME_Absolute
149 GNUNET_TIME_absolute_min (struct
151 t1, struct GNUNET_TIME_Absolute t2)
153 return (t1.value < t2.value) ? t1 : t2;
158 * Return the maximum 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_max (struct
167 t1, struct GNUNET_TIME_Absolute t2)
169 return (t1.value > t2.value) ? t1 : t2;
174 * Given a timestamp in the future, how much time
175 * remains until then?
177 * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
179 struct GNUNET_TIME_Relative
180 GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
182 struct GNUNET_TIME_Relative ret;
183 if (future.value == (uint64_t) - 1LL)
184 return GNUNET_TIME_relative_get_forever ();
185 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
186 if (now.value > future.value)
187 return GNUNET_TIME_relative_get_zero ();
188 ret.value = future.value - now.value;
193 * Compute the time difference between the given start and end times.
194 * Use this function instead of actual subtraction to ensure that
195 * "FOREVER" and overflows are handeled correctly.
197 * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
199 struct GNUNET_TIME_Relative
200 GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
201 struct GNUNET_TIME_Absolute end)
203 struct GNUNET_TIME_Relative ret;
204 if (end.value == (uint64_t) - 1LL)
205 return GNUNET_TIME_relative_get_forever ();
206 if (end.value < start.value)
207 return GNUNET_TIME_relative_get_zero ();
208 ret.value = end.value - start.value;
213 * Get the duration of an operation as the
214 * difference of the current time and the given start time "hence".
216 * @return aborts if hence==FOREVER, 0 if hence > now, otherwise now-hence.
218 struct GNUNET_TIME_Relative
219 GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute hence)
221 struct GNUNET_TIME_Absolute now;
222 struct GNUNET_TIME_Relative ret;
224 now = GNUNET_TIME_absolute_get ();
225 GNUNET_assert (hence.value != (uint64_t) - 1LL);
226 if (hence.value > now.value)
227 return GNUNET_TIME_relative_get_zero ();
228 ret.value = now.value - hence.value;
234 * Add a given relative duration to the
237 * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
239 struct GNUNET_TIME_Absolute
240 GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
241 struct GNUNET_TIME_Relative duration)
243 struct GNUNET_TIME_Absolute ret;
245 if ((start.value == (uint64_t) - 1LL) ||
246 (duration.value == (uint64_t) - 1LL))
247 return GNUNET_TIME_absolute_get_forever ();
248 if (start.value + duration.value < start.value)
251 return GNUNET_TIME_absolute_get_forever ();
253 ret.value = start.value + duration.value;
258 * Multiply relative time by a given factor.
260 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
262 struct GNUNET_TIME_Relative
263 GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
266 struct GNUNET_TIME_Relative ret;
268 return GNUNET_TIME_relative_get_zero ();
269 ret.value = rel.value * (unsigned long long) factor;
270 if (ret.value / factor != rel.value)
273 return GNUNET_TIME_relative_get_forever ();
280 * Calculate the estimate time of arrival/completion
283 * @param start when did the operation start?
284 * @param finished how much has been done?
285 * @param total how much must be done overall (same unit as for "finished")
286 * @return remaining duration for the operation,
287 * assuming it continues at the same speed
289 struct GNUNET_TIME_Relative
290 GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
291 uint64_t finished, uint64_t total)
293 struct GNUNET_TIME_Relative dur;
295 struct GNUNET_TIME_Relative ret;
297 GNUNET_break (finished <= total);
298 if (finished >= total)
299 return GNUNET_TIME_UNIT_ZERO;
301 return GNUNET_TIME_UNIT_FOREVER_REL;
302 dur = GNUNET_TIME_absolute_get_duration (start);
303 exp = ((double) dur.value) * ((double) total) / ((double) finished);
304 ret.value = ((uint64_t) exp) - dur.value;
310 * Add relative times together.
312 * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
314 struct GNUNET_TIME_Relative
315 GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
316 struct GNUNET_TIME_Relative a2)
318 struct GNUNET_TIME_Relative ret;
320 if ((a1.value == (uint64_t) - 1LL) || (a2.value == (uint64_t) - 1LL))
321 return GNUNET_TIME_relative_get_forever ();
322 if (a1.value + a2.value < a1.value)
325 return GNUNET_TIME_relative_get_forever ();
327 ret.value = a1.value + a2.value;
333 * Convert relative time to network byte order.
335 struct GNUNET_TIME_RelativeNBO
336 GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
338 struct GNUNET_TIME_RelativeNBO ret;
339 ret.value__ = GNUNET_htonll (a.value);
344 * Convert relative time from network byte order.
346 struct GNUNET_TIME_Relative
347 GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
349 struct GNUNET_TIME_Relative ret;
350 ret.value = GNUNET_ntohll (a.value__);
356 * Convert absolute time to network byte order.
358 struct GNUNET_TIME_AbsoluteNBO
359 GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
361 struct GNUNET_TIME_AbsoluteNBO ret;
362 ret.value__ = GNUNET_htonll (a.value);
367 * Convert absolute time from network byte order.
369 struct GNUNET_TIME_Absolute
370 GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
372 struct GNUNET_TIME_Absolute ret;
373 ret.value = GNUNET_ntohll (a.value__);