-
Notifications
You must be signed in to change notification settings - Fork 30
/
timing_mach.h
133 lines (110 loc) · 3.72 KB
/
timing_mach.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef TIMING_MACH_H
#define TIMING_MACH_H
/* ************* */
/* TIMING_MACH_H */
/* C99 check */
#if defined(__STDC__)
# if defined(__STDC_VERSION__)
# if (__STDC_VERSION__ >= 199901L)
# define TIMING_C99
# endif
# endif
#endif
#include <time.h>
#define TIMING_GIGA (1000000000)
#define TIMING_NANO (1e-9)
/* inline functions - maintain ANSI C compatibility */
#ifndef TIMING_C99
/* this is a bad hack that makes the functions static in a header file.
Compiler warnings about unused functions will plague anyone using this code with ANSI C. */
#define inline static
#endif
/* timespec to double */
inline double timespec2secd(const struct timespec *ts_in) {
return ((double) ts_in->tv_sec) + ((double) ts_in->tv_nsec ) * TIMING_NANO;
}
/* double sec to timespec */
inline void secd2timespec(struct timespec *ts_out, const double sec_d) {
ts_out->tv_sec = (time_t) (sec_d);
ts_out->tv_nsec = (long) ((sec_d - (double) ts_out->tv_sec) * TIMING_GIGA);
}
/* timespec difference (monotonic) left - right */
inline void timespec_monodiff_lmr(struct timespec *ts_out,
const struct timespec *ts_in) {
/* out = out - in,
where out > in
*/
ts_out->tv_sec = ts_out->tv_sec - ts_in->tv_sec;
ts_out->tv_nsec = ts_out->tv_nsec - ts_in->tv_nsec;
if (ts_out->tv_nsec < 0) {
ts_out->tv_sec = ts_out->tv_sec - 1;
ts_out->tv_nsec = ts_out->tv_nsec + TIMING_GIGA;
}
}
/* timespec difference (monotonic) right - left */
inline void timespec_monodiff_rml(struct timespec *ts_out,
const struct timespec *ts_in) {
/* out = in - out,
where in > out
*/
ts_out->tv_sec = ts_in->tv_sec - ts_out->tv_sec;
ts_out->tv_nsec = ts_in->tv_nsec - ts_out->tv_nsec;
if (ts_out->tv_nsec < 0) {
ts_out->tv_sec = ts_out->tv_sec - 1;
ts_out->tv_nsec = ts_out->tv_nsec + TIMING_GIGA;
}
}
/* timespec addition (monotonic) */
inline void timespec_monoadd(struct timespec *ts_out,
const struct timespec *ts_in) {
/* out = in + out */
ts_out->tv_sec = ts_out->tv_sec + ts_in->tv_sec;
ts_out->tv_nsec = ts_out->tv_nsec + ts_in->tv_nsec;
if (ts_out->tv_nsec >= TIMING_GIGA) {
ts_out->tv_sec = ts_out->tv_sec + 1;
ts_out->tv_nsec = ts_out->tv_nsec - TIMING_GIGA;
}
}
#ifndef TIMING_C99
#undef inline
#endif
#ifdef __MACH__
/* ******** */
/* __MACH__ */
/* only CLOCK_REALTIME and CLOCK_MONOTONIC are emulated */
#ifndef CLOCK_REALTIME
# define CLOCK_REALTIME 0
#endif
#ifndef CLOCK_MONOTONIC
# define CLOCK_MONOTONIC 1
#endif
/* typdef POSIX clockid_t */
//typedef int clockid_t;
/* initialize mach timing */
int timing_mach_init (void);
/* clock_gettime - emulate POSIX */
int clock_gettime(const clockid_t id, struct timespec *tspec);
/* clock_nanosleep for CLOCK_MONOTONIC and TIMER_ABSTIME */
int clock_nanosleep_abstime(const struct timespec *req);
/* __MACH__ */
/* ******** */
#else
/* ***** */
/* POSIX */
/* clock_nanosleep for CLOCK_MONOTONIC and TIMER_ABSTIME */
# define clock_nanosleep_abstime(req) \
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, (req), NULL)
/* POSIX */
/* ***** */
#endif
/* timer functions that make use of clock_nanosleep_abstime
For POSIX systems, it is recommended to use POSIX timers and signals.
For Mac OSX (mach), there are no POSIX timers so these functions are very helpful.
*/
/* Sets absolute time ts_target to ts_step after current time */
int itimer_start (struct timespec *ts_target, const struct timespec *ts_step);
/* Nanosleeps to ts_target then adds ts_step to ts_target for next iteration */
int itimer_step (struct timespec *ts_target, const struct timespec *ts_step);
/* TIMING_MACH_H */
/* ************* */
#endif