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.c789
1 files changed, 0 insertions, 789 deletions
diff --git a/src/util/time.c b/src/util/time.c
deleted file mode 100644
index 144e1b401..000000000
--- a/src/util/time.c
+++ /dev/null
@@ -1,789 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001-2013, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
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_util_lib.h"
28#if __STDC_NO_ATOMICS__
29#define ATOMIC
30#else
31#ifdef HAVE_STDATOMIC_H
32#include <stdatomic.h>
33#define ATOMIC _Atomic
34#else
35#define __STDC_NO_ATOMICS__ 1
36#define ATOMIC
37#endif
38#endif
39
40#define LOG(kind, ...) GNUNET_log_from (kind, "util-time", __VA_ARGS__)
41
42/**
43 * Variable used to simulate clock skew. Used for testing, never in production.
44 */
45static long long timestamp_offset;
46
47void
48GNUNET_TIME_set_offset (long long offset)
49{
50 timestamp_offset = offset;
51}
52
53
54long long
55GNUNET_TIME_get_offset ()
56{
57 return timestamp_offset;
58}
59
60
61int
62GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at)
63{
64 if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
65 return GNUNET_OK;
66 if (0 == at->abs_value_us % 1000000)
67 return GNUNET_OK;
68 at->abs_value_us -= at->abs_value_us % 1000000;
69 return GNUNET_NO;
70}
71
72
73int
74GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt)
75{
76 if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
77 return GNUNET_OK;
78 if (0 == rt->rel_value_us % 1000000)
79 return GNUNET_OK;
80 rt->rel_value_us -= rt->rel_value_us % 1000000;
81 return GNUNET_NO;
82}
83
84
85struct GNUNET_TIME_Absolute
86GNUNET_TIME_absolute_get ()
87{
88 struct GNUNET_TIME_Absolute ret;
89 struct timeval tv;
90
91 gettimeofday (&tv, NULL);
92 ret.abs_value_us = (uint64_t) (((uint64_t) tv.tv_sec * 1000LL * 1000LL)
93 + ((uint64_t) tv.tv_usec))
94 + timestamp_offset;
95 return ret;
96}
97
98
99struct GNUNET_TIME_Relative
100GNUNET_TIME_relative_get_zero_ ()
101{
102 static struct GNUNET_TIME_Relative zero;
103
104 return zero;
105}
106
107
108struct GNUNET_TIME_Absolute
109GNUNET_TIME_absolute_get_zero_ ()
110{
111 static struct GNUNET_TIME_Absolute zero;
112
113 return zero;
114}
115
116
117struct GNUNET_TIME_Relative
118GNUNET_TIME_relative_get_unit_ ()
119{
120 static struct GNUNET_TIME_Relative one = { 1 };
121
122 return one;
123}
124
125
126struct GNUNET_TIME_Relative
127GNUNET_TIME_relative_get_millisecond_ ()
128{
129 static struct GNUNET_TIME_Relative one = { 1000 };
130
131 return one;
132}
133
134
135struct GNUNET_TIME_Relative
136GNUNET_TIME_relative_get_second_ ()
137{
138 static struct GNUNET_TIME_Relative one = { 1000 * 1000LL };
139
140 return one;
141}
142
143
144struct GNUNET_TIME_Relative
145GNUNET_TIME_relative_get_minute_ ()
146{
147 static struct GNUNET_TIME_Relative one = { 60 * 1000 * 1000LL };
148
149 return one;
150}
151
152
153struct GNUNET_TIME_Relative
154GNUNET_TIME_relative_get_hour_ ()
155{
156 static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 * 1000LL };
157
158 return one;
159}
160
161
162struct GNUNET_TIME_Relative
163GNUNET_TIME_relative_get_forever_ ()
164{
165 static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
166
167 return forever;
168}
169
170
171struct GNUNET_TIME_Absolute
172GNUNET_TIME_absolute_get_forever_ ()
173{
174 static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
175
176 return forever;
177}
178
179
180struct GNUNET_TIME_Absolute
181GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
182{
183 struct GNUNET_TIME_Absolute ret;
184
185 if (rel.rel_value_us == UINT64_MAX)
186 return GNUNET_TIME_UNIT_FOREVER_ABS;
187 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
188
189 if (rel.rel_value_us + now.abs_value_us < rel.rel_value_us)
190 {
191 GNUNET_break (0); /* overflow... */
192 return GNUNET_TIME_UNIT_FOREVER_ABS;
193 }
194 ret.abs_value_us = rel.rel_value_us + now.abs_value_us;
195 return ret;
196}
197
198
199struct GNUNET_TIME_Relative
200GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
201 struct GNUNET_TIME_Relative t2)
202{
203 return (t1.rel_value_us < t2.rel_value_us) ? t1 : t2;
204}
205
206
207struct GNUNET_TIME_Relative
208GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
209 struct GNUNET_TIME_Relative t2)
210{
211 return (t1.rel_value_us > t2.rel_value_us) ? t1 : t2;
212}
213
214
215struct GNUNET_TIME_Absolute
216GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
217 struct GNUNET_TIME_Absolute t2)
218{
219 return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
220}
221
222
223struct GNUNET_TIME_Absolute
224GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
225 struct GNUNET_TIME_Absolute t2)
226{
227 return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
228}
229
230
231struct GNUNET_TIME_Relative
232GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
233{
234 struct GNUNET_TIME_Relative ret;
235
236 if (future.abs_value_us == UINT64_MAX)
237 return GNUNET_TIME_UNIT_FOREVER_REL;
238 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
239
240 if (now.abs_value_us > future.abs_value_us)
241 return GNUNET_TIME_UNIT_ZERO;
242 ret.rel_value_us = future.abs_value_us - now.abs_value_us;
243 return ret;
244}
245
246
247struct GNUNET_TIME_Relative
248GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
249 struct GNUNET_TIME_Absolute end)
250{
251 struct GNUNET_TIME_Relative ret;
252
253 if (end.abs_value_us == UINT64_MAX)
254 return GNUNET_TIME_UNIT_FOREVER_REL;
255 if (end.abs_value_us < start.abs_value_us)
256 return GNUNET_TIME_UNIT_ZERO;
257 ret.rel_value_us = end.abs_value_us - start.abs_value_us;
258 return ret;
259}
260
261
262struct GNUNET_TIME_Relative
263GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
264{
265 struct GNUNET_TIME_Absolute now;
266 struct GNUNET_TIME_Relative ret;
267
268 now = GNUNET_TIME_absolute_get ();
269 if (whence.abs_value_us > now.abs_value_us)
270 return GNUNET_TIME_UNIT_ZERO;
271 ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
272 return ret;
273}
274
275
276struct GNUNET_TIME_Absolute
277GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
278 struct GNUNET_TIME_Relative duration)
279{
280 struct GNUNET_TIME_Absolute ret;
281
282 if ((start.abs_value_us == UINT64_MAX) ||
283 (duration.rel_value_us == UINT64_MAX))
284 return GNUNET_TIME_UNIT_FOREVER_ABS;
285 if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
286 {
287 GNUNET_break (0);
288 return GNUNET_TIME_UNIT_FOREVER_ABS;
289 }
290 ret.abs_value_us = start.abs_value_us + duration.rel_value_us;
291 return ret;
292}
293
294
295struct GNUNET_TIME_Absolute
296GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
297 struct GNUNET_TIME_Relative duration)
298{
299 struct GNUNET_TIME_Absolute ret;
300
301 if (start.abs_value_us <= duration.rel_value_us)
302 return GNUNET_TIME_UNIT_ZERO_ABS;
303 if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
304 return GNUNET_TIME_UNIT_FOREVER_ABS;
305 ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
306 return ret;
307}
308
309
310struct GNUNET_TIME_Relative
311GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
312 unsigned long long factor)
313{
314 struct GNUNET_TIME_Relative ret;
315
316 if (0 == factor)
317 return GNUNET_TIME_UNIT_ZERO;
318 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
319 return GNUNET_TIME_UNIT_FOREVER_REL;
320 ret.rel_value_us = rel.rel_value_us * factor;
321 if (ret.rel_value_us / factor != rel.rel_value_us)
322 {
323 GNUNET_break (0);
324 return GNUNET_TIME_UNIT_FOREVER_REL;
325 }
326 return ret;
327}
328
329
330struct GNUNET_TIME_Relative
331relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor)
332{
333 struct GNUNET_TIME_Relative out;
334 double m;
335
336 GNUNET_assert (0 <= factor);
337
338 if (0 == factor)
339 return GNUNET_TIME_UNIT_ZERO;
340 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
341 return GNUNET_TIME_UNIT_FOREVER_REL;
342
343 m = ((double) rel.rel_value_us) * factor;
344
345 if (m >= (double) (GNUNET_TIME_UNIT_FOREVER_REL).rel_value_us)
346 {
347 GNUNET_break (0);
348 return GNUNET_TIME_UNIT_FOREVER_REL;
349 }
350
351 out.rel_value_us = (uint64_t) m;
352 return out;
353}
354
355
356struct GNUNET_TIME_Relative
357GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
358 unsigned long long factor)
359{
360 struct GNUNET_TIME_Relative ret;
361
362 if (0 == factor)
363 return GNUNET_TIME_UNIT_ZERO;
364 if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
365 return GNUNET_TIME_UNIT_FOREVER_REL;
366 ret.rel_value_us = rel.rel_value_us * factor;
367 if (ret.rel_value_us / factor != rel.rel_value_us)
368 {
369 return GNUNET_TIME_UNIT_FOREVER_REL;
370 }
371 return ret;
372}
373
374
375struct GNUNET_TIME_Relative
376GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
377 unsigned long long factor)
378{
379 struct GNUNET_TIME_Relative ret;
380
381 if ((0 == factor) ||
382 (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
383 return GNUNET_TIME_UNIT_FOREVER_REL;
384 ret.rel_value_us = rel.rel_value_us / factor;
385 return ret;
386}
387
388
389struct GNUNET_TIME_Relative
390GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
391 uint64_t finished,
392 uint64_t total)
393{
394 struct GNUNET_TIME_Relative due;
395 double exp;
396 struct GNUNET_TIME_Relative ret;
397
398 GNUNET_break (finished <= total);
399 if (finished >= total)
400 return GNUNET_TIME_UNIT_ZERO;
401 if (0 == finished)
402 return GNUNET_TIME_UNIT_FOREVER_REL;
403 due = GNUNET_TIME_absolute_get_duration (start);
404 exp = ((double) due.rel_value_us) * ((double) total) / ((double) finished);
405 ret.rel_value_us = ((uint64_t) exp) - due.rel_value_us;
406 return ret;
407}
408
409
410struct GNUNET_TIME_Relative
411GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
412 struct GNUNET_TIME_Relative a2)
413{
414 struct GNUNET_TIME_Relative ret;
415
416 if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
417 return GNUNET_TIME_UNIT_FOREVER_REL;
418 if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
419 {
420 GNUNET_break (0);
421 return GNUNET_TIME_UNIT_FOREVER_REL;
422 }
423 ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
424 return ret;
425}
426
427
428struct GNUNET_TIME_Relative
429GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
430 struct GNUNET_TIME_Relative a2)
431{
432 struct GNUNET_TIME_Relative ret;
433
434 if (a2.rel_value_us >= a1.rel_value_us)
435 return GNUNET_TIME_UNIT_ZERO;
436 if (a1.rel_value_us == UINT64_MAX)
437 return GNUNET_TIME_UNIT_FOREVER_REL;
438 ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
439 return ret;
440}
441
442
443struct GNUNET_TIME_RelativeNBO
444GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
445{
446 struct GNUNET_TIME_RelativeNBO ret;
447
448 ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
449 return ret;
450}
451
452
453struct GNUNET_TIME_Relative
454GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
455{
456 struct GNUNET_TIME_Relative ret;
457
458 ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
459 return ret;
460}
461
462
463struct GNUNET_TIME_AbsoluteNBO
464GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
465{
466 struct GNUNET_TIME_AbsoluteNBO ret;
467
468 ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
469 return ret;
470}
471
472
473bool
474GNUNET_TIME_absolute_is_never (struct GNUNET_TIME_Absolute abs)
475{
476 return GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == abs.abs_value_us;
477}
478
479
480bool
481GNUNET_TIME_relative_is_forever (struct GNUNET_TIME_Relative rel)
482{
483 return GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == rel.rel_value_us;
484}
485
486
487bool
488GNUNET_TIME_relative_is_zero (struct GNUNET_TIME_Relative rel)
489{
490 return 0 == rel.rel_value_us;
491}
492
493
494bool
495GNUNET_TIME_absolute_is_past (struct GNUNET_TIME_Absolute abs)
496{
497 struct GNUNET_TIME_Absolute now;
498
499 now = GNUNET_TIME_absolute_get ();
500 return abs.abs_value_us < now.abs_value_us;
501}
502
503
504bool
505GNUNET_TIME_absolute_is_future (struct GNUNET_TIME_Absolute abs)
506{
507 struct GNUNET_TIME_Absolute now;
508
509 now = GNUNET_TIME_absolute_get ();
510 return abs.abs_value_us > now.abs_value_us;
511}
512
513
514struct GNUNET_TIME_Absolute
515GNUNET_TIME_absolute_from_ms (uint64_t ms_after_epoch)
516{
517 struct GNUNET_TIME_Absolute ret;
518
519 ret.abs_value_us = GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us
520 * ms_after_epoch;
521 if (ret.abs_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us !=
522 ms_after_epoch)
523 ret = GNUNET_TIME_UNIT_FOREVER_ABS;
524 return ret;
525}
526
527
528struct GNUNET_TIME_Absolute
529GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch)
530{
531 struct GNUNET_TIME_Absolute ret;
532
533 ret.abs_value_us = GNUNET_TIME_UNIT_SECONDS.rel_value_us * s_after_epoch;
534 if (ret.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us !=
535 s_after_epoch)
536 ret = GNUNET_TIME_UNIT_FOREVER_ABS;
537 return ret;
538}
539
540
541struct GNUNET_TIME_Absolute
542GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
543{
544 struct GNUNET_TIME_Absolute ret;
545
546 ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
547 return ret;
548}
549
550
551unsigned int
552GNUNET_TIME_get_current_year ()
553{
554 time_t tp;
555 struct tm *t;
556
557 tp = time (NULL);
558 t = gmtime (&tp);
559 if (t == NULL)
560 return 0;
561 return t->tm_year + 1900;
562}
563
564
565unsigned int
566GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
567{
568 struct tm *t;
569 time_t tp;
570
571 tp = at.abs_value_us / 1000LL / 1000LL; /* microseconds to seconds */
572 t = gmtime (&tp);
573 if (t == NULL)
574 return 0;
575 return t->tm_year + 1900;
576}
577
578
579#ifndef HAVE_TIMEGM
580/**
581 * As suggested in the timegm() man page.
582 */
583static time_t
584my_timegm (struct tm *tm)
585{
586 time_t ret;
587 char *tz;
588
589 tz = getenv ("TZ");
590 setenv ("TZ", "", 1);
591 tzset ();
592 ret = mktime (tm);
593 if (tz)
594 setenv ("TZ", tz, 1);
595 else
596 unsetenv ("TZ");
597 tzset ();
598 return ret;
599}
600
601
602#endif
603
604
605struct GNUNET_TIME_Absolute
606GNUNET_TIME_year_to_time (unsigned int year)
607{
608 struct GNUNET_TIME_Absolute ret;
609 time_t tp;
610 struct tm t;
611
612 memset (&t, 0, sizeof(t));
613 if (year < 1900)
614 {
615 GNUNET_break (0);
616 return GNUNET_TIME_absolute_get (); /* now */
617 }
618 t.tm_year = year - 1900;
619 t.tm_mday = 1;
620 t.tm_mon = 0;
621 t.tm_wday = 1;
622 t.tm_yday = 1;
623#ifndef HAVE_TIMEGM
624 tp = my_timegm (&t);
625#else
626 tp = timegm (&t);
627#endif
628 GNUNET_break (tp != (time_t) -1);
629 ret.abs_value_us = tp * 1000LL * 1000LL; /* seconds to microseconds */
630 return ret;
631}
632
633
634struct GNUNET_TIME_Relative
635GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt,
636 struct GNUNET_TIME_Relative threshold)
637{
638 double r = (rand () % 500) / 1000.0;
639 struct GNUNET_TIME_Relative t;
640
641 t = relative_multiply_double (
642 GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, rt),
643 2 + r);
644 return GNUNET_TIME_relative_min (threshold, t);
645}
646
647
648struct GNUNET_TIME_Relative
649GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r)
650{
651 double d = ((rand () % 1001) + 500) / 1000.0;
652
653 return relative_multiply_double (r, d);
654}
655
656
657struct GNUNET_TIME_Absolute
658GNUNET_TIME_absolute_get_monotonic (
659 const struct GNUNET_CONFIGURATION_Handle *cfg)
660{
661 static const struct GNUNET_CONFIGURATION_Handle *last_cfg;
662 static struct GNUNET_TIME_Absolute last_time;
663 static struct GNUNET_DISK_MapHandle *map_handle;
664 static ATOMIC volatile uint64_t *map;
665 struct GNUNET_TIME_Absolute now;
666
667 now = GNUNET_TIME_absolute_get ();
668 if (last_cfg != cfg)
669 {
670 char *filename;
671
672 if (NULL != map_handle)
673 {
674 GNUNET_DISK_file_unmap (map_handle);
675 map_handle = NULL;
676 }
677 map = NULL;
678
679 last_cfg = cfg;
680 if ((NULL != cfg) &&
681 (GNUNET_OK ==
682 GNUNET_CONFIGURATION_get_value_filename (cfg,
683 "util",
684 "MONOTONIC_TIME_FILENAME",
685 &filename)))
686 {
687 struct GNUNET_DISK_FileHandle *fh;
688
689 fh = GNUNET_DISK_file_open (filename,
690 GNUNET_DISK_OPEN_READWRITE
691 | GNUNET_DISK_OPEN_CREATE,
692 GNUNET_DISK_PERM_USER_WRITE
693 | GNUNET_DISK_PERM_GROUP_WRITE
694 | GNUNET_DISK_PERM_USER_READ
695 | GNUNET_DISK_PERM_GROUP_READ);
696 if (NULL == fh)
697 {
698 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
699 _ ("Failed to map `%s', cannot assure monotonic time!\n"),
700 filename);
701 }
702 else
703 {
704 off_t size;
705
706 size = 0;
707 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &size));
708 if (size < (off_t) sizeof(*map))
709 {
710 struct GNUNET_TIME_AbsoluteNBO o;
711
712 o = GNUNET_TIME_absolute_hton (now);
713 if (sizeof(o) != GNUNET_DISK_file_write (fh, &o, sizeof(o)))
714 size = 0;
715 else
716 size = sizeof(o);
717 }
718 if (size == sizeof(*map))
719 {
720 map = GNUNET_DISK_file_map (fh,
721 &map_handle,
722 GNUNET_DISK_MAP_TYPE_READWRITE,
723 sizeof(*map));
724 if (NULL == map)
725 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
726 _ (
727 "Failed to map `%s', cannot assure monotonic time!\n"),
728 filename);
729 }
730 else
731 {
732 GNUNET_log (
733 GNUNET_ERROR_TYPE_WARNING,
734 _ (
735 "Failed to setup monotonic time file `%s', cannot assure monotonic time!\n"),
736 filename);
737 }
738 }
739 GNUNET_DISK_file_close (fh);
740 GNUNET_free (filename);
741 }
742 }
743 if (NULL != map)
744 {
745 struct GNUNET_TIME_AbsoluteNBO mt;
746
747#if __STDC_NO_ATOMICS__
748#if __GNUC__
749 mt.abs_value_us__ = __sync_fetch_and_or (map, 0);
750#else
751 mt.abs_value_us__ = *map; /* godspeed, pray this is atomic */
752#endif
753#else
754 mt.abs_value_us__ = atomic_load (map);
755#endif
756 last_time =
757 GNUNET_TIME_absolute_max (GNUNET_TIME_absolute_ntoh (mt), last_time);
758 }
759 if (now.abs_value_us <= last_time.abs_value_us)
760 now.abs_value_us = last_time.abs_value_us + 1;
761 last_time = now;
762 if (NULL != map)
763 {
764 uint64_t val = GNUNET_TIME_absolute_hton (now).abs_value_us__;
765#if __STDC_NO_ATOMICS__
766#if __GNUC__
767 (void) __sync_lock_test_and_set (map, val);
768#else
769 *map = val; /* godspeed, pray this is atomic */
770#endif
771#else
772 atomic_store (map, val);
773#endif
774 }
775 return now;
776}
777
778
779/**
780 * Destructor
781 */
782void __attribute__ ((destructor))
783GNUNET_util_time_fini ()
784{
785 (void) GNUNET_TIME_absolute_get_monotonic (NULL);
786}
787
788
789/* end of time.c */