• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24  /*
25 
26    Timer - struct timespec conversion runtimes and easy to use functions to
27            measure elapsed time.
28 
29   */
30 
31 #ifndef TST_TIMER
32 #define TST_TIMER
33 
34 #include <sys/time.h>
35 #include <time.h>
36 
37 /*
38  * Converts timespec to microseconds.
39  */
tst_timespec_to_us(struct timespec t)40 static inline long long tst_timespec_to_us(struct timespec t)
41 {
42 	return t.tv_sec * 1000000 + (t.tv_nsec + 500) / 1000;
43 }
44 
45 /*
46  * Converts timespec to miliseconds.
47  */
tst_timespec_to_ms(struct timespec t)48 static inline long long tst_timespec_to_ms(struct timespec t)
49 {
50 	return t.tv_sec * 1000 + (t.tv_nsec + 500000) / 1000000;
51 }
52 
53 /*
54  * Converts timeval to microseconds.
55  */
tst_timeval_to_us(struct timeval t)56 static inline long long tst_timeval_to_us(struct timeval t)
57 {
58 	return t.tv_sec * 1000000 + t.tv_usec;
59 }
60 
61 /*
62  * Converts timeval to miliseconds.
63  */
tst_timeval_to_ms(struct timeval t)64 static inline long long tst_timeval_to_ms(struct timeval t)
65 {
66 	return t.tv_sec * 1000 + (t.tv_usec + 500) / 1000;
67 }
68 
69 /*
70  * Converts ms to struct timeval
71  */
tst_ms_to_timeval(long long ms)72 static inline struct timeval tst_ms_to_timeval(long long ms)
73 {
74 	struct timeval ret;
75 
76 	ret.tv_sec = ms / 1000;
77 	ret.tv_usec = (ms % 1000) * 1000;
78 
79 	return ret;
80 }
81 
82 /*
83  * Converts us to struct timeval
84  */
tst_us_to_timeval(long long us)85 static inline struct timeval tst_us_to_timeval(long long us)
86 {
87 	struct timeval ret;
88 
89 	ret.tv_sec = us / 1000000;
90 	ret.tv_usec = us % 1000000;
91 
92 	return ret;
93 }
94 
95 /*
96  * Converts ms to struct timespec
97  */
tst_ms_to_timespec(long long ms)98 static inline struct timespec tst_ms_to_timespec(long long ms)
99 {
100 	struct timespec ret;
101 
102 	ret.tv_sec = ms / 1000;
103 	ret.tv_nsec = (ms % 1000) * 1000000;
104 
105 	return ret;
106 }
107 
108 /*
109  * Converts us to struct timespec
110  */
tst_us_to_timespec(long long us)111 static inline struct timespec tst_us_to_timespec(long long us)
112 {
113 	struct timespec ret;
114 
115 	ret.tv_sec = us / 1000000;
116 	ret.tv_nsec = (us % 1000000) * 1000;
117 
118 	return ret;
119 }
120 
121 /*
122  * Comparsions
123  */
tst_timespec_lt(struct timespec t1,struct timespec t2)124 static inline int tst_timespec_lt(struct timespec t1, struct timespec t2)
125 {
126 	if (t1.tv_sec == t2.tv_sec)
127 		return t1.tv_nsec < t2.tv_nsec;
128 
129 	return t1.tv_sec < t2.tv_sec;
130 }
131 
132 /*
133  * Adds us microseconds to t.
134  */
tst_timespec_add_us(struct timespec t,long long us)135 static inline struct timespec tst_timespec_add_us(struct timespec t,
136                                                   long long us)
137 {
138 	t.tv_sec += us / 1000000;
139 	t.tv_nsec += (us % 1000000) * 1000;
140 
141 	if (t.tv_nsec >= 1000000000) {
142 		t.tv_sec++;
143 		t.tv_nsec -= 1000000000;
144 	}
145 
146 	return t;
147 }
148 
149 /*
150  * Returns difference between two timespec structures.
151  */
tst_timespec_diff(struct timespec t1,struct timespec t2)152 static inline struct timespec tst_timespec_diff(struct timespec t1,
153                                                 struct timespec t2)
154 {
155 	struct timespec res;
156 
157 	res.tv_sec = t1.tv_sec - t2.tv_sec;
158 
159 	if (t1.tv_nsec < t2.tv_nsec) {
160 		res.tv_sec--;
161 		res.tv_nsec = 1000000000 - (t2.tv_nsec - t1.tv_nsec);
162 	} else {
163 		res.tv_nsec = t1.tv_nsec - t2.tv_nsec;
164 	}
165 
166 	return res;
167 }
168 
tst_timespec_diff_us(struct timespec t1,struct timespec t2)169 static inline long long tst_timespec_diff_us(struct timespec t1,
170                                              struct timespec t2)
171 {
172 	return tst_timespec_to_us(tst_timespec_diff(t1, t2));
173 }
174 
tst_timespec_diff_ms(struct timespec t1,struct timespec t2)175 static inline long long tst_timespec_diff_ms(struct timespec t1,
176                                              struct timespec t2)
177 {
178 	return tst_timespec_to_ms(tst_timespec_diff(t1, t2));
179 }
180 
181 /*
182  * Returns difference between two timeval structures.
183  */
tst_timeval_diff(struct timeval t1,struct timeval t2)184 static inline struct timeval tst_timeval_diff(struct timeval t1,
185                                               struct timeval t2)
186 {
187 	struct timeval res;
188 
189 	res.tv_sec = t1.tv_sec - t2.tv_sec;
190 
191 	if (t1.tv_usec < t2.tv_usec) {
192 		res.tv_sec--;
193 		res.tv_usec = 1000000 - (t2.tv_usec - t1.tv_usec);
194 	} else {
195 		res.tv_usec = t1.tv_usec - t2.tv_usec;
196 	}
197 
198 	return res;
199 }
200 
tst_timeval_diff_us(struct timeval t1,struct timeval t2)201 static inline long long tst_timeval_diff_us(struct timeval t1,
202                                             struct timeval t2)
203 {
204 	return tst_timeval_to_us(tst_timeval_diff(t1, t2));
205 }
206 
tst_timeval_diff_ms(struct timeval t1,struct timeval t2)207 static inline long long tst_timeval_diff_ms(struct timeval t1,
208                                             struct timeval t2)
209 {
210 	return tst_timeval_to_ms(tst_timeval_diff(t1, t2));
211 }
212 
213 /*
214  * Returns absolute value of difference between two timespec structures.
215  */
tst_timespec_abs_diff(struct timespec t1,struct timespec t2)216 static inline struct timespec tst_timespec_abs_diff(struct timespec t1,
217                                                     struct timespec t2)
218 {
219 	if (tst_timespec_lt(t1, t2))
220 		return tst_timespec_diff(t2, t1);
221 	else
222 		return tst_timespec_diff(t1, t2);
223 }
224 
tst_timespec_abs_diff_us(struct timespec t1,struct timespec t2)225 static inline long long tst_timespec_abs_diff_us(struct timespec t1,
226                                                  struct timespec t2)
227 {
228        return tst_timespec_to_us(tst_timespec_abs_diff(t1, t2));
229 }
230 
tst_timespec_abs_diff_ms(struct timespec t1,struct timespec t2)231 static inline long long tst_timespec_abs_diff_ms(struct timespec t1,
232                                                  struct timespec t2)
233 {
234        return tst_timespec_to_ms(tst_timespec_abs_diff(t1, t2));
235 }
236 
237 /*
238  * Exits the test with TCONF if particular timer is not supported. This is
239  * intended to be used in test setup. There is no cleanup callback parameter as
240  * you are expected to call it before initializing any resources that has to be
241  * cleaned up later.
242  *
243  * @clk_id: Posix clock to use.
244  */
245 void tst_timer_check(clockid_t clk_id);
246 
247 /*
248  * Marks a start time for given clock type.
249  *
250  * @clk_id: Posix clock to use.
251  */
252 void tst_timer_start(clockid_t clk_id);
253 
254 /*
255  * Marks timer end time.
256  */
257 void tst_timer_stop(void);
258 
259 /*
260  * Retuns elapsed time in struct timespec.
261  */
262 struct timespec tst_timer_elapsed(void);
263 
264 /*
265  * Returns elapsed time in miliseconds.
266  */
tst_timer_elapsed_ms(void)267 static inline long long tst_timer_elapsed_ms(void)
268 {
269 	return tst_timespec_to_ms(tst_timer_elapsed());
270 }
271 
272 /*
273  * Returns elapsed time in microseconds.
274  */
tst_timer_elapsed_us(void)275 static inline long long tst_timer_elapsed_us(void)
276 {
277 	return tst_timespec_to_us(tst_timer_elapsed());
278 }
279 
280 #endif /* TST_TIMER */
281