aboutsummaryrefslogtreecommitdiff
path: root/src/util/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/time.c')
-rw-r--r--src/util/time.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/util/time.c b/src/util/time.c
new file mode 100644
index 000000000..3ae472561
--- /dev/null
+++ b/src/util/time.c
@@ -0,0 +1,286 @@
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 */
36struct GNUNET_TIME_Absolute
37GNUNET_TIME_absolute_get ()
38{
39 struct GNUNET_TIME_Absolute ret;
40 struct timeval tv;
41
42 gettimeofday (&tv, NULL);
43 ret.value = tv.tv_sec * 1000 + tv.tv_usec / 1000;
44 return ret;
45}
46
47
48/**
49 * Return relative time of 0ms.
50 */
51struct GNUNET_TIME_Relative
52GNUNET_TIME_relative_get_zero ()
53{
54 static struct GNUNET_TIME_Relative zero;
55 return zero;
56}
57
58/**
59 * Return relative time of 1ms.
60 */
61struct GNUNET_TIME_Relative
62GNUNET_TIME_relative_get_unit ()
63{
64 static struct GNUNET_TIME_Relative one = { 1 };
65 return one;
66}
67
68/**
69 * Return "forever".
70 */
71struct GNUNET_TIME_Relative
72GNUNET_TIME_relative_get_forever ()
73{
74 static struct GNUNET_TIME_Relative forever = { (uint64_t) - 1LL };
75 return forever;
76}
77
78/**
79 * Return "forever".
80 */
81struct GNUNET_TIME_Absolute
82GNUNET_TIME_absolute_get_forever ()
83{
84 static struct GNUNET_TIME_Absolute forever = { (uint64_t) - 1LL };
85 return forever;
86}
87
88/**
89 * Convert relative time to an absolute time in the
90 * future.
91 *
92 * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
93 */
94struct GNUNET_TIME_Absolute
95GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
96{
97 struct GNUNET_TIME_Absolute ret;
98 if (rel.value == (uint64_t) - 1LL)
99 return GNUNET_TIME_absolute_get_forever ();
100 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
101 if (rel.value + now.value < rel.value)
102 {
103 GNUNET_break (0); /* overflow... */
104 return GNUNET_TIME_absolute_get_forever ();
105 }
106 ret.value = rel.value + now.value;
107 return ret;
108}
109
110/**
111 * Given a timestamp in the future, how much time
112 * remains until then?
113 *
114 * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
115 */
116struct GNUNET_TIME_Relative
117GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
118{
119 struct GNUNET_TIME_Relative ret;
120 if (future.value == (uint64_t) - 1LL)
121 return GNUNET_TIME_relative_get_forever ();
122 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
123 if (now.value > future.value)
124 return GNUNET_TIME_relative_get_zero ();
125 ret.value = future.value - now.value;
126 return ret;
127}
128
129/**
130 * Compute the time difference between the given start and end times.
131 * Use this function instead of actual subtraction to ensure that
132 * "FOREVER" and overflows are handeled correctly.
133 *
134 * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
135 */
136struct GNUNET_TIME_Relative
137GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
138 struct GNUNET_TIME_Absolute end)
139{
140 struct GNUNET_TIME_Relative ret;
141 if (end.value == (uint64_t) - 1LL)
142 return GNUNET_TIME_relative_get_forever ();
143 if (end.value < start.value)
144 return GNUNET_TIME_relative_get_zero ();
145 ret.value = end.value - start.value;
146 return ret;
147}
148
149/**
150 * Get the duration of an operation as the
151 * difference of the current time and the given start time "hence".
152 *
153 * @return aborts if hence==FOREVER, 0 if hence > now, otherwise now-hence.
154 */
155struct GNUNET_TIME_Relative
156GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute hence)
157{
158 struct GNUNET_TIME_Absolute now;
159 struct GNUNET_TIME_Relative ret;
160
161 now = GNUNET_TIME_absolute_get ();
162 GNUNET_assert (hence.value != (uint64_t) - 1LL);
163 if (hence.value > now.value)
164 return GNUNET_TIME_relative_get_zero ();
165 ret.value = now.value - hence.value;
166 return ret;
167}
168
169
170/**
171 * Add a given relative duration to the
172 * given start time.
173 *
174 * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
175 */
176struct GNUNET_TIME_Absolute
177GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
178 struct GNUNET_TIME_Relative duration)
179{
180 struct GNUNET_TIME_Absolute ret;
181
182 if ((start.value == (uint64_t) - 1LL) ||
183 (duration.value == (uint64_t) - 1LL))
184 return GNUNET_TIME_absolute_get_forever ();
185 if (start.value + duration.value < start.value)
186 {
187 GNUNET_break (0);
188 return GNUNET_TIME_absolute_get_forever ();
189 }
190 ret.value = start.value + duration.value;
191 return ret;
192}
193
194/**
195 * Multiply relative time by a given factor.
196 *
197 * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
198 */
199struct GNUNET_TIME_Relative
200GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
201 unsigned int factor)
202{
203 struct GNUNET_TIME_Relative ret;
204 if (factor == 0)
205 return GNUNET_TIME_relative_get_zero ();
206 ret.value = rel.value * factor;
207 if (ret.value / factor != rel.value)
208 {
209 GNUNET_break (0);
210 return GNUNET_TIME_relative_get_forever ();
211 }
212 return ret;
213}
214
215/**
216 * Add relative times together.
217 *
218 * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
219 */
220struct GNUNET_TIME_Relative
221GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
222 struct GNUNET_TIME_Relative a2)
223{
224 struct GNUNET_TIME_Relative ret;
225
226 if ((a1.value == (uint64_t) - 1LL) || (a2.value == (uint64_t) - 1LL))
227 return GNUNET_TIME_relative_get_forever ();
228 if (a1.value + a2.value < a1.value)
229 {
230 GNUNET_break (0);
231 return GNUNET_TIME_relative_get_forever ();
232 }
233 ret.value = a1.value + a2.value;
234 return ret;
235}
236
237
238/**
239 * Convert relative time to network byte order.
240 */
241struct GNUNET_TIME_RelativeNBO
242GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
243{
244 struct GNUNET_TIME_RelativeNBO ret;
245 ret.value = GNUNET_htonll (a.value);
246 return ret;
247}
248
249/**
250 * Convert relative time from network byte order.
251 */
252struct GNUNET_TIME_Relative
253GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
254{
255 struct GNUNET_TIME_Relative ret;
256 ret.value = GNUNET_ntohll (a.value);
257 return ret;
258
259}
260
261/**
262 * Convert absolute time to network byte order.
263 */
264struct GNUNET_TIME_AbsoluteNBO
265GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
266{
267 struct GNUNET_TIME_AbsoluteNBO ret;
268 ret.value = GNUNET_htonll (a.value);
269 return ret;
270}
271
272/**
273 * Convert absolute time from network byte order.
274 */
275struct GNUNET_TIME_Absolute
276GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
277{
278 struct GNUNET_TIME_Absolute ret;
279 ret.value = GNUNET_ntohll (a.value);
280 return ret;
281
282}
283
284
285
286/* end of time.c */