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