xref: /aosp_15_r20/external/ltp/include/tst_timer.h (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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