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