• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright (C) 2015-2020 Cyril Hrubis <chrubis@suse.cz>
3  */
4 
5  /*
6 
7    Timer - struct timespec conversion runtimes and easy to use functions to
8            measure elapsed time.
9 
10   */
11 
12 #ifndef TST_TIMER
13 #define TST_TIMER
14 
15 #include <sys/time.h>
16 #include <time.h>
17 #include "tst_test.h"
18 #include "lapi/syscalls.h"
19 
20 /*
21  * Converts timeval to microseconds.
22  */
tst_timeval_to_us(struct timeval t)23 static inline long long tst_timeval_to_us(struct timeval t)
24 {
25 	return t.tv_sec * 1000000 + t.tv_usec;
26 }
27 
28 /*
29  * Converts timeval to milliseconds.
30  */
tst_timeval_to_ms(struct timeval t)31 static inline long long tst_timeval_to_ms(struct timeval t)
32 {
33 	return t.tv_sec * 1000 + (t.tv_usec + 500) / 1000;
34 }
35 
36 /*
37  * Converts milliseconds to struct timeval
38  */
tst_ms_to_timeval(long long ms)39 static inline struct timeval tst_ms_to_timeval(long long ms)
40 {
41 	struct timeval ret;
42 
43 	ret.tv_sec = ms / 1000;
44 	ret.tv_usec = (ms % 1000) * 1000;
45 
46 	return ret;
47 }
48 
49 /*
50  * Converts microseconds to struct timeval
51  */
tst_us_to_timeval(long long us)52 static inline struct timeval tst_us_to_timeval(long long us)
53 {
54 	struct timeval ret;
55 
56 	ret.tv_sec = us / 1000000;
57 	ret.tv_usec = us % 1000000;
58 
59 	return ret;
60 }
61 
62 /*
63  * Returns difference between two timeval structures.
64  */
tst_timeval_diff(struct timeval t1,struct timeval t2)65 static inline struct timeval tst_timeval_diff(struct timeval t1,
66                                               struct timeval t2)
67 {
68 	struct timeval res;
69 
70 	res.tv_sec = t1.tv_sec - t2.tv_sec;
71 
72 	if (t1.tv_usec < t2.tv_usec) {
73 		res.tv_sec--;
74 		res.tv_usec = 1000000 - (t2.tv_usec - t1.tv_usec);
75 	} else {
76 		res.tv_usec = t1.tv_usec - t2.tv_usec;
77 	}
78 
79 	return res;
80 }
81 
tst_timeval_diff_us(struct timeval t1,struct timeval t2)82 static inline long long tst_timeval_diff_us(struct timeval t1,
83                                             struct timeval t2)
84 {
85 	return tst_timeval_to_us(tst_timeval_diff(t1, t2));
86 }
87 
tst_timeval_diff_ms(struct timeval t1,struct timeval t2)88 static inline long long tst_timeval_diff_ms(struct timeval t1,
89                                             struct timeval t2)
90 {
91 	return tst_timeval_to_ms(tst_timeval_diff(t1, t2));
92 }
93 
94 #ifndef __kernel_timespec
95 
96 #if defined(__x86_64__) && defined(__ILP32__)
97 typedef long long __kernel_long_t;
98 #else
99 typedef long __kernel_long_t;
100 #endif
101 
102 typedef __kernel_long_t	__kernel_old_time_t;
103 
104 struct __kernel_old_timespec {
105 	__kernel_old_time_t	tv_sec;		/* seconds */
106 	__kernel_old_time_t	tv_nsec;	/* nanoseconds */
107 };
108 
109 typedef long long __kernel_time64_t;
110 
111 struct __kernel_timespec {
112 	__kernel_time64_t       tv_sec;                 /* seconds */
113 	long long               tv_nsec;                /* nanoseconds */
114 };
115 #endif
116 
117 enum tst_ts_type {
118 	TST_LIBC_TIMESPEC,
119 	TST_KERN_OLD_TIMESPEC,
120 	TST_KERN_TIMESPEC
121 };
122 
123 struct tst_ts {
124 	enum tst_ts_type type;
125 	union ts {
126 		struct timespec libc_ts;
127 		struct __kernel_old_timespec kern_old_ts;
128 		struct __kernel_timespec kern_ts;
129 	} ts;
130 };
131 
tst_ts_get(struct tst_ts * t)132 static inline void *tst_ts_get(struct tst_ts *t)
133 {
134 	if (!t)
135 		return NULL;
136 
137 	switch (t->type) {
138 	case TST_LIBC_TIMESPEC:
139 		return &t->ts.libc_ts;
140 	case TST_KERN_OLD_TIMESPEC:
141 		return &t->ts.kern_old_ts;
142 	case TST_KERN_TIMESPEC:
143 		return &t->ts.kern_ts;
144 	default:
145 		tst_brk(TBROK, "Invalid type: %d", t->type);
146 		return NULL;
147 	}
148 }
149 
libc_clock_getres(clockid_t clk_id,void * ts)150 static inline int libc_clock_getres(clockid_t clk_id, void *ts)
151 {
152 	return clock_getres(clk_id, ts);
153 }
154 
sys_clock_getres(clockid_t clk_id,void * ts)155 static inline int sys_clock_getres(clockid_t clk_id, void *ts)
156 {
157 	return tst_syscall(__NR_clock_getres, clk_id, ts);
158 }
159 
sys_clock_getres64(clockid_t clk_id,void * ts)160 static inline int sys_clock_getres64(clockid_t clk_id, void *ts)
161 {
162 	return tst_syscall(__NR_clock_getres_time64, clk_id, ts);
163 }
164 
libc_clock_gettime(clockid_t clk_id,void * ts)165 static inline int libc_clock_gettime(clockid_t clk_id, void *ts)
166 {
167 	return clock_gettime(clk_id, ts);
168 }
169 
sys_clock_gettime(clockid_t clk_id,void * ts)170 static inline int sys_clock_gettime(clockid_t clk_id, void *ts)
171 {
172 	return tst_syscall(__NR_clock_gettime, clk_id, ts);
173 }
174 
sys_clock_gettime64(clockid_t clk_id,void * ts)175 static inline int sys_clock_gettime64(clockid_t clk_id, void *ts)
176 {
177 	return tst_syscall(__NR_clock_gettime64, clk_id, ts);
178 }
179 
libc_clock_settime(clockid_t clk_id,void * ts)180 static inline int libc_clock_settime(clockid_t clk_id, void *ts)
181 {
182 	return clock_settime(clk_id, ts);
183 }
184 
sys_clock_settime(clockid_t clk_id,void * ts)185 static inline int sys_clock_settime(clockid_t clk_id, void *ts)
186 {
187 	return tst_syscall(__NR_clock_settime, clk_id, ts);
188 }
189 
sys_clock_settime64(clockid_t clk_id,void * ts)190 static inline int sys_clock_settime64(clockid_t clk_id, void *ts)
191 {
192 	return tst_syscall(__NR_clock_settime64, clk_id, ts);
193 }
194 
libc_clock_nanosleep(clockid_t clk_id,int flags,void * request,void * remain)195 static inline int libc_clock_nanosleep(clockid_t clk_id, int flags,
196 				       void *request, void *remain)
197 {
198 	return clock_nanosleep(clk_id, flags, request, remain);
199 }
200 
sys_clock_nanosleep(clockid_t clk_id,int flags,void * request,void * remain)201 static inline int sys_clock_nanosleep(clockid_t clk_id, int flags,
202 				      void *request, void *remain)
203 {
204 	return tst_syscall(__NR_clock_nanosleep, clk_id, flags,
205 			   request, remain);
206 }
207 
sys_clock_nanosleep64(clockid_t clk_id,int flags,void * request,void * remain)208 static inline int sys_clock_nanosleep64(clockid_t clk_id, int flags,
209 				        void *request, void *remain)
210 {
211 	return tst_syscall(__NR_clock_nanosleep_time64, clk_id, flags,
212 			   request, remain);
213 }
214 
215 /*
216  * Returns tst_ts seconds.
217  */
tst_ts_get_sec(struct tst_ts ts)218 static inline long long tst_ts_get_sec(struct tst_ts ts)
219 {
220 	switch (ts.type) {
221 	case TST_LIBC_TIMESPEC:
222 		return ts.ts.libc_ts.tv_sec;
223 	case TST_KERN_OLD_TIMESPEC:
224 		return ts.ts.kern_old_ts.tv_sec;
225 	case TST_KERN_TIMESPEC:
226 		return ts.ts.kern_ts.tv_sec;
227 	default:
228 		tst_brk(TBROK, "Invalid type: %d", ts.type);
229 		return -1;
230 	}
231 }
232 
233 /*
234  * Returns tst_ts nanoseconds.
235  */
tst_ts_get_nsec(struct tst_ts ts)236 static inline long long tst_ts_get_nsec(struct tst_ts ts)
237 {
238 	switch (ts.type) {
239 	case TST_LIBC_TIMESPEC:
240 		return ts.ts.libc_ts.tv_nsec;
241 	case TST_KERN_OLD_TIMESPEC:
242 		return ts.ts.kern_old_ts.tv_nsec;
243 	case TST_KERN_TIMESPEC:
244 		return ts.ts.kern_ts.tv_nsec;
245 	default:
246 		tst_brk(TBROK, "Invalid type: %d", ts.type);
247 		return -1;
248 	}
249 }
250 
251 /*
252  * Checks that timespec is valid, i.e. that the timestamp is not zero and that
253  * the nanoseconds are normalized i.e. in <0, 1s) interval.
254  *
255  *  0: On success, i.e. timespec updated correctly.
256  * -1: Error, timespec not updated.
257  * -2: Error, tv_nsec is corrupted.
258  */
tst_ts_valid(struct tst_ts * t)259 static inline int tst_ts_valid(struct tst_ts *t)
260 {
261 	long long nsec = tst_ts_get_nsec(*t);
262 
263 	if (nsec < 0 || nsec >= 1000000000)
264 		return -2;
265 
266 	if (tst_ts_get_sec(*t) == 0 && tst_ts_get_nsec(*t) == 0)
267 		return -1;
268 
269 	return 0;
270 }
271 
272 /*
273  * Sets tst_ts seconds.
274  */
tst_ts_set_sec(struct tst_ts * ts,long long sec)275 static inline void tst_ts_set_sec(struct tst_ts *ts, long long sec)
276 {
277 	switch (ts->type) {
278 	case TST_LIBC_TIMESPEC:
279 		ts->ts.libc_ts.tv_sec = sec;
280 	break;
281 	case TST_KERN_OLD_TIMESPEC:
282 		ts->ts.kern_old_ts.tv_sec = sec;
283 	break;
284 	case TST_KERN_TIMESPEC:
285 		ts->ts.kern_ts.tv_sec = sec;
286 	break;
287 	default:
288 		tst_brk(TBROK, "Invalid type: %d", ts->type);
289 	}
290 }
291 
292 /*
293  * Sets tst_ts nanoseconds.
294  */
tst_ts_set_nsec(struct tst_ts * ts,long long nsec)295 static inline void tst_ts_set_nsec(struct tst_ts *ts, long long nsec)
296 {
297 	switch (ts->type) {
298 	case TST_LIBC_TIMESPEC:
299 		ts->ts.libc_ts.tv_nsec = nsec;
300 	break;
301 	case TST_KERN_OLD_TIMESPEC:
302 		ts->ts.kern_old_ts.tv_nsec = nsec;
303 	break;
304 	case TST_KERN_TIMESPEC:
305 		ts->ts.kern_ts.tv_nsec = nsec;
306 	break;
307 	default:
308 		tst_brk(TBROK, "Invalid type: %d", ts->type);
309 	}
310 }
311 
312 /*
313  * Converts timespec to tst_ts.
314  */
tst_ts_from_timespec(struct timespec ts)315 static inline struct tst_ts tst_ts_from_timespec(struct timespec ts)
316 {
317 	struct tst_ts t = {
318 		.type = TST_LIBC_TIMESPEC,
319 		.ts.libc_ts.tv_sec = ts.tv_sec,
320 		.ts.libc_ts.tv_nsec = ts.tv_nsec,
321 	};
322 
323 	return t;
324 }
325 
326 /*
327  * Converst tst_ts into timespec.
328  */
tst_ts_to_timespec(struct tst_ts t)329 static inline struct timespec tst_ts_to_timespec(struct tst_ts t)
330 {
331 	return t.ts.libc_ts;
332 }
333 
334 /*
335  * Converts tst_ts to nanoseconds.
336  */
tst_ts_to_ns(struct tst_ts t)337 static inline long long tst_ts_to_ns(struct tst_ts t)
338 {
339 	return tst_ts_get_sec(t) * 1000000000 + tst_ts_get_nsec(t);
340 }
341 
342 /*
343  * Converts tst_ts to microseconds and rounds the value.
344  */
tst_ts_to_us(struct tst_ts t)345 static inline long long tst_ts_to_us(struct tst_ts t)
346 {
347 	return tst_ts_get_sec(t) * 1000000 +
348 	       (tst_ts_get_nsec(t) + 500) / 1000;
349 }
350 
351 /*
352  * Converts timespec to microseconds and rounds the value.
353  */
tst_timespec_to_us(struct timespec ts)354 static inline long long tst_timespec_to_us(struct timespec ts)
355 {
356 	return tst_ts_to_us(tst_ts_from_timespec(ts));
357 }
358 
359 /*
360  * Converts tst_ts to milliseconds and rounds the value.
361  */
tst_ts_to_ms(struct tst_ts t)362 static inline long long tst_ts_to_ms(struct tst_ts t)
363 {
364 	return tst_ts_get_sec(t) * 1000 +
365 	       (tst_ts_get_nsec(t) + 500000) / 1000000;
366 }
367 
368 /*
369  * Converts timespec to milliseconds and rounds the value.
370  */
tst_timespec_to_ms(struct timespec ts)371 static inline long long tst_timespec_to_ms(struct timespec ts)
372 {
373 	return tst_ts_to_ms(tst_ts_from_timespec(ts));
374 }
375 
376 /*
377  * Converts nanoseconds to tst_ts
378  */
379 static inline struct tst_ts
tst_ts_from_ns(enum tst_ts_type type,long long ns)380 tst_ts_from_ns(enum tst_ts_type type, long long ns)
381 {
382 	struct tst_ts ret = {.type = type};
383 
384 	tst_ts_set_sec(&ret, ns / 1000000000);
385 	tst_ts_set_nsec(&ret, ns % 1000000000);
386 
387 	return ret;
388 }
389 
390 /*
391  * Converts microseconds to tst_ts
392  */
393 static inline struct tst_ts
tst_ts_from_us(enum tst_ts_type type,long long us)394 tst_ts_from_us(enum tst_ts_type type, long long us)
395 {
396 	struct tst_ts ret = {.type = type};
397 
398 	tst_ts_set_sec(&ret, us / 1000000);
399 	tst_ts_set_nsec(&ret, (us % 1000000) * 1000);
400 
401 	return ret;
402 }
403 
404 /*
405  * Converts microseconds to timespec
406  */
407 static inline struct timespec
tst_timespec_from_us(long long us)408 tst_timespec_from_us(long long us)
409 {
410 	return tst_ts_to_timespec(tst_ts_from_us(TST_LIBC_TIMESPEC, us));
411 }
412 
413 /*
414  * Converts miliseconds to tst_ts
415  */
416 static inline struct tst_ts
tst_ts_from_ms(enum tst_ts_type type,long long ms)417 tst_ts_from_ms(enum tst_ts_type type, long long ms)
418 {
419 	struct tst_ts ret = {.type = type};
420 
421 	tst_ts_set_sec(&ret, ms / 1000);
422 	tst_ts_set_nsec(&ret, (ms % 1000) * 1000000);
423 
424 	return ret;
425 }
426 
427 /*
428  * Converts miliseconds to timespec
429  */
430 static inline struct timespec
tst_timespec_from_ms(long long ms)431 tst_timespec_from_ms(long long ms)
432 {
433 	return tst_ts_to_timespec(tst_ts_from_ms(TST_LIBC_TIMESPEC, ms));
434 }
435 
436 /*
437  * Returns if t1 less than t2. Both t1 and t2 must be normalized.
438  */
tst_ts_lt(struct tst_ts t1,struct tst_ts t2)439 static inline int tst_ts_lt(struct tst_ts t1, struct tst_ts t2)
440 {
441 	if (tst_ts_get_sec(t1) == tst_ts_get_sec(t2))
442 		return tst_ts_get_nsec(t1) < tst_ts_get_nsec(t2);
443 
444 	return tst_ts_get_sec(t1) < tst_ts_get_sec(t2);
445 }
446 
447 /*
448  * Returns if ts1 less than ts2. Both ts1 and ts2 must be normalized.
449  */
tst_timespec_lt(struct timespec ts1,struct timespec ts2)450 static inline int tst_timespec_lt(struct timespec ts1, struct timespec ts2)
451 {
452 	return tst_ts_lt(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
453 }
454 
455 /*
456  * Returns normalized tst_ts, i.e. 0 <= nsec < 1000000000.
457  */
tst_ts_normalize(struct tst_ts t)458 static inline struct tst_ts tst_ts_normalize(struct tst_ts t)
459 {
460 	long long sec = tst_ts_get_sec(t);
461 	long long nsec = tst_ts_get_nsec(t);
462 
463 	if (nsec >= 1000000000) {
464 		tst_ts_set_sec(&t, sec + 1);
465 		tst_ts_set_nsec(&t, nsec - 1000000000);
466 	}
467 
468 	if (nsec < 0) {
469 		tst_ts_set_sec(&t, sec - 1);
470 		tst_ts_set_nsec(&t, nsec + 1000000000);
471 	}
472 
473 	return t;
474 }
475 
476 /*
477  * Adds us microseconds to tst_ts.
478  */
479 static inline struct tst_ts
tst_ts_add_us(struct tst_ts t,long long us)480 tst_ts_add_us(struct tst_ts t, long long us)
481 {
482 	struct tst_ts res = {.type = t.type};
483 
484 	tst_ts_set_sec(&res, tst_ts_get_sec(t) + us / 1000000);
485 	tst_ts_set_nsec(&res, tst_ts_get_nsec(t) + (us % 1000000) * 1000);
486 
487 	return tst_ts_normalize(res);
488 }
489 
490 /*
491  * Adds us microseconds to struct timespec.
492  */
493 static inline struct timespec
tst_timespec_add_us(struct timespec ts,long long us)494 tst_timespec_add_us(struct timespec ts, long long us)
495 {
496 	struct tst_ts res;
497 
498 	res = tst_ts_add_us(tst_ts_from_timespec(ts), us);
499 
500 	return tst_ts_to_timespec(res);
501 }
502 
503 /*
504  * Substracts us microseconds from tst_ts.
505  */
506 static inline struct tst_ts
tst_ts_sub_us(struct tst_ts t,long long us)507 tst_ts_sub_us(struct tst_ts t, long long us)
508 {
509 	struct tst_ts res = {.type = t.type};
510 
511 	tst_ts_set_sec(&res, tst_ts_get_sec(t) - us / 1000000);
512 	tst_ts_set_nsec(&res, tst_ts_get_nsec(t) - (us % 1000000) * 1000);
513 
514 	return tst_ts_normalize(res);
515 }
516 
517 /*
518  * Substracts us microseconds from timespec.
519  */
520 static inline struct timespec
tst_timespec_sub_us(struct timespec ts,long long us)521 tst_timespec_sub_us(struct timespec ts, long long us)
522 {
523 	struct tst_ts res;
524 
525 	res = tst_ts_sub_us(tst_ts_from_timespec(ts), us);
526 
527 	return tst_ts_to_timespec(res);
528 }
529 
530 /*
531  * Adds two tst_ts structures.
532  */
533 static inline struct tst_ts
tst_ts_add(struct tst_ts t1,struct tst_ts t2)534 tst_ts_add(struct tst_ts t1, struct tst_ts t2)
535 {
536 	struct tst_ts res = {.type = t1.type};
537 
538 	tst_ts_set_sec(&res, tst_ts_get_sec(t1) + tst_ts_get_sec(t2));
539 	tst_ts_set_nsec(&res, tst_ts_get_nsec(t1) + tst_ts_get_nsec(t2));
540 
541 	return tst_ts_normalize(res);
542 }
543 
544 /*
545  * Adds two timespec structures.
546  */
547 static inline struct timespec
tst_timespec_add(struct timespec ts1,struct timespec ts2)548 tst_timespec_add(struct timespec ts1, struct timespec ts2)
549 {
550 	struct tst_ts res;
551 
552 	res = tst_ts_add(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
553 
554 	return tst_ts_to_timespec(res);
555 }
556 
557 /*
558  * Substract two tst_ts structures.
559  */
560 static inline struct tst_ts
tst_ts_diff(struct tst_ts t1,struct tst_ts t2)561 tst_ts_diff(struct tst_ts t1, struct tst_ts t2)
562 {
563 	struct tst_ts res = {.type = t1.type};
564 
565 	tst_ts_set_sec(&res, tst_ts_get_sec(t1) - tst_ts_get_sec(t2));
566 	tst_ts_set_nsec(&res, tst_ts_get_nsec(t1) - tst_ts_get_nsec(t2));
567 
568 	return tst_ts_normalize(res);
569 }
570 
571 /*
572  * Substract two timespec structures.
573  */
574 static inline struct timespec
tst_timespec_diff(struct timespec ts1,struct timespec ts2)575 tst_timespec_diff(struct timespec ts1, struct timespec ts2)
576 {
577 	struct tst_ts res;
578 
579 	res = tst_ts_diff(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
580 
581 	return tst_ts_to_timespec(res);
582 }
583 
584 /*
585  * Substract two tst_ts structures returns number of nanoseconds.
586  */
587 static inline long long
tst_ts_diff_ns(struct tst_ts t1,struct tst_ts t2)588 tst_ts_diff_ns(struct tst_ts t1, struct tst_ts t2)
589 {
590 	return tst_ts_to_ns(tst_ts_diff(t1, t2));
591 }
592 
593 /*
594  * Substract two timespec structures returns number of nanoseconds.
595  */
596 static inline long long
tst_timespec_diff_ns(struct timespec ts1,struct timespec ts2)597 tst_timespec_diff_ns(struct timespec ts1, struct timespec ts2)
598 {
599 	return tst_ts_diff_ns(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
600 }
601 
602 /*
603  * Substract two tst_ts structures returns number of microseconds.
604  */
605 static inline long long
tst_ts_diff_us(struct tst_ts t1,struct tst_ts t2)606 tst_ts_diff_us(struct tst_ts t1, struct tst_ts t2)
607 {
608 	return tst_ts_to_us(tst_ts_diff(t1, t2));
609 }
610 
611 /*
612  * Substract two timespec structures returns number of microseconds.
613  */
614 static inline long long
tst_timespec_diff_us(struct timespec ts1,struct timespec ts2)615 tst_timespec_diff_us(struct timespec ts1, struct timespec ts2)
616 {
617 	return tst_ts_diff_us(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
618 }
619 
620 /*
621  * Substract two tst_ts structures returns number of milliseconds.
622  */
623 static inline long long
tst_ts_diff_ms(struct tst_ts t1,struct tst_ts t2)624 tst_ts_diff_ms(struct tst_ts t1, struct tst_ts t2)
625 {
626 	return tst_ts_to_ms(tst_ts_diff(t1, t2));
627 }
628 
629 /*
630  * Substract two timespec structures returns number of milliseconds.
631  */
632 static inline long long
tst_timespec_diff_ms(struct timespec ts1,struct timespec ts2)633 tst_timespec_diff_ms(struct timespec ts1, struct timespec ts2)
634 {
635 	return tst_ts_diff_ms(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
636 }
637 
638 /*
639  * Returns absolute value of difference between two timespec structures.
640  */
641 static inline struct tst_ts
tst_ts_abs_diff(struct tst_ts t1,struct tst_ts t2)642 tst_ts_abs_diff(struct tst_ts t1, struct tst_ts t2)
643 {
644 	if (tst_ts_lt(t1, t2))
645 		return tst_ts_diff(t2, t1);
646 	else
647 		return tst_ts_diff(t1, t2);
648 }
649 
650 /*
651  * Returns absolute value of difference between two tst_ts structures in
652  * microseconds.
653  */
654 static inline long long
tst_ts_abs_diff_us(struct tst_ts t1,struct tst_ts t2)655 tst_ts_abs_diff_us(struct tst_ts t1, struct tst_ts t2)
656 {
657 	return tst_ts_to_us(tst_ts_abs_diff(t1, t2));
658 }
659 
660 /*
661  * Returns absolute value of difference between two timespec structures in
662  * microseconds.
663  */
664 static inline long long
tst_timespec_abs_diff_us(struct timespec ts1,struct timespec ts2)665 tst_timespec_abs_diff_us(struct timespec ts1, struct timespec ts2)
666 {
667 	return tst_ts_abs_diff_us(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
668 }
669 
670 /*
671  * Returns absolute value of difference between two timespec structures in
672  * milliseconds.
673  */
674 static inline long long
tst_ts_abs_diff_ms(struct tst_ts t1,struct tst_ts t2)675 tst_ts_abs_diff_ms(struct tst_ts t1, struct tst_ts t2)
676 {
677 	return tst_ts_to_ms(tst_ts_abs_diff(t1, t2));
678 }
679 
680 /*
681  * Exits the test with TCONF if particular timer is not supported. This is
682  * intended to be used in test setup. There is no cleanup callback parameter as
683  * you are expected to call it before initializing any resources that has to be
684  * cleaned up later.
685  *
686  * @clk_id: Posix clock to use.
687  */
688 void tst_timer_check(clockid_t clk_id);
689 
690 /*
691  * Marks a start time for given clock type.
692  *
693  * @clk_id: Posix clock to use.
694  */
695 void tst_timer_start(clockid_t clk_id);
696 
697 /*
698  * Returns true if timer started by tst_timer_start() has been running for
699  * longer than ms seconds.
700  *
701  * @ms: Time interval in milliseconds.
702  */
703 int tst_timer_expired_ms(long long ms);
704 
705 /*
706  * Marks timer end time.
707  */
708 void tst_timer_stop(void);
709 
710 /*
711  * Retuns elapsed time in struct timespec.
712  */
713 struct timespec tst_timer_elapsed(void);
714 
715 /*
716  * Returns elapsed time in milliseconds.
717  */
tst_timer_elapsed_ms(void)718 static inline long long tst_timer_elapsed_ms(void)
719 {
720 	return tst_timespec_to_ms(tst_timer_elapsed());
721 }
722 
723 /*
724  * Returns elapsed time in microseconds.
725  */
tst_timer_elapsed_us(void)726 static inline long long tst_timer_elapsed_us(void)
727 {
728 	return tst_timespec_to_us(tst_timer_elapsed());
729 }
730 
731 #endif /* TST_TIMER */
732