libspades
Ace of Spades library
clock.h
1#ifndef LIBSPADES_CLOCK_H
2#define LIBSPADES_CLOCK_H
3#ifdef __cplusplus
4extern "C" {
5#endif
6
7#if defined(__unix__) || defined(__unix)
8#define LIBSPADES_POSIX 1
9#endif
10
11#define LIBSPADES_SECONDS 1
12#define LIBSPADES_MILLISECONDS 1000
13#define LIBSPADES_MICROSECONDS 1000000
14#define LIBSPADES_NANOSECONDS 1000000000
15
16#ifdef LIBSPADES_POSIX
17#if (_POSIX_C_SOURCE < 199309L)
18#undef _POSIX_C_SOURCE /* this might be illegal but whatever */
19#endif
20
21#if !defined(_POSIX_C_SOURCE)
22#define _POSIX_C_SOURCE 199309L
23#endif
24
25#include <unistd.h>
26
27#if defined(_POSIX_TIMERS) && ((_POSIX_TIMERS > 0) || defined(__OpenBSD__))
28/* Use clock_gettime if supported. */
29#define LIBSPADES_CLOCK_UNIT LIBSPADES_NANOSECONDS
30#else
31/* Use gettimeofday if clock_gettime is unsupported. */
32#define LIBSPADES_CLOCK_UNIT LIBSPADES_MICROSECONDS
33#endif /* defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) */
34
35#else /* LIBSPADES_POSIX */
36/* Fall back to ENet's implementation. */
37#define LIBSPADES_CLOCK_UNIT LIBSPADES_MILLISECONDS
38#endif /* LIBSPADES_POSIX */
39
40#include "datatypes.h"
41
42/* "Why not just put it into one group of macros?" I hear someone ask.
43 * The answer is: this is the only way I know of to guarantee that the integer isn't ruined by multiplying out of
44 * range or dividing away important digits. */
45#if (LIBSPADES_CLOCK_UNIT == LIBSPADES_SECONDS)
46#define LIBSPADES_SECONDS_TO_CLOCK_UNIT(s) ((uint64_t)(s))
47#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT(ms) ((uint64_t)(ms) / 1000)
48#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT(us) ((uint64_t)(us) / 1000000)
49#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT(ns) ((uint64_t)(ns) / 1000000000)
50
51#define LIBSPADES_SECONDS_TO_CLOCK_UNIT_DOUBLE(s) ((uint64_t)((double)(s)))
52#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT_DOUBLE(ms) ((uint64_t)((double)(ms) / 1000))
53#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT_DOUBLE(us) ((uint64_t)((double)(us) / 1000000))
54#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT_DOUBLE(ns) ((uint64_t)((double)(ns) / 1000000000))
55
56#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_FLOAT(c) ((float)(c))
57#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_FLOAT(c) ((float)((c) * 1000))
58#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_FLOAT(c) ((float)((c) * 1000000))
59#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_FLOAT(c) ((float)((c) * 1000000000))
60
61#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_DOUBLE(c) ((double)(c))
62#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_DOUBLE(c) ((double)((c) * 1000))
63#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_DOUBLE(c) ((double)((c) * 1000000))
64#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_DOUBLE(c) ((double)((c) * 1000000000))
65
66#define LIBSPADES_CLOCK_UNIT_TO_SECONDS(c) ((uint64_t)(c))
67#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS(c) ((uint64_t)((c) * 1000))
68#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS(c) ((uint64_t)((c) * 1000000))
69#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS(c) ((uint64_t)((c) * 1000000000))
70#endif
71
72#if (LIBSPADES_CLOCK_UNIT == LIBSPADES_MILLISECONDS)
73#define LIBSPADES_SECONDS_TO_CLOCK_UNIT(s) ((uint64_t)(s) * 1000)
74#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT(ms) ((uint64_t)(ms))
75#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT(us) ((uint64_t)(us) / 1000)
76#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT(ns) ((uint64_t)(ns) / 1000000)
77
78#define LIBSPADES_SECONDS_TO_CLOCK_UNIT_DOUBLE(s) ((uint64_t)((double)(s) * 1000))
79#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT_DOUBLE(ms) ((uint64_t)((double)(ms)))
80#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT_DOUBLE(us) ((uint64_t)((double)(us) / 1000))
81#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT_DOUBLE(ns) ((uint64_t)((double)(ns) / 1000000))
82
83#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_FLOAT(c) ((float)(c) / 1000)
84#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_FLOAT(c) ((float)(c))
85#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_FLOAT(c) ((float)((c) * 1000))
86#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_FLOAT(c) ((float)((c) * 1000000))
87
88#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_DOUBLE(c) ((double)(c) / 1000)
89#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_DOUBLE(c) ((double)(c))
90#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_DOUBLE(c) ((double)((c) * 1000))
91#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_DOUBLE(c) ((double)((c) * 1000000))
92
93#define LIBSPADES_CLOCK_UNIT_TO_SECONDS(c) ((uint64_t)(c) / 1000)
94#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS(c) ((uint64_t)(c))
95#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS(c) ((uint64_t)((c) * 1000))
96#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS(c) ((uint64_t)((c) * 1000000))
97#endif
98
99#if (LIBSPADES_CLOCK_UNIT == LIBSPADES_MICROSECONDS)
100#define LIBSPADES_SECONDS_TO_CLOCK_UNIT(s) ((uint64_t)(s) * 1000000)
101#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT(ms) ((uint64_t)(ms) * 1000)
102#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT(us) ((uint64_t)(us))
103#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT(ns) ((uint64_t)(ns) / 1000)
104
105#define LIBSPADES_SECONDS_TO_CLOCK_UNIT_DOUBLE(s) ((uint64_t)((double)(s) * 1000000))
106#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT_DOUBLE(ms) ((uint64_t)((double)(ms) * 1000))
107#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT_DOUBLE(us) ((uint64_t)((double)(us)))
108#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT_DOUBLE(ns) ((uint64_t)((double)(ns) / 1000))
109
110#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_FLOAT(c) ((float)(c) / 1000000)
111#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_FLOAT(c) ((float)(c) / 1000)
112#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_FLOAT(c) ((float)(c))
113#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_FLOAT(c) ((float)((c) * 1000))
114
115#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_DOUBLE(c) ((double)(c) / 1000000)
116#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_DOUBLE(c) ((double)(c) / 1000)
117#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_DOUBLE(c) ((double)(c))
118#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_DOUBLE(c) ((double)((c) * 1000))
119
120#define LIBSPADES_CLOCK_UNIT_TO_SECONDS(c) ((uint64_t)(c) / 1000000)
121#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS(c) ((uint64_t)(c) / 1000)
122#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS(c) ((uint64_t)(c))
123#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS(c) ((uint64_t)((c) * 1000))
124#endif
125
126#if (LIBSPADES_CLOCK_UNIT == LIBSPADES_NANOSECONDS)
127#define LIBSPADES_SECONDS_TO_CLOCK_UNIT(s) ((uint64_t)(s) * 1000000000)
128#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT(ms) ((uint64_t)(ms) * 1000000)
129#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT(us) ((uint64_t)(us) * 1000)
130#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT(ns) ((uint64_t)(ns))
131
132#define LIBSPADES_SECONDS_TO_CLOCK_UNIT_DOUBLE(s) ((uint64_t)((double)(s) * 1000000000))
133#define LIBSPADES_MILLISECONDS_TO_CLOCK_UNIT_DOUBLE(ms) ((uint64_t)((double)(ms) * 1000000))
134#define LIBSPADES_MICROSECONDS_TO_CLOCK_UNIT_DOUBLE(us) ((uint64_t)((double)(us) * 1000))
135#define LIBSPADES_NANOSECONDS_TO_CLOCK_UNIT_DOUBLE(ns) ((uint64_t)((double)(ns)))
136
137#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_FLOAT(c) ((float)(c) / 1000000000)
138#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_FLOAT(c) ((float)(c) / 1000000)
139#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_FLOAT(c) ((float)(c) / 1000)
140#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_FLOAT(c) ((float)(c))
141
142#define LIBSPADES_CLOCK_UNIT_TO_SECONDS_DOUBLE(c) ((double)(c) / 1000000000)
143#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS_DOUBLE(c) ((double)(c) / 1000000)
144#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS_DOUBLE(c) ((double)(c) / 1000)
145#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS_DOUBLE(c) ((double)(c))
146
147#define LIBSPADES_CLOCK_UNIT_TO_SECONDS(c) ((uint64_t)(c) / 1000000000)
148#define LIBSPADES_CLOCK_UNIT_TO_MILLISECONDS(c) ((uint64_t)(c) / 1000000)
149#define LIBSPADES_CLOCK_UNIT_TO_MICROSECONDS(c) ((uint64_t)(c) / 1000)
150#define LIBSPADES_CLOCK_UNIT_TO_NANOSECONDS(c) ((uint64_t)(c))
151#endif
152
153uint64_t libspades_get_clock(void);
154
155#ifdef __cplusplus
156}
157#endif
158#endif