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