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 <sched.h>
16 #include <sys/time.h>
17 #include <mqueue.h>
18 #include <time.h>
19 #include "tst_test.h"
20 #include "lapi/common_timers.h"
21 #include "lapi/posix_types.h"
22 #include "lapi/syscalls.h"
23
24 /*
25 * Converts timeval to microseconds.
26 */
tst_timeval_to_us(struct timeval t)27 static inline long long tst_timeval_to_us(struct timeval t)
28 {
29 return ((long long)t.tv_sec) * 1000000 + t.tv_usec;
30 }
31
32 /*
33 * Converts timeval to milliseconds.
34 */
tst_timeval_to_ms(struct timeval t)35 static inline long long tst_timeval_to_ms(struct timeval t)
36 {
37 return ((long long)t.tv_sec) * 1000 + (t.tv_usec + 500) / 1000;
38 }
39
40 /*
41 * Converts milliseconds to struct timeval
42 */
tst_ms_to_timeval(long long ms)43 static inline struct timeval tst_ms_to_timeval(long long ms)
44 {
45 struct timeval ret;
46
47 ret.tv_sec = ms / 1000;
48 ret.tv_usec = (ms % 1000) * 1000;
49
50 return ret;
51 }
52
53 /*
54 * Converts microseconds to struct timeval
55 */
tst_us_to_timeval(long long us)56 static inline struct timeval tst_us_to_timeval(long long us)
57 {
58 struct timeval ret;
59
60 ret.tv_sec = us / 1000000;
61 ret.tv_usec = us % 1000000;
62
63 return ret;
64 }
65
66 /*
67 * Returns difference between two timeval structures.
68 */
tst_timeval_diff(struct timeval t1,struct timeval t2)69 static inline struct timeval tst_timeval_diff(struct timeval t1,
70 struct timeval t2)
71 {
72 struct timeval res;
73
74 res.tv_sec = t1.tv_sec - t2.tv_sec;
75
76 if (t1.tv_usec < t2.tv_usec) {
77 res.tv_sec--;
78 res.tv_usec = 1000000 - (t2.tv_usec - t1.tv_usec);
79 } else {
80 res.tv_usec = t1.tv_usec - t2.tv_usec;
81 }
82
83 return res;
84 }
85
tst_timeval_diff_us(struct timeval t1,struct timeval t2)86 static inline long long tst_timeval_diff_us(struct timeval t1,
87 struct timeval t2)
88 {
89 return tst_timeval_to_us(tst_timeval_diff(t1, t2));
90 }
91
tst_timeval_diff_ms(struct timeval t1,struct timeval t2)92 static inline long long tst_timeval_diff_ms(struct timeval t1,
93 struct timeval t2)
94 {
95 return tst_timeval_to_ms(tst_timeval_diff(t1, t2));
96 }
97
98 #ifndef __kernel_timespec
99
100 typedef __kernel_long_t __kernel_old_time_t;
101
102 #ifndef HAVE_STRUCT___KERNEL_OLD_TIMEVAL
103 struct __kernel_old_timeval {
104 __kernel_old_time_t tv_sec; /* seconds */
105 __kernel_suseconds_t tv_usec; /* microseconds */
106 };
107 #endif
108
109 #ifndef HAVE_STRUCT___KERNEL_OLD_TIMESPEC
110 struct __kernel_old_timespec {
111 __kernel_old_time_t tv_sec; /* seconds */
112 __kernel_old_time_t tv_nsec; /* nanoseconds */
113 };
114 #endif
115
116 typedef long long __kernel_time64_t;
117
118 #ifndef HAVE_STRUCT___KERNEL_TIMESPEC
119 struct __kernel_timespec {
120 __kernel_time64_t tv_sec; /* seconds */
121 long long tv_nsec; /* nanoseconds */
122 };
123 #endif
124
125 #ifndef HAVE_STRUCT___KERNEL_OLD_ITIMERSPEC
126 struct __kernel_old_itimerspec {
127 struct __kernel_old_timespec it_interval; /* timer period */
128 struct __kernel_old_timespec it_value; /* timer expiration */
129 };
130 #endif
131
132 #ifndef HAVE_STRUCT___KERNEL_ITIMERSPEC
133 struct __kernel_itimerspec {
134 struct __kernel_timespec it_interval; /* timer period */
135 struct __kernel_timespec it_value; /* timer expiration */
136 };
137 #endif
138 #endif
139
140 enum tst_ts_type {
141 TST_LIBC_TIMESPEC,
142 TST_KERN_OLD_TIMESPEC,
143 TST_KERN_TIMESPEC
144 };
145
146 struct tst_ts {
147 enum tst_ts_type type;
148 union ts {
149 struct timespec libc_ts;
150 struct __kernel_old_timespec kern_old_ts;
151 struct __kernel_timespec kern_ts;
152 } ts;
153 };
154
155 struct tst_its {
156 enum tst_ts_type type;
157 union {
158 struct __kernel_old_itimerspec kern_old_its;
159 struct __kernel_itimerspec kern_its;
160 } ts;
161 };
162
tst_ts_get(struct tst_ts * t)163 static inline void *tst_ts_get(struct tst_ts *t)
164 {
165 if (!t)
166 return NULL;
167
168 switch (t->type) {
169 case TST_LIBC_TIMESPEC:
170 return &t->ts.libc_ts;
171 case TST_KERN_OLD_TIMESPEC:
172 return &t->ts.kern_old_ts;
173 case TST_KERN_TIMESPEC:
174 return &t->ts.kern_ts;
175 default:
176 tst_brk(TBROK, "Invalid type: %d", t->type);
177 return NULL;
178 }
179 }
180
tst_its_get(struct tst_its * t)181 static inline void *tst_its_get(struct tst_its *t)
182 {
183 if (!t)
184 return NULL;
185
186 switch (t->type) {
187 case TST_KERN_OLD_TIMESPEC:
188 return &t->ts.kern_old_its;
189 case TST_KERN_TIMESPEC:
190 return &t->ts.kern_its;
191 default:
192 tst_brk(TBROK, "Invalid type: %d", t->type);
193 return NULL;
194 }
195 }
196
libc_clock_getres(clockid_t clk_id,void * ts)197 static inline int libc_clock_getres(clockid_t clk_id, void *ts)
198 {
199 return clock_getres(clk_id, ts);
200 }
201
sys_clock_getres(clockid_t clk_id,void * ts)202 static inline int sys_clock_getres(clockid_t clk_id, void *ts)
203 {
204 return tst_syscall(__NR_clock_getres, clk_id, ts);
205 }
206
sys_clock_getres64(clockid_t clk_id,void * ts)207 static inline int sys_clock_getres64(clockid_t clk_id, void *ts)
208 {
209 return tst_syscall(__NR_clock_getres_time64, clk_id, ts);
210 }
211
libc_clock_gettime(clockid_t clk_id,void * ts)212 static inline int libc_clock_gettime(clockid_t clk_id, void *ts)
213 {
214 return clock_gettime(clk_id, ts);
215 }
216
sys_clock_gettime(clockid_t clk_id,void * ts)217 static inline int sys_clock_gettime(clockid_t clk_id, void *ts)
218 {
219 return tst_syscall(__NR_clock_gettime, clk_id, ts);
220 }
221
sys_clock_gettime64(clockid_t clk_id,void * ts)222 static inline int sys_clock_gettime64(clockid_t clk_id, void *ts)
223 {
224 return tst_syscall(__NR_clock_gettime64, clk_id, ts);
225 }
226
libc_clock_settime(clockid_t clk_id,void * ts)227 static inline int libc_clock_settime(clockid_t clk_id, void *ts)
228 {
229 return clock_settime(clk_id, ts);
230 }
231
sys_clock_settime(clockid_t clk_id,void * ts)232 static inline int sys_clock_settime(clockid_t clk_id, void *ts)
233 {
234 return tst_syscall(__NR_clock_settime, clk_id, ts);
235 }
236
sys_clock_settime64(clockid_t clk_id,void * ts)237 static inline int sys_clock_settime64(clockid_t clk_id, void *ts)
238 {
239 return tst_syscall(__NR_clock_settime64, clk_id, ts);
240 }
241
libc_clock_nanosleep(clockid_t clk_id,int flags,void * request,void * remain)242 static inline int libc_clock_nanosleep(clockid_t clk_id, int flags,
243 void *request, void *remain)
244 {
245 return clock_nanosleep(clk_id, flags, request, remain);
246 }
247
sys_clock_nanosleep(clockid_t clk_id,int flags,void * request,void * remain)248 static inline int sys_clock_nanosleep(clockid_t clk_id, int flags,
249 void *request, void *remain)
250 {
251 return tst_syscall(__NR_clock_nanosleep, clk_id, flags,
252 request, remain);
253 }
254
sys_clock_nanosleep64(clockid_t clk_id,int flags,void * request,void * remain)255 static inline int sys_clock_nanosleep64(clockid_t clk_id, int flags,
256 void *request, void *remain)
257 {
258 return tst_syscall(__NR_clock_nanosleep_time64, clk_id, flags,
259 request, remain);
260 }
261
sys_futex(int * uaddr,int futex_op,int val,void * to,int * uaddr2,int val3)262 static inline int sys_futex(int *uaddr, int futex_op, int val, void *to,
263 int *uaddr2, int val3)
264 {
265 return tst_syscall(__NR_futex, uaddr, futex_op, val, to, uaddr2, val3);
266 }
267
sys_futex_time64(int * uaddr,int futex_op,int val,void * to,int * uaddr2,int val3)268 static inline int sys_futex_time64(int *uaddr, int futex_op, int val, void *to,
269 int *uaddr2, int val3)
270 {
271 return tst_syscall(__NR_futex_time64, uaddr, futex_op, val, to, uaddr2, val3);
272 }
273
libc_mq_timedsend(mqd_t mqdes,const char * msg_ptr,size_t msg_len,unsigned int msg_prio,void * abs_timeout)274 static inline int libc_mq_timedsend(mqd_t mqdes, const char *msg_ptr,
275 size_t msg_len, unsigned int msg_prio, void *abs_timeout)
276 {
277 return mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, abs_timeout);
278 }
279
sys_mq_timedsend(mqd_t mqdes,const char * msg_ptr,size_t msg_len,unsigned int msg_prio,void * abs_timeout)280 static inline int sys_mq_timedsend(mqd_t mqdes, const char *msg_ptr,
281 size_t msg_len, unsigned int msg_prio, void *abs_timeout)
282 {
283 return tst_syscall(__NR_mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio,
284 abs_timeout);
285 }
286
sys_mq_timedsend64(mqd_t mqdes,const char * msg_ptr,size_t msg_len,unsigned int msg_prio,void * abs_timeout)287 static inline int sys_mq_timedsend64(mqd_t mqdes, const char *msg_ptr,
288 size_t msg_len, unsigned int msg_prio, void *abs_timeout)
289 {
290 return tst_syscall(__NR_mq_timedsend_time64, mqdes, msg_ptr, msg_len,
291 msg_prio, abs_timeout);
292 }
293
libc_mq_timedreceive(mqd_t mqdes,char * msg_ptr,size_t msg_len,unsigned int * msg_prio,void * abs_timeout)294 static inline ssize_t libc_mq_timedreceive(mqd_t mqdes, char *msg_ptr,
295 size_t msg_len, unsigned int *msg_prio, void *abs_timeout)
296 {
297 return mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, abs_timeout);
298 }
299
sys_mq_timedreceive(mqd_t mqdes,char * msg_ptr,size_t msg_len,unsigned int * msg_prio,void * abs_timeout)300 static inline ssize_t sys_mq_timedreceive(mqd_t mqdes, char *msg_ptr,
301 size_t msg_len, unsigned int *msg_prio, void *abs_timeout)
302 {
303 return tst_syscall(__NR_mq_timedreceive, mqdes, msg_ptr, msg_len,
304 msg_prio, abs_timeout);
305 }
306
sys_mq_timedreceive64(mqd_t mqdes,char * msg_ptr,size_t msg_len,unsigned int * msg_prio,void * abs_timeout)307 static inline ssize_t sys_mq_timedreceive64(mqd_t mqdes, char *msg_ptr,
308 size_t msg_len, unsigned int *msg_prio, void *abs_timeout)
309 {
310 return tst_syscall(__NR_mq_timedreceive_time64, mqdes, msg_ptr, msg_len,
311 msg_prio, abs_timeout);
312 }
313
libc_sched_rr_get_interval(pid_t pid,void * ts)314 static inline int libc_sched_rr_get_interval(pid_t pid, void *ts)
315 {
316 return sched_rr_get_interval(pid, ts);
317 }
318
sys_sched_rr_get_interval(pid_t pid,void * ts)319 static inline int sys_sched_rr_get_interval(pid_t pid, void *ts)
320 {
321 return tst_syscall(__NR_sched_rr_get_interval, pid, ts);
322 }
323
sys_sched_rr_get_interval64(pid_t pid,void * ts)324 static inline int sys_sched_rr_get_interval64(pid_t pid, void *ts)
325 {
326 return tst_syscall(__NR_sched_rr_get_interval_time64, pid, ts);
327 }
328
sys_timer_gettime(kernel_timer_t timerid,void * its)329 static inline int sys_timer_gettime(kernel_timer_t timerid, void *its)
330 {
331 return tst_syscall(__NR_timer_gettime, timerid, its);
332 }
333
sys_timer_gettime64(kernel_timer_t timerid,void * its)334 static inline int sys_timer_gettime64(kernel_timer_t timerid, void *its)
335 {
336 return tst_syscall(__NR_timer_gettime64, timerid, its);
337 }
338
sys_timer_settime(kernel_timer_t timerid,int flags,void * its,void * old_its)339 static inline int sys_timer_settime(kernel_timer_t timerid, int flags, void *its,
340 void *old_its)
341 {
342 return tst_syscall(__NR_timer_settime, timerid, flags, its, old_its);
343 }
344
sys_timer_settime64(kernel_timer_t timerid,int flags,void * its,void * old_its)345 static inline int sys_timer_settime64(kernel_timer_t timerid, int flags, void *its,
346 void *old_its)
347 {
348 return tst_syscall(__NR_timer_settime64, timerid, flags, its, old_its);
349 }
350
sys_timerfd_gettime(int fd,void * its)351 static inline int sys_timerfd_gettime(int fd, void *its)
352 {
353 return tst_syscall(__NR_timerfd_gettime, fd, its);
354 }
355
sys_timerfd_gettime64(int fd,void * its)356 static inline int sys_timerfd_gettime64(int fd, void *its)
357 {
358 return tst_syscall(__NR_timerfd_gettime64, fd, its);
359 }
360
sys_timerfd_settime(int fd,int flags,void * its,void * old_its)361 static inline int sys_timerfd_settime(int fd, int flags, void *its,
362 void *old_its)
363 {
364 return tst_syscall(__NR_timerfd_settime, fd, flags, its, old_its);
365 }
366
sys_timerfd_settime64(int fd,int flags,void * its,void * old_its)367 static inline int sys_timerfd_settime64(int fd, int flags, void *its,
368 void *old_its)
369 {
370 return tst_syscall(__NR_timerfd_settime64, fd, flags, its, old_its);
371 }
372
373 /*
374 * Returns tst_ts seconds.
375 */
tst_ts_get_sec(struct tst_ts ts)376 static inline long long tst_ts_get_sec(struct tst_ts ts)
377 {
378 switch (ts.type) {
379 case TST_LIBC_TIMESPEC:
380 return ts.ts.libc_ts.tv_sec;
381 case TST_KERN_OLD_TIMESPEC:
382 return ts.ts.kern_old_ts.tv_sec;
383 case TST_KERN_TIMESPEC:
384 return ts.ts.kern_ts.tv_sec;
385 default:
386 tst_brk(TBROK, "Invalid type: %d", ts.type);
387 return -1;
388 }
389 }
390
391 /*
392 * Returns tst_ts nanoseconds.
393 */
tst_ts_get_nsec(struct tst_ts ts)394 static inline long long tst_ts_get_nsec(struct tst_ts ts)
395 {
396 switch (ts.type) {
397 case TST_LIBC_TIMESPEC:
398 return ts.ts.libc_ts.tv_nsec;
399 case TST_KERN_OLD_TIMESPEC:
400 return ts.ts.kern_old_ts.tv_nsec;
401 case TST_KERN_TIMESPEC:
402 return ts.ts.kern_ts.tv_nsec;
403 default:
404 tst_brk(TBROK, "Invalid type: %d", ts.type);
405 return -1;
406 }
407 }
408
409 /*
410 * Sets tst_ts seconds.
411 */
tst_ts_set_sec(struct tst_ts * ts,long long sec)412 static inline void tst_ts_set_sec(struct tst_ts *ts, long long sec)
413 {
414 switch (ts->type) {
415 case TST_LIBC_TIMESPEC:
416 ts->ts.libc_ts.tv_sec = sec;
417 break;
418 case TST_KERN_OLD_TIMESPEC:
419 ts->ts.kern_old_ts.tv_sec = sec;
420 break;
421 case TST_KERN_TIMESPEC:
422 ts->ts.kern_ts.tv_sec = sec;
423 break;
424 default:
425 tst_brk(TBROK, "Invalid type: %d", ts->type);
426 }
427 }
428
429 /*
430 * Sets tst_ts nanoseconds.
431 */
tst_ts_set_nsec(struct tst_ts * ts,long long nsec)432 static inline void tst_ts_set_nsec(struct tst_ts *ts, long long nsec)
433 {
434 switch (ts->type) {
435 case TST_LIBC_TIMESPEC:
436 ts->ts.libc_ts.tv_nsec = nsec;
437 break;
438 case TST_KERN_OLD_TIMESPEC:
439 ts->ts.kern_old_ts.tv_nsec = nsec;
440 break;
441 case TST_KERN_TIMESPEC:
442 ts->ts.kern_ts.tv_nsec = nsec;
443 break;
444 default:
445 tst_brk(TBROK, "Invalid type: %d", ts->type);
446 }
447 }
448
449 /*
450 * Returns tst_its it_interval seconds.
451 */
tst_its_get_interval_sec(struct tst_its its)452 static inline long long tst_its_get_interval_sec(struct tst_its its)
453 {
454 switch (its.type) {
455 case TST_KERN_OLD_TIMESPEC:
456 return its.ts.kern_old_its.it_interval.tv_sec;
457 case TST_KERN_TIMESPEC:
458 return its.ts.kern_its.it_interval.tv_sec;
459 default:
460 tst_brk(TBROK, "Invalid type: %d", its.type);
461 return -1;
462 }
463 }
464
465 /*
466 * Returns tst_its it_interval nanoseconds.
467 */
tst_its_get_interval_nsec(struct tst_its its)468 static inline long long tst_its_get_interval_nsec(struct tst_its its)
469 {
470 switch (its.type) {
471 case TST_KERN_OLD_TIMESPEC:
472 return its.ts.kern_old_its.it_interval.tv_nsec;
473 case TST_KERN_TIMESPEC:
474 return its.ts.kern_its.it_interval.tv_nsec;
475 default:
476 tst_brk(TBROK, "Invalid type: %d", its.type);
477 return -1;
478 }
479 }
480
481 /*
482 * Sets tst_its it_interval seconds.
483 */
tst_its_set_interval_sec(struct tst_its * its,long long sec)484 static inline void tst_its_set_interval_sec(struct tst_its *its, long long sec)
485 {
486 switch (its->type) {
487 break;
488 case TST_KERN_OLD_TIMESPEC:
489 its->ts.kern_old_its.it_interval.tv_sec = sec;
490 break;
491 case TST_KERN_TIMESPEC:
492 its->ts.kern_its.it_interval.tv_sec = sec;
493 break;
494 default:
495 tst_brk(TBROK, "Invalid type: %d", its->type);
496 }
497 }
498
499 /*
500 * Sets tst_its it_interval nanoseconds.
501 */
tst_its_set_interval_nsec(struct tst_its * its,long long nsec)502 static inline void tst_its_set_interval_nsec(struct tst_its *its, long long nsec)
503 {
504 switch (its->type) {
505 break;
506 case TST_KERN_OLD_TIMESPEC:
507 its->ts.kern_old_its.it_interval.tv_nsec = nsec;
508 break;
509 case TST_KERN_TIMESPEC:
510 its->ts.kern_its.it_interval.tv_nsec = nsec;
511 break;
512 default:
513 tst_brk(TBROK, "Invalid type: %d", its->type);
514 }
515 }
516
517 /*
518 * Returns tst_its it_value seconds.
519 */
tst_its_get_value_sec(struct tst_its its)520 static inline long long tst_its_get_value_sec(struct tst_its its)
521 {
522 switch (its.type) {
523 case TST_KERN_OLD_TIMESPEC:
524 return its.ts.kern_old_its.it_value.tv_sec;
525 case TST_KERN_TIMESPEC:
526 return its.ts.kern_its.it_value.tv_sec;
527 default:
528 tst_brk(TBROK, "Invalid type: %d", its.type);
529 return -1;
530 }
531 }
532
533 /*
534 * Returns tst_its it_value nanoseconds.
535 */
tst_its_get_value_nsec(struct tst_its its)536 static inline long long tst_its_get_value_nsec(struct tst_its its)
537 {
538 switch (its.type) {
539 case TST_KERN_OLD_TIMESPEC:
540 return its.ts.kern_old_its.it_value.tv_nsec;
541 case TST_KERN_TIMESPEC:
542 return its.ts.kern_its.it_value.tv_nsec;
543 default:
544 tst_brk(TBROK, "Invalid type: %d", its.type);
545 return -1;
546 }
547 }
548
549 /*
550 * Sets tst_its it_value seconds.
551 */
tst_its_set_value_sec(struct tst_its * its,long long sec)552 static inline void tst_its_set_value_sec(struct tst_its *its, long long sec)
553 {
554 switch (its->type) {
555 break;
556 case TST_KERN_OLD_TIMESPEC:
557 its->ts.kern_old_its.it_value.tv_sec = sec;
558 break;
559 case TST_KERN_TIMESPEC:
560 its->ts.kern_its.it_value.tv_sec = sec;
561 break;
562 default:
563 tst_brk(TBROK, "Invalid type: %d", its->type);
564 }
565 }
566
567 /*
568 * Sets tst_its it_value nanoseconds.
569 */
tst_its_set_value_nsec(struct tst_its * its,long long nsec)570 static inline void tst_its_set_value_nsec(struct tst_its *its, long long nsec)
571 {
572 switch (its->type) {
573 break;
574 case TST_KERN_OLD_TIMESPEC:
575 its->ts.kern_old_its.it_value.tv_nsec = nsec;
576 break;
577 case TST_KERN_TIMESPEC:
578 its->ts.kern_its.it_value.tv_nsec = nsec;
579 break;
580 default:
581 tst_brk(TBROK, "Invalid type: %d", its->type);
582 }
583 }
584
585 /*
586 * Checks that timespec is valid, i.e. that the timestamp is not zero and that
587 * the nanoseconds are normalized i.e. in <0, 1s) interval.
588 *
589 * 0: On success, i.e. timespec updated correctly.
590 * -1: Error, timespec not updated.
591 * -2: Error, tv_nsec is corrupted.
592 */
tst_ts_valid(struct tst_ts * t)593 static inline int tst_ts_valid(struct tst_ts *t)
594 {
595 long long nsec = tst_ts_get_nsec(*t);
596
597 if (nsec < 0 || nsec >= 1000000000)
598 return -2;
599
600 if (tst_ts_get_sec(*t) == 0 && tst_ts_get_nsec(*t) == 0)
601 return -1;
602
603 return 0;
604 }
605
606 /*
607 * Converts timespec to tst_ts.
608 */
tst_ts_from_timespec(struct timespec ts)609 static inline struct tst_ts tst_ts_from_timespec(struct timespec ts)
610 {
611 struct tst_ts t = {
612 .type = TST_LIBC_TIMESPEC,
613 .ts.libc_ts.tv_sec = ts.tv_sec,
614 .ts.libc_ts.tv_nsec = ts.tv_nsec,
615 };
616
617 return t;
618 }
619
620 /*
621 * Converst tst_ts into timespec.
622 */
tst_ts_to_timespec(struct tst_ts t)623 static inline struct timespec tst_ts_to_timespec(struct tst_ts t)
624 {
625 return t.ts.libc_ts;
626 }
627
628 /*
629 * Converts tst_ts to nanoseconds.
630 */
tst_ts_to_ns(struct tst_ts t)631 static inline long long tst_ts_to_ns(struct tst_ts t)
632 {
633 return tst_ts_get_sec(t) * 1000000000 + tst_ts_get_nsec(t);
634 }
635
636 /*
637 * Converts tst_ts to microseconds and rounds the value.
638 */
tst_ts_to_us(struct tst_ts t)639 static inline long long tst_ts_to_us(struct tst_ts t)
640 {
641 return tst_ts_get_sec(t) * 1000000 +
642 (tst_ts_get_nsec(t) + 500) / 1000;
643 }
644
645 /*
646 * Converts timespec to microseconds and rounds the value.
647 */
tst_timespec_to_us(struct timespec ts)648 static inline long long tst_timespec_to_us(struct timespec ts)
649 {
650 return tst_ts_to_us(tst_ts_from_timespec(ts));
651 }
652
653 /*
654 * Converts tst_ts to milliseconds and rounds the value.
655 */
tst_ts_to_ms(struct tst_ts t)656 static inline long long tst_ts_to_ms(struct tst_ts t)
657 {
658 return tst_ts_get_sec(t) * 1000 +
659 (tst_ts_get_nsec(t) + 500000) / 1000000;
660 }
661
662 /*
663 * Converts timespec to milliseconds and rounds the value.
664 */
tst_timespec_to_ms(struct timespec ts)665 static inline long long tst_timespec_to_ms(struct timespec ts)
666 {
667 return tst_ts_to_ms(tst_ts_from_timespec(ts));
668 }
669
670 /*
671 * Converts nanoseconds to tst_ts
672 */
673 static inline struct tst_ts
tst_ts_from_ns(enum tst_ts_type type,long long ns)674 tst_ts_from_ns(enum tst_ts_type type, long long ns)
675 {
676 struct tst_ts ret = {.type = type};
677
678 tst_ts_set_sec(&ret, ns / 1000000000);
679 tst_ts_set_nsec(&ret, ns % 1000000000);
680
681 return ret;
682 }
683
684 /*
685 * Converts microseconds to tst_ts
686 */
687 static inline struct tst_ts
tst_ts_from_us(enum tst_ts_type type,long long us)688 tst_ts_from_us(enum tst_ts_type type, long long us)
689 {
690 struct tst_ts ret = {.type = type};
691
692 tst_ts_set_sec(&ret, us / 1000000);
693 tst_ts_set_nsec(&ret, (us % 1000000) * 1000);
694
695 return ret;
696 }
697
698 /*
699 * Converts microseconds to timespec
700 */
701 static inline struct timespec
tst_timespec_from_us(long long us)702 tst_timespec_from_us(long long us)
703 {
704 return tst_ts_to_timespec(tst_ts_from_us(TST_LIBC_TIMESPEC, us));
705 }
706
707 /*
708 * Converts miliseconds to tst_ts
709 */
710 static inline struct tst_ts
tst_ts_from_ms(enum tst_ts_type type,long long ms)711 tst_ts_from_ms(enum tst_ts_type type, long long ms)
712 {
713 struct tst_ts ret = {.type = type};
714
715 tst_ts_set_sec(&ret, ms / 1000);
716 tst_ts_set_nsec(&ret, (ms % 1000) * 1000000);
717
718 return ret;
719 }
720
721 /*
722 * Converts miliseconds to timespec
723 */
724 static inline struct timespec
tst_timespec_from_ms(long long ms)725 tst_timespec_from_ms(long long ms)
726 {
727 return tst_ts_to_timespec(tst_ts_from_ms(TST_LIBC_TIMESPEC, ms));
728 }
729
730 /*
731 * Sets tst_its it_value from microseconds.
732 */
tst_its_set_interval_from_us(struct tst_its * its,long long usec)733 static inline void tst_its_set_interval_from_us(struct tst_its *its, long long usec)
734 {
735 struct timespec tp = tst_timespec_from_us(usec);
736
737 tst_its_set_interval_sec(its, tp.tv_sec);
738 tst_its_set_interval_nsec(its, tp.tv_nsec);
739 }
740
741 /*
742 * Sets tst_its it_value from microseconds.
743 */
tst_its_set_value_from_us(struct tst_its * its,long long usec)744 static inline void tst_its_set_value_from_us(struct tst_its *its, long long usec)
745 {
746 struct timespec tp = tst_timespec_from_us(usec);
747
748 tst_its_set_value_sec(its, tp.tv_sec);
749 tst_its_set_value_nsec(its, tp.tv_nsec);
750 }
751
752 /*
753 * Sets tst_its it_interval from tst_ts.
754 */
tst_its_set_interval_from_ts(struct tst_its * its,struct tst_ts ts)755 static inline void tst_its_set_interval_from_ts(struct tst_its *its, struct tst_ts ts)
756 {
757 tst_its_set_interval_sec(its, tst_ts_get_sec(ts));
758 tst_its_set_interval_nsec(its, tst_ts_get_nsec(ts));
759 }
760
761 /*
762 * Sets tst_its it_value from tst_ts.
763 */
tst_its_set_value_from_ts(struct tst_its * its,struct tst_ts ts)764 static inline void tst_its_set_value_from_ts(struct tst_its *its, struct tst_ts ts)
765 {
766 tst_its_set_value_sec(its, tst_ts_get_sec(ts));
767 tst_its_set_value_nsec(its, tst_ts_get_nsec(ts));
768 }
769
770 /*
771 * Returns if t1 less than t2. Both t1 and t2 must be normalized.
772 */
tst_ts_lt(struct tst_ts t1,struct tst_ts t2)773 static inline int tst_ts_lt(struct tst_ts t1, struct tst_ts t2)
774 {
775 if (tst_ts_get_sec(t1) == tst_ts_get_sec(t2))
776 return tst_ts_get_nsec(t1) < tst_ts_get_nsec(t2);
777
778 return tst_ts_get_sec(t1) < tst_ts_get_sec(t2);
779 }
780
781 /*
782 * Returns if ts1 less than ts2. Both ts1 and ts2 must be normalized.
783 */
tst_timespec_lt(struct timespec ts1,struct timespec ts2)784 static inline int tst_timespec_lt(struct timespec ts1, struct timespec ts2)
785 {
786 return tst_ts_lt(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
787 }
788
789 /*
790 * Returns normalized tst_ts, i.e. 0 <= nsec < 1000000000.
791 */
tst_ts_normalize(struct tst_ts t)792 static inline struct tst_ts tst_ts_normalize(struct tst_ts t)
793 {
794 long long sec = tst_ts_get_sec(t);
795 long long nsec = tst_ts_get_nsec(t);
796
797 if (nsec >= 1000000000) {
798 tst_ts_set_sec(&t, sec + 1);
799 tst_ts_set_nsec(&t, nsec - 1000000000);
800 }
801
802 if (nsec < 0) {
803 tst_ts_set_sec(&t, sec - 1);
804 tst_ts_set_nsec(&t, nsec + 1000000000);
805 }
806
807 return t;
808 }
809
810 /*
811 * Adds us microseconds to tst_ts.
812 */
813 static inline struct tst_ts
tst_ts_add_us(struct tst_ts t,long long us)814 tst_ts_add_us(struct tst_ts t, long long us)
815 {
816 struct tst_ts res = {.type = t.type};
817
818 tst_ts_set_sec(&res, tst_ts_get_sec(t) + us / 1000000);
819 tst_ts_set_nsec(&res, tst_ts_get_nsec(t) + (us % 1000000) * 1000);
820
821 return tst_ts_normalize(res);
822 }
823
824 /*
825 * Adds us microseconds to struct timespec.
826 */
827 static inline struct timespec
tst_timespec_add_us(struct timespec ts,long long us)828 tst_timespec_add_us(struct timespec ts, long long us)
829 {
830 struct tst_ts res;
831
832 res = tst_ts_add_us(tst_ts_from_timespec(ts), us);
833
834 return tst_ts_to_timespec(res);
835 }
836
837 /*
838 * Substracts us microseconds from tst_ts.
839 */
840 static inline struct tst_ts
tst_ts_sub_us(struct tst_ts t,long long us)841 tst_ts_sub_us(struct tst_ts t, long long us)
842 {
843 struct tst_ts res = {.type = t.type};
844
845 tst_ts_set_sec(&res, tst_ts_get_sec(t) - us / 1000000);
846 tst_ts_set_nsec(&res, tst_ts_get_nsec(t) - (us % 1000000) * 1000);
847
848 return tst_ts_normalize(res);
849 }
850
851 /*
852 * Substracts us microseconds from timespec.
853 */
854 static inline struct timespec
tst_timespec_sub_us(struct timespec ts,long long us)855 tst_timespec_sub_us(struct timespec ts, long long us)
856 {
857 struct tst_ts res;
858
859 res = tst_ts_sub_us(tst_ts_from_timespec(ts), us);
860
861 return tst_ts_to_timespec(res);
862 }
863
864 /*
865 * Adds two tst_ts structures.
866 */
867 static inline struct tst_ts
tst_ts_add(struct tst_ts t1,struct tst_ts t2)868 tst_ts_add(struct tst_ts t1, struct tst_ts t2)
869 {
870 struct tst_ts res = {.type = t1.type};
871
872 tst_ts_set_sec(&res, tst_ts_get_sec(t1) + tst_ts_get_sec(t2));
873 tst_ts_set_nsec(&res, tst_ts_get_nsec(t1) + tst_ts_get_nsec(t2));
874
875 return tst_ts_normalize(res);
876 }
877
878 /*
879 * Adds two timespec structures.
880 */
881 static inline struct timespec
tst_timespec_add(struct timespec ts1,struct timespec ts2)882 tst_timespec_add(struct timespec ts1, struct timespec ts2)
883 {
884 struct tst_ts res;
885
886 res = tst_ts_add(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
887
888 return tst_ts_to_timespec(res);
889 }
890
891 /*
892 * Substract two tst_ts structures.
893 */
894 static inline struct tst_ts
tst_ts_diff(struct tst_ts t1,struct tst_ts t2)895 tst_ts_diff(struct tst_ts t1, struct tst_ts t2)
896 {
897 struct tst_ts res = {.type = t1.type};
898
899 tst_ts_set_sec(&res, tst_ts_get_sec(t1) - tst_ts_get_sec(t2));
900 tst_ts_set_nsec(&res, tst_ts_get_nsec(t1) - tst_ts_get_nsec(t2));
901
902 return tst_ts_normalize(res);
903 }
904
905 /*
906 * Substract two timespec structures.
907 */
908 static inline struct timespec
tst_timespec_diff(struct timespec ts1,struct timespec ts2)909 tst_timespec_diff(struct timespec ts1, struct timespec ts2)
910 {
911 struct tst_ts res;
912
913 res = tst_ts_diff(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
914
915 return tst_ts_to_timespec(res);
916 }
917
918 /*
919 * Substract two tst_ts structures returns number of nanoseconds.
920 */
921 static inline long long
tst_ts_diff_ns(struct tst_ts t1,struct tst_ts t2)922 tst_ts_diff_ns(struct tst_ts t1, struct tst_ts t2)
923 {
924 return tst_ts_to_ns(tst_ts_diff(t1, t2));
925 }
926
927 /*
928 * Substract two timespec structures returns number of nanoseconds.
929 */
930 static inline long long
tst_timespec_diff_ns(struct timespec ts1,struct timespec ts2)931 tst_timespec_diff_ns(struct timespec ts1, struct timespec ts2)
932 {
933 return tst_ts_diff_ns(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
934 }
935
936 /*
937 * Substract two tst_ts structures returns number of microseconds.
938 */
939 static inline long long
tst_ts_diff_us(struct tst_ts t1,struct tst_ts t2)940 tst_ts_diff_us(struct tst_ts t1, struct tst_ts t2)
941 {
942 return tst_ts_to_us(tst_ts_diff(t1, t2));
943 }
944
945 /*
946 * Substract two timespec structures returns number of microseconds.
947 */
948 static inline long long
tst_timespec_diff_us(struct timespec ts1,struct timespec ts2)949 tst_timespec_diff_us(struct timespec ts1, struct timespec ts2)
950 {
951 return tst_ts_diff_us(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
952 }
953
954 /*
955 * Substract two tst_ts structures returns number of milliseconds.
956 */
957 static inline long long
tst_ts_diff_ms(struct tst_ts t1,struct tst_ts t2)958 tst_ts_diff_ms(struct tst_ts t1, struct tst_ts t2)
959 {
960 return tst_ts_to_ms(tst_ts_diff(t1, t2));
961 }
962
963 /*
964 * Substract two timespec structures returns number of milliseconds.
965 */
966 static inline long long
tst_timespec_diff_ms(struct timespec ts1,struct timespec ts2)967 tst_timespec_diff_ms(struct timespec ts1, struct timespec ts2)
968 {
969 return tst_ts_diff_ms(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
970 }
971
972 /*
973 * Returns absolute value of difference between two timespec structures.
974 */
975 static inline struct tst_ts
tst_ts_abs_diff(struct tst_ts t1,struct tst_ts t2)976 tst_ts_abs_diff(struct tst_ts t1, struct tst_ts t2)
977 {
978 if (tst_ts_lt(t1, t2))
979 return tst_ts_diff(t2, t1);
980 else
981 return tst_ts_diff(t1, t2);
982 }
983
984 /*
985 * Returns absolute value of difference between two tst_ts structures in
986 * microseconds.
987 */
988 static inline long long
tst_ts_abs_diff_us(struct tst_ts t1,struct tst_ts t2)989 tst_ts_abs_diff_us(struct tst_ts t1, struct tst_ts t2)
990 {
991 return tst_ts_to_us(tst_ts_abs_diff(t1, t2));
992 }
993
994 /*
995 * Returns absolute value of difference between two timespec structures in
996 * microseconds.
997 */
998 static inline long long
tst_timespec_abs_diff_us(struct timespec ts1,struct timespec ts2)999 tst_timespec_abs_diff_us(struct timespec ts1, struct timespec ts2)
1000 {
1001 return tst_ts_abs_diff_us(tst_ts_from_timespec(ts1), tst_ts_from_timespec(ts2));
1002 }
1003
1004 /*
1005 * Returns absolute value of difference between two timespec structures in
1006 * milliseconds.
1007 */
1008 static inline long long
tst_ts_abs_diff_ms(struct tst_ts t1,struct tst_ts t2)1009 tst_ts_abs_diff_ms(struct tst_ts t1, struct tst_ts t2)
1010 {
1011 return tst_ts_to_ms(tst_ts_abs_diff(t1, t2));
1012 }
1013
1014 /*
1015 * Exits the test with TCONF if particular timer is not supported. This is
1016 * intended to be used in test setup. There is no cleanup callback parameter as
1017 * you are expected to call it before initializing any resources that has to be
1018 * cleaned up later.
1019 *
1020 * @clk_id: Posix clock to use.
1021 */
1022 void tst_timer_check(clockid_t clk_id);
1023
1024 /*
1025 * Marks a start time for given clock type.
1026 *
1027 * @clk_id: Posix clock to use.
1028 */
1029 void tst_timer_start(clockid_t clk_id);
1030
1031 /*
1032 * Returns true if timer started by tst_timer_start() has been running for
1033 * longer than ms seconds.
1034 *
1035 * @ms: Time interval in milliseconds.
1036 */
1037 int tst_timer_expired_ms(long long ms);
1038
1039 /*
1040 * Marks timer end time.
1041 */
1042 void tst_timer_stop(void);
1043
1044 /*
1045 * Retuns elapsed time in struct timespec.
1046 */
1047 struct timespec tst_timer_elapsed(void);
1048
1049 /*
1050 * Returns elapsed time in milliseconds.
1051 */
tst_timer_elapsed_ms(void)1052 static inline long long tst_timer_elapsed_ms(void)
1053 {
1054 return tst_timespec_to_ms(tst_timer_elapsed());
1055 }
1056
1057 /*
1058 * Returns elapsed time in microseconds.
1059 */
tst_timer_elapsed_us(void)1060 static inline long long tst_timer_elapsed_us(void)
1061 {
1062 return tst_timespec_to_us(tst_timer_elapsed());
1063 }
1064
1065 #endif /* TST_TIMER */
1066