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