diff options
Diffstat (limited to 'src/util/time.c')
-rw-r--r-- | src/util/time.c | 218 |
1 files changed, 191 insertions, 27 deletions
diff --git a/src/util/time.c b/src/util/time.c index 144e1b401..83b39b4e8 100644 --- a/src/util/time.c +++ b/src/util/time.c | |||
@@ -58,27 +58,35 @@ GNUNET_TIME_get_offset () | |||
58 | } | 58 | } |
59 | 59 | ||
60 | 60 | ||
61 | int | 61 | struct GNUNET_TIME_Timestamp |
62 | GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at) | 62 | GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at) |
63 | { | 63 | { |
64 | if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) | 64 | struct GNUNET_TIME_Timestamp ts; |
65 | return GNUNET_OK; | 65 | |
66 | if (0 == at->abs_value_us % 1000000) | 66 | if (GNUNET_TIME_absolute_is_never (at)) |
67 | return GNUNET_OK; | 67 | return GNUNET_TIME_UNIT_FOREVER_TS; |
68 | at->abs_value_us -= at->abs_value_us % 1000000; | 68 | ts.abs_time.abs_value_us = at.abs_value_us - at.abs_value_us % 1000000; |
69 | return GNUNET_NO; | 69 | return ts; |
70 | } | ||
71 | |||
72 | |||
73 | struct GNUNET_TIME_TimestampNBO | ||
74 | GNUNET_TIME_timestamp_hton (struct GNUNET_TIME_Timestamp t) | ||
75 | { | ||
76 | struct GNUNET_TIME_TimestampNBO tn; | ||
77 | |||
78 | tn.abs_time_nbo = GNUNET_TIME_absolute_hton (t.abs_time); | ||
79 | return tn; | ||
70 | } | 80 | } |
71 | 81 | ||
72 | 82 | ||
73 | int | 83 | struct GNUNET_TIME_Timestamp |
74 | GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt) | 84 | GNUNET_TIME_timestamp_ntoh (struct GNUNET_TIME_TimestampNBO tn) |
75 | { | 85 | { |
76 | if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 86 | struct GNUNET_TIME_Timestamp t; |
77 | return GNUNET_OK; | 87 | |
78 | if (0 == rt->rel_value_us % 1000000) | 88 | t.abs_time = GNUNET_TIME_absolute_ntoh (tn.abs_time_nbo); |
79 | return GNUNET_OK; | 89 | return t; |
80 | rt->rel_value_us -= rt->rel_value_us % 1000000; | ||
81 | return GNUNET_NO; | ||
82 | } | 90 | } |
83 | 91 | ||
84 | 92 | ||
@@ -96,6 +104,14 @@ GNUNET_TIME_absolute_get () | |||
96 | } | 104 | } |
97 | 105 | ||
98 | 106 | ||
107 | struct GNUNET_TIME_Timestamp | ||
108 | GNUNET_TIME_timestamp_get () | ||
109 | { | ||
110 | return GNUNET_TIME_absolute_to_timestamp ( | ||
111 | GNUNET_TIME_absolute_get ()); | ||
112 | } | ||
113 | |||
114 | |||
99 | struct GNUNET_TIME_Relative | 115 | struct GNUNET_TIME_Relative |
100 | GNUNET_TIME_relative_get_zero_ () | 116 | GNUNET_TIME_relative_get_zero_ () |
101 | { | 117 | { |
@@ -177,12 +193,114 @@ GNUNET_TIME_absolute_get_forever_ () | |||
177 | } | 193 | } |
178 | 194 | ||
179 | 195 | ||
196 | const char * | ||
197 | GNUNET_TIME_timestamp2s (struct GNUNET_TIME_Timestamp ts) | ||
198 | { | ||
199 | static GNUNET_THREAD_LOCAL char buf[255]; | ||
200 | time_t tt; | ||
201 | struct tm *tp; | ||
202 | |||
203 | if (GNUNET_TIME_absolute_is_never (ts.abs_time)) | ||
204 | return "end of time"; | ||
205 | tt = ts.abs_time.abs_value_us / 1000LL / 1000LL; | ||
206 | tp = localtime (&tt); | ||
207 | /* This is hacky, but i don't know a way to detect libc character encoding. | ||
208 | * Just expect utf8 from glibc these days. | ||
209 | * As for msvcrt, use the wide variant, which always returns utf16 | ||
210 | * (otherwise we'd have to detect current codepage or use W32API character | ||
211 | * set conversion routines to convert to UTF8). | ||
212 | */ | ||
213 | strftime (buf, | ||
214 | sizeof(buf), | ||
215 | "%a %b %d %H:%M:%S %Y", | ||
216 | tp); | ||
217 | return buf; | ||
218 | } | ||
219 | |||
220 | |||
221 | const char * | ||
222 | GNUNET_TIME_absolute2s (struct GNUNET_TIME_Absolute t) | ||
223 | { | ||
224 | static GNUNET_THREAD_LOCAL char buf[255]; | ||
225 | time_t tt; | ||
226 | struct tm *tp; | ||
227 | |||
228 | if (GNUNET_TIME_absolute_is_never (t)) | ||
229 | return "end of time"; | ||
230 | tt = t.abs_value_us / 1000LL / 1000LL; | ||
231 | tp = localtime (&tt); | ||
232 | /* This is hacky, but i don't know a way to detect libc character encoding. | ||
233 | * Just expect utf8 from glibc these days. | ||
234 | * As for msvcrt, use the wide variant, which always returns utf16 | ||
235 | * (otherwise we'd have to detect current codepage or use W32API character | ||
236 | * set conversion routines to convert to UTF8). | ||
237 | */ | ||
238 | strftime (buf, | ||
239 | sizeof(buf), | ||
240 | "%a %b %d %H:%M:%S %Y", | ||
241 | tp); | ||
242 | return buf; | ||
243 | } | ||
244 | |||
245 | |||
246 | const char * | ||
247 | GNUNET_TIME_relative2s (struct GNUNET_TIME_Relative delta, | ||
248 | bool do_round) | ||
249 | { | ||
250 | static GNUNET_THREAD_LOCAL char buf[128]; | ||
251 | const char *unit = /* time unit */ "µs"; | ||
252 | uint64_t dval = delta.rel_value_us; | ||
253 | |||
254 | if (GNUNET_TIME_relative_is_forever (delta)) | ||
255 | return "forever"; | ||
256 | if (0 == delta.rel_value_us) | ||
257 | return "0 ms"; | ||
258 | if ( ((GNUNET_YES == do_round) && | ||
259 | (dval > 5 * 1000)) || | ||
260 | (0 == (dval % 1000))) | ||
261 | { | ||
262 | dval = dval / 1000; | ||
263 | unit = /* time unit */ "ms"; | ||
264 | if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000))) | ||
265 | { | ||
266 | dval = dval / 1000; | ||
267 | unit = /* time unit */ "s"; | ||
268 | if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60))) | ||
269 | { | ||
270 | dval = dval / 60; | ||
271 | unit = /* time unit */ "m"; | ||
272 | if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60))) | ||
273 | { | ||
274 | dval = dval / 60; | ||
275 | unit = /* time unit */ "h"; | ||
276 | if (((GNUNET_YES == do_round) && (dval > 5 * 24)) || | ||
277 | (0 == (dval % 24))) | ||
278 | { | ||
279 | dval = dval / 24; | ||
280 | if (1 == dval) | ||
281 | unit = /* time unit */ "day"; | ||
282 | else | ||
283 | unit = /* time unit */ "days"; | ||
284 | } | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | GNUNET_snprintf (buf, | ||
290 | sizeof(buf), | ||
291 | "%llu %s", | ||
292 | (unsigned long long) dval, | ||
293 | unit); | ||
294 | return buf; | ||
295 | } | ||
296 | |||
297 | |||
180 | struct GNUNET_TIME_Absolute | 298 | struct GNUNET_TIME_Absolute |
181 | GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) | 299 | GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) |
182 | { | 300 | { |
183 | struct GNUNET_TIME_Absolute ret; | 301 | struct GNUNET_TIME_Absolute ret; |
184 | 302 | ||
185 | if (rel.rel_value_us == UINT64_MAX) | 303 | if (GNUNET_TIME_relative_is_forever (rel)) |
186 | return GNUNET_TIME_UNIT_FOREVER_ABS; | 304 | return GNUNET_TIME_UNIT_FOREVER_ABS; |
187 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | 305 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); |
188 | 306 | ||
@@ -196,6 +314,14 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) | |||
196 | } | 314 | } |
197 | 315 | ||
198 | 316 | ||
317 | struct GNUNET_TIME_Timestamp | ||
318 | GNUNET_TIME_relative_to_timestamp (struct GNUNET_TIME_Relative rel) | ||
319 | { | ||
320 | return GNUNET_TIME_absolute_to_timestamp ( | ||
321 | GNUNET_TIME_relative_to_absolute (rel)); | ||
322 | } | ||
323 | |||
324 | |||
199 | struct GNUNET_TIME_Relative | 325 | struct GNUNET_TIME_Relative |
200 | GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1, | 326 | GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1, |
201 | struct GNUNET_TIME_Relative t2) | 327 | struct GNUNET_TIME_Relative t2) |
@@ -228,12 +354,28 @@ GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1, | |||
228 | } | 354 | } |
229 | 355 | ||
230 | 356 | ||
357 | struct GNUNET_TIME_Timestamp | ||
358 | GNUNET_TIME_timestamp_max (struct GNUNET_TIME_Timestamp t1, | ||
359 | struct GNUNET_TIME_Timestamp t2) | ||
360 | { | ||
361 | return (t1.abs_time.abs_value_us > t2.abs_time.abs_value_us) ? t1 : t2; | ||
362 | } | ||
363 | |||
364 | |||
365 | struct GNUNET_TIME_Timestamp | ||
366 | GNUNET_TIME_timestamp_min (struct GNUNET_TIME_Timestamp t1, | ||
367 | struct GNUNET_TIME_Timestamp t2) | ||
368 | { | ||
369 | return (t1.abs_time.abs_value_us < t2.abs_time.abs_value_us) ? t1 : t2; | ||
370 | } | ||
371 | |||
372 | |||
231 | struct GNUNET_TIME_Relative | 373 | struct GNUNET_TIME_Relative |
232 | GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) | 374 | GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) |
233 | { | 375 | { |
234 | struct GNUNET_TIME_Relative ret; | 376 | struct GNUNET_TIME_Relative ret; |
235 | 377 | ||
236 | if (future.abs_value_us == UINT64_MAX) | 378 | if (GNUNET_TIME_absolute_is_never (future)) |
237 | return GNUNET_TIME_UNIT_FOREVER_REL; | 379 | return GNUNET_TIME_UNIT_FOREVER_REL; |
238 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | 380 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); |
239 | 381 | ||
@@ -250,7 +392,7 @@ GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start, | |||
250 | { | 392 | { |
251 | struct GNUNET_TIME_Relative ret; | 393 | struct GNUNET_TIME_Relative ret; |
252 | 394 | ||
253 | if (end.abs_value_us == UINT64_MAX) | 395 | if (GNUNET_TIME_absolute_is_never (end)) |
254 | return GNUNET_TIME_UNIT_FOREVER_REL; | 396 | return GNUNET_TIME_UNIT_FOREVER_REL; |
255 | if (end.abs_value_us < start.abs_value_us) | 397 | if (end.abs_value_us < start.abs_value_us) |
256 | return GNUNET_TIME_UNIT_ZERO; | 398 | return GNUNET_TIME_UNIT_ZERO; |
@@ -279,8 +421,8 @@ GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start, | |||
279 | { | 421 | { |
280 | struct GNUNET_TIME_Absolute ret; | 422 | struct GNUNET_TIME_Absolute ret; |
281 | 423 | ||
282 | if ((start.abs_value_us == UINT64_MAX) || | 424 | if (GNUNET_TIME_absolute_is_never (start) || |
283 | (duration.rel_value_us == UINT64_MAX)) | 425 | GNUNET_TIME_relative_is_forever (duration)) |
284 | return GNUNET_TIME_UNIT_FOREVER_ABS; | 426 | return GNUNET_TIME_UNIT_FOREVER_ABS; |
285 | if (start.abs_value_us + duration.rel_value_us < start.abs_value_us) | 427 | if (start.abs_value_us + duration.rel_value_us < start.abs_value_us) |
286 | { | 428 | { |
@@ -300,7 +442,7 @@ GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start, | |||
300 | 442 | ||
301 | if (start.abs_value_us <= duration.rel_value_us) | 443 | if (start.abs_value_us <= duration.rel_value_us) |
302 | return GNUNET_TIME_UNIT_ZERO_ABS; | 444 | return GNUNET_TIME_UNIT_ZERO_ABS; |
303 | if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) | 445 | if (GNUNET_TIME_absolute_is_never (start)) |
304 | return GNUNET_TIME_UNIT_FOREVER_ABS; | 446 | return GNUNET_TIME_UNIT_FOREVER_ABS; |
305 | ret.abs_value_us = start.abs_value_us - duration.rel_value_us; | 447 | ret.abs_value_us = start.abs_value_us - duration.rel_value_us; |
306 | return ret; | 448 | return ret; |
@@ -315,7 +457,7 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel, | |||
315 | 457 | ||
316 | if (0 == factor) | 458 | if (0 == factor) |
317 | return GNUNET_TIME_UNIT_ZERO; | 459 | return GNUNET_TIME_UNIT_ZERO; |
318 | if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 460 | if (GNUNET_TIME_relative_is_forever (rel)) |
319 | return GNUNET_TIME_UNIT_FOREVER_REL; | 461 | return GNUNET_TIME_UNIT_FOREVER_REL; |
320 | ret.rel_value_us = rel.rel_value_us * factor; | 462 | ret.rel_value_us = rel.rel_value_us * factor; |
321 | if (ret.rel_value_us / factor != rel.rel_value_us) | 463 | if (ret.rel_value_us / factor != rel.rel_value_us) |
@@ -328,7 +470,8 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel, | |||
328 | 470 | ||
329 | 471 | ||
330 | struct GNUNET_TIME_Relative | 472 | struct GNUNET_TIME_Relative |
331 | relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor) | 473 | relative_multiply_double (struct GNUNET_TIME_Relative rel, |
474 | double factor) | ||
332 | { | 475 | { |
333 | struct GNUNET_TIME_Relative out; | 476 | struct GNUNET_TIME_Relative out; |
334 | double m; | 477 | double m; |
@@ -337,7 +480,7 @@ relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor) | |||
337 | 480 | ||
338 | if (0 == factor) | 481 | if (0 == factor) |
339 | return GNUNET_TIME_UNIT_ZERO; | 482 | return GNUNET_TIME_UNIT_ZERO; |
340 | if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 483 | if (GNUNET_TIME_relative_is_forever (rel)) |
341 | return GNUNET_TIME_UNIT_FOREVER_REL; | 484 | return GNUNET_TIME_UNIT_FOREVER_REL; |
342 | 485 | ||
343 | m = ((double) rel.rel_value_us) * factor; | 486 | m = ((double) rel.rel_value_us) * factor; |
@@ -361,7 +504,7 @@ GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel, | |||
361 | 504 | ||
362 | if (0 == factor) | 505 | if (0 == factor) |
363 | return GNUNET_TIME_UNIT_ZERO; | 506 | return GNUNET_TIME_UNIT_ZERO; |
364 | if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 507 | if (GNUNET_TIME_relative_is_forever (rel)) |
365 | return GNUNET_TIME_UNIT_FOREVER_REL; | 508 | return GNUNET_TIME_UNIT_FOREVER_REL; |
366 | ret.rel_value_us = rel.rel_value_us * factor; | 509 | ret.rel_value_us = rel.rel_value_us * factor; |
367 | if (ret.rel_value_us / factor != rel.rel_value_us) | 510 | if (ret.rel_value_us / factor != rel.rel_value_us) |
@@ -379,7 +522,7 @@ GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel, | |||
379 | struct GNUNET_TIME_Relative ret; | 522 | struct GNUNET_TIME_Relative ret; |
380 | 523 | ||
381 | if ((0 == factor) || | 524 | if ((0 == factor) || |
382 | (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)) | 525 | (GNUNET_TIME_relative_is_forever (rel))) |
383 | return GNUNET_TIME_UNIT_FOREVER_REL; | 526 | return GNUNET_TIME_UNIT_FOREVER_REL; |
384 | ret.rel_value_us = rel.rel_value_us / factor; | 527 | ret.rel_value_us = rel.rel_value_us / factor; |
385 | return ret; | 528 | return ret; |
@@ -538,6 +681,20 @@ GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch) | |||
538 | } | 681 | } |
539 | 682 | ||
540 | 683 | ||
684 | struct GNUNET_TIME_Timestamp | ||
685 | GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch) | ||
686 | { | ||
687 | struct GNUNET_TIME_Timestamp ret; | ||
688 | |||
689 | ret.abs_time.abs_value_us | ||
690 | = GNUNET_TIME_UNIT_SECONDS.rel_value_us * s_after_epoch; | ||
691 | if (ret.abs_time.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us | ||
692 | != s_after_epoch) | ||
693 | ret = GNUNET_TIME_UNIT_FOREVER_TS; | ||
694 | return ret; | ||
695 | } | ||
696 | |||
697 | |||
541 | struct GNUNET_TIME_Absolute | 698 | struct GNUNET_TIME_Absolute |
542 | GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a) | 699 | GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a) |
543 | { | 700 | { |
@@ -645,6 +802,13 @@ GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt, | |||
645 | } | 802 | } |
646 | 803 | ||
647 | 804 | ||
805 | bool | ||
806 | GNUNET_TIME_absolute_is_zero (struct GNUNET_TIME_Absolute abs) | ||
807 | { | ||
808 | return 0 == abs.abs_value_us; | ||
809 | } | ||
810 | |||
811 | |||
648 | struct GNUNET_TIME_Relative | 812 | struct GNUNET_TIME_Relative |
649 | GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r) | 813 | GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r) |
650 | { | 814 | { |