• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright (C) 2015-2020 Cyril Hrubis <chrubis@suse.cz>
3  */
4 
5  /*
6 
7    Timer - struct timespec conversion runtimes and easy to use functions to
8            measure elapsed time.
9 
10   */
11 
12 #ifndef TST_TIMER
13 #define TST_TIMER
14 
15 #include <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