1 /* Licensed under BSD-MIT - see LICENSE file for details */
2 #include <ccan/time/time.h>
6 #if !HAVE_CLOCK_GETTIME
9 struct timeabs time_now(void)
13 gettimeofday(&now, NULL);
14 ret.ts.tv_sec = now.tv_sec;
15 ret.ts.tv_nsec = now.tv_usec * 1000;
16 return TIMEABS_CHECK(ret);
20 struct timeabs time_now(void)
23 clock_gettime(CLOCK_REALTIME, &ret.ts);
24 return TIMEABS_CHECK(ret);
26 #endif /* HAVE_CLOCK_GETTIME */
28 struct timemono time_mono(void)
31 #ifdef TIME_HAVE_MONOTONIC
32 clock_gettime(CLOCK_MONOTONIC, &ret.ts);
33 #else /* Best we can do */
34 ret.ts = time_now().ts;
35 #endif /* !HAVE_TIME_MONOTONIC */
39 struct timerel time_divide(struct timerel t, unsigned long div)
44 /* Dividing seconds is simple. */
45 res.ts.tv_sec = TIMEREL_CHECK(t).ts.tv_sec / div;
46 rem = t.ts.tv_sec % div;
48 /* If we can't fit remainder * 1,000,000,000 in 64 bits? */
49 #if 0 /* ilog is great, but we use fp for multiply anyway. */
51 if (bits + 30 >= 64) {
52 /* Reduce accuracy slightly */
53 rem >>= (bits - (64 - 30));
54 div >>= (bits - (64 - 30));
57 if (rem & ~(((uint64_t)1 << 30) - 1)) {
58 /* FIXME: fp is cheating! */
59 double nsec = rem * 1000000000.0 + t.ts.tv_nsec;
60 res.ts.tv_nsec = nsec / div;
62 ns = rem * 1000000000 + t.ts.tv_nsec;
63 res.ts.tv_nsec = ns / div;
65 return TIMEREL_CHECK(res);
68 struct timerel time_multiply(struct timerel t, unsigned long mult)
72 /* Are we going to overflow if we multiply nsec? */
73 if (mult & ~((1UL << 30) - 1)) {
74 /* FIXME: fp is cheating! */
75 double nsec = (double)t.ts.tv_nsec * mult;
77 res.ts.tv_sec = nsec / 1000000000.0;
78 res.ts.tv_nsec = nsec - (res.ts.tv_sec * 1000000000.0);
80 uint64_t nsec = t.ts.tv_nsec * mult;
82 res.ts.tv_nsec = nsec % 1000000000;
83 res.ts.tv_sec = nsec / 1000000000;
85 res.ts.tv_sec += TIMEREL_CHECK(t).ts.tv_sec * mult;
86 return TIMEREL_CHECK(res);
89 struct timespec time_check_(struct timespec t, const char *abortstr)
91 if (t.tv_sec < 0 || t.tv_nsec >= 1000000000) {
93 fprintf(stderr, "%s: malformed time %li.%09li\n",
95 (long)t.tv_sec, (long)t.tv_nsec);
98 struct timespec old = t;
100 if (t.tv_nsec >= 1000000000) {
101 t.tv_sec += t.tv_nsec / 1000000000;
102 t.tv_nsec %= 1000000000;
107 fprintf(stderr, "WARNING: malformed time"
108 " %li seconds %li ns converted to %li.%09li.\n",
109 (long)old.tv_sec, (long)old.tv_nsec,
110 (long)t.tv_sec, (long)t.tv_nsec);
116 struct timerel timerel_check(struct timerel t, const char *abortstr)
120 ret.ts = time_check_(t.ts, abortstr);
124 struct timeabs timeabs_check(struct timeabs t, const char *abortstr)
128 ret.ts = time_check_(t.ts, abortstr);