Merge branch 'master' of git.distorted.org.uk:~mdw/publish/public-git/disorder
[disorder] / lib / timeval.h
1 /*
2 * This file is part of DisOrder.
3 * Copyright (C) 2007-2009, 2013 Richard Kettlewell
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 /** @file lib/timeval.h
19 * @brief Arithmetic on timeval structures
20 */
21 #ifndef TIMEVAL_H
22 #define TIMEVAL_H
23
24 #include <time.h>
25 #include <sys/time.h>
26 #include <math.h>
27
28 static inline struct timeval tvsub(const struct timeval a,
29 const struct timeval b) {
30 struct timeval r;
31
32 r.tv_sec = a.tv_sec - b.tv_sec;
33 r.tv_usec = a.tv_usec - b.tv_usec;
34 if(r.tv_usec < 0) {
35 r.tv_usec += 1000000;
36 r.tv_sec--;
37 }
38 if(r.tv_usec > 999999) {
39 r.tv_usec -= 1000000;
40 r.tv_sec++;
41 }
42 return r;
43 }
44
45 static inline struct timeval tvadd(const struct timeval a,
46 const struct timeval b) {
47 struct timeval r;
48
49 r.tv_sec = a.tv_sec + b.tv_sec;
50 r.tv_usec = a.tv_usec + b.tv_usec;
51 if(r.tv_usec < 0) {
52 r.tv_usec += 1000000;
53 r.tv_sec--;
54 }
55 if(r.tv_usec > 999999) {
56 r.tv_usec -= 1000000;
57 r.tv_sec++;
58 }
59 return r;
60 }
61
62 static inline double tvdouble(const struct timeval a) {
63 return a.tv_sec + a.tv_usec / 1000000.0;
64 }
65
66 static inline int64_t tvsub_us(const struct timeval a,
67 const struct timeval b) {
68 return (((uint64_t)a.tv_sec * 1000000 + a.tv_usec)
69 - ((uint64_t)b.tv_sec * 1000000 + b.tv_usec));
70 }
71
72 /** @brief Great-than comparison for timevals */
73 static inline int tvgt(const struct timeval *a, const struct timeval *b) {
74 if(a->tv_sec > b->tv_sec)
75 return 1;
76 if(a->tv_sec == b->tv_sec
77 && a->tv_usec > b->tv_usec)
78 return 1;
79 return 0;
80 }
81
82 /** @brief Less-than
83 comparison for timevals */
84 static inline int tvlt(const struct timeval *a, const struct timeval *b) {
85 if(a->tv_sec < b->tv_sec)
86 return 1;
87 if(a->tv_sec == b->tv_sec
88 && a->tv_usec < b->tv_usec)
89 return 1;
90 return 0;
91 }
92
93 /** @brief Greater-than-or-equal comparison for timevals */
94 static inline int tvge(const struct timeval *a, const struct timeval *b) {
95 return !tvlt(a, b);
96 }
97
98 /** @brief Less-than-or-equal comparison for timevals */
99 static inline int tvle(const struct timeval *a, const struct timeval *b) {
100 return !tvgt(a, b);
101 }
102
103 /** @brief Return the sum of two timespecs */
104 static inline struct timespec tsadd(const struct timespec a,
105 const struct timespec b) {
106 struct timespec r;
107
108 r.tv_sec = a.tv_sec + b.tv_sec;
109 r.tv_nsec = a.tv_nsec + b.tv_nsec;
110 if(r.tv_nsec < 0) {
111 r.tv_nsec += 1000000;
112 r.tv_sec--;
113 }
114 if(r.tv_nsec > 999999) {
115 r.tv_nsec -= 1000000;
116 r.tv_sec++;
117 }
118 return r;
119 }
120
121 /** @brief Subtract one timespec from another */
122 static inline struct timespec tssub(const struct timespec a,
123 const struct timespec b) {
124 struct timespec r;
125
126 r.tv_sec = a.tv_sec - b.tv_sec;
127 r.tv_nsec = a.tv_nsec - b.tv_nsec;
128 if(r.tv_nsec < 0) {
129 r.tv_nsec += 1000000;
130 r.tv_sec--;
131 }
132 if(r.tv_nsec > 999999) {
133 r.tv_nsec -= 1000000;
134 r.tv_sec++;
135 }
136 return r;
137 }
138
139 /** @brief Convert a timespec to a double */
140 static inline double ts_to_double(const struct timespec ts) {
141 return ts.tv_sec + ts.tv_nsec / 1000000000.0;
142 }
143
144 /** @brief Convert a double to a timespec */
145 static inline struct timespec double_to_ts(double n) {
146 double i, f;
147 struct timespec r;
148 f = modf(n, &i);
149 r.tv_sec = i;
150 r.tv_nsec = 1000000000 * f;
151 return r;
152 }
153
154 #endif /* TIMEVAL_H */
155
156 /*
157 Local Variables:
158 c-basic-offset:2
159 comment-column:40
160 fill-column:79
161 indent-tabs-mode:nil
162 End:
163 */