• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24  /*
25 
26    Timer - struct timespec conversion runtimes and easy to use functions to
27            measure elapsed time.
28 
29   */
30 
31 #ifndef TST_TIMER
32 #define TST_TIMER
33 
34 #include <sys/time.h>
35 #include <time.h>
36 
37 /*
38  * Converts timespec to microseconds.
39  */
tst_timespec_to_us(struct timespec t)40 static inline long long tst_timespec_to_us(struct timespec t)
41 {
42 	return t.tv_sec * 1000000 + (t.tv_nsec + 500) / 1000;
43 }
44 
45 /*
46  * Converts timespec to miliseconds.
47  */
tst_timespec_to_ms(struct timespec t)48 static inline long long tst_timespec_to_ms(struct timespec t)
49 {
50 	return t.tv_sec * 1000 + (t.tv_nsec + 500000) / 1000000;
51 }
52 
53 /*
54  * Converts ms to struct timeval
55  */
tst_ms_to_timeval(long long ms)56 static inline struct timeval tst_ms_to_timeval(long long ms)
57 {
58 	struct timeval ret;
59 
60 	ret.tv_sec = ms / 1000;
61 	ret.tv_usec = (ms % 1000) * 1000;
62 
63 	return ret;
64 }
65 
66 /*
67  * Converts us to struct timeval
68  */
tst_us_to_timeval(long long us)69 static inline struct timeval tst_us_to_timeval(long long us)
70 {
71 	struct timeval ret;
72 
73 	ret.tv_sec = us / 1000000;
74 	ret.tv_usec = us % 1000000;
75 
76 	return ret;
77 }
78 
79 /*
80  * Comparsions
81  */
tst_timespec_lt(struct timespec t1,struct timespec t2)82 static inline int tst_timespec_lt(struct timespec t1, struct timespec t2)
83 {
84 	if (t1.tv_sec == t2.tv_sec)
85 		return t1.tv_nsec < t2.tv_nsec;
86 
87 	return t1.tv_sec < t2.tv_sec;
88 }
89 
90 /*
91  * Adds us microseconds to t.
92  */
tst_timespec_add_us(struct timespec t,long long us)93 static inline struct timespec tst_timespec_add_us(struct timespec t,
94                                                   long long us)
95 {
96 	t.tv_sec += us / 1000000;
97 	t.tv_nsec += (us % 1000000) * 1000;
98 
99 	if (t.tv_nsec >= 1000000000) {
100 		t.tv_sec++;
101 		t.tv_nsec -= 1000000000;
102 	}
103 
104 	return t;
105 }
106 
107 /*
108  * Returns difference between two timespec structures.
109  */
tst_timespec_diff(struct timespec t1,struct timespec t2)110 static inline struct timespec tst_timespec_diff(struct timespec t1,
111                                                 struct timespec t2)
112 {
113 	struct timespec res;
114 
115 	res.tv_sec = t1.tv_sec - t2.tv_sec;
116 
117 	if (t1.tv_nsec < t2.tv_nsec) {
118 		res.tv_sec--;
119 		res.tv_nsec = 1000000000 - (t2.tv_nsec - t1.tv_nsec);
120 	} else {
121 		res.tv_nsec = t1.tv_nsec - t2.tv_nsec;
122 	}
123 
124 	return res;
125 }
126 
tst_timespec_diff_us(struct timespec t1,struct timespec t2)127 static inline long long tst_timespec_diff_us(struct timespec t1,
128                                              struct timespec t2)
129 {
130 	return tst_timespec_to_us(tst_timespec_diff(t1, t2));
131 }
132 
tst_timespec_diff_ms(struct timespec t1,struct timespec t2)133 static inline long long tst_timespec_diff_ms(struct timespec t1,
134                                              struct timespec t2)
135 {
136 	return tst_timespec_to_ms(tst_timespec_diff(t1, t2));
137 }
138 
139 /*
140  * Returns absolute value of difference between two timespec structures.
141  */
tst_timespec_abs_diff(struct timespec t1,struct timespec t2)142 static inline struct timespec tst_timespec_abs_diff(struct timespec t1,
143                                                     struct timespec t2)
144 {
145 	if (tst_timespec_lt(t1, t2))
146 		return tst_timespec_diff(t2, t1);
147 	else
148 		return tst_timespec_diff(t1, t2);
149 }
150 
tst_timespec_abs_diff_us(struct timespec t1,struct timespec t2)151 static inline long long tst_timespec_abs_diff_us(struct timespec t1,
152                                                  struct timespec t2)
153 {
154        return tst_timespec_to_us(tst_timespec_abs_diff(t1, t2));
155 }
156 
tst_timespec_abs_diff_ms(struct timespec t1,struct timespec t2)157 static inline long long tst_timespec_abs_diff_ms(struct timespec t1,
158                                                  struct timespec t2)
159 {
160        return tst_timespec_to_ms(tst_timespec_abs_diff(t1, t2));
161 }
162 
163 /*
164  * Exits the test with TCONF if particular timer is not supported. This is
165  * intended to be used in test setup. There is no cleanup callback parameter as
166  * you are expected to call it before initializing any resources that has to be
167  * cleaned up later.
168  *
169  * @clk_id: Posix clock to use.
170  */
171 void tst_timer_check(clockid_t clk_id);
172 
173 /*
174  * Marks a start time for given clock type.
175  *
176  * @clk_id: Posix clock to use.
177  */
178 void tst_timer_start(clockid_t clk_id);
179 
180 /*
181  * Marks timer end time.
182  */
183 void tst_timer_stop(void);
184 
185 /*
186  * Retuns elapsed time in struct timespec.
187  */
188 struct timespec tst_timer_elapsed(void);
189 
190 /*
191  * Returns elapsed time in miliseconds.
192  */
tst_timer_elapsed_ms(void)193 static inline long long tst_timer_elapsed_ms(void)
194 {
195 	return tst_timespec_to_ms(tst_timer_elapsed());
196 }
197 
198 /*
199  * Returns elapsed time in microseconds.
200  */
tst_timer_elapsed_us(void)201 static inline long long tst_timer_elapsed_us(void)
202 {
203 	return tst_timespec_to_us(tst_timer_elapsed());
204 }
205 
206 #endif /* TST_TIMER */
207