1 /* 2 * Copyright (C) 2015 Cyril Hrubis <chrubis (at) 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 static inline long long tst_timespec_to_ns(struct timespec t) 38 { 39 return t.tv_sec * 1000000000 + t.tv_nsec; 40 } 41 42 /* 43 * Converts timespec to microseconds. 44 */ 45 static inline long long tst_timespec_to_us(struct timespec t) 46 { 47 return t.tv_sec * 1000000 + (t.tv_nsec + 500) / 1000; 48 } 49 50 /* 51 * Converts timespec to miliseconds. 52 */ 53 static inline long long tst_timespec_to_ms(struct timespec t) 54 { 55 return t.tv_sec * 1000 + (t.tv_nsec + 500000) / 1000000; 56 } 57 58 /* 59 * Converts timeval to microseconds. 60 */ 61 static inline long long tst_timeval_to_us(struct timeval t) 62 { 63 return t.tv_sec * 1000000 + t.tv_usec; 64 } 65 66 /* 67 * Converts timeval to miliseconds. 68 */ 69 static inline long long tst_timeval_to_ms(struct timeval t) 70 { 71 return t.tv_sec * 1000 + (t.tv_usec + 500) / 1000; 72 } 73 74 /* 75 * Converts ms to struct timeval 76 */ 77 static inline struct timeval tst_ms_to_timeval(long long ms) 78 { 79 struct timeval ret; 80 81 ret.tv_sec = ms / 1000; 82 ret.tv_usec = (ms % 1000) * 1000; 83 84 return ret; 85 } 86 87 /* 88 * Converts us to struct timeval 89 */ 90 static inline struct timeval tst_us_to_timeval(long long us) 91 { 92 struct timeval ret; 93 94 ret.tv_sec = us / 1000000; 95 ret.tv_usec = us % 1000000; 96 97 return ret; 98 } 99 100 /* 101 * Converts ms to struct timespec 102 */ 103 static inline struct timespec tst_ms_to_timespec(long long ms) 104 { 105 struct timespec ret; 106 107 ret.tv_sec = ms / 1000; 108 ret.tv_nsec = (ms % 1000) * 1000000; 109 110 return ret; 111 } 112 113 /* 114 * Converts us to struct timespec 115 */ 116 static inline struct timespec tst_us_to_timespec(long long us) 117 { 118 struct timespec ret; 119 120 ret.tv_sec = us / 1000000; 121 ret.tv_nsec = (us % 1000000) * 1000; 122 123 return ret; 124 } 125 126 /* 127 * Comparsions 128 */ 129 static inline int tst_timespec_lt(struct timespec t1, struct timespec t2) 130 { 131 if (t1.tv_sec == t2.tv_sec) 132 return t1.tv_nsec < t2.tv_nsec; 133 134 return t1.tv_sec < t2.tv_sec; 135 } 136 137 /* 138 * Adds us microseconds to t. 139 */ 140 static inline struct timespec tst_timespec_add_us(struct timespec t, 141 long long us) 142 { 143 t.tv_sec += us / 1000000; 144 t.tv_nsec += (us % 1000000) * 1000; 145 146 if (t.tv_nsec >= 1000000000) { 147 t.tv_sec++; 148 t.tv_nsec -= 1000000000; 149 } 150 151 return t; 152 } 153 154 /* 155 * Returns difference between two timespec structures. 156 */ 157 static inline struct timespec tst_timespec_diff(struct timespec t1, 158 struct timespec t2) 159 { 160 struct timespec res; 161 162 res.tv_sec = t1.tv_sec - t2.tv_sec; 163 164 if (t1.tv_nsec < t2.tv_nsec) { 165 res.tv_sec--; 166 res.tv_nsec = 1000000000 - (t2.tv_nsec - t1.tv_nsec); 167 } else { 168 res.tv_nsec = t1.tv_nsec - t2.tv_nsec; 169 } 170 171 return res; 172 } 173 174 static inline long long tst_timespec_diff_ns(struct timespec t1, 175 struct timespec t2) 176 { 177 return t1.tv_nsec - t2.tv_nsec + 1000000000LL * (t1.tv_sec - t2.tv_sec); 178 } 179 180 static inline long long tst_timespec_diff_us(struct timespec t1, 181 struct timespec t2) 182 { 183 return tst_timespec_to_us(tst_timespec_diff(t1, t2)); 184 } 185 186 static inline long long tst_timespec_diff_ms(struct timespec t1, 187 struct timespec t2) 188 { 189 return tst_timespec_to_ms(tst_timespec_diff(t1, t2)); 190 } 191 192 /* 193 * Returns difference between two timeval structures. 194 */ 195 static inline struct timeval tst_timeval_diff(struct timeval t1, 196 struct timeval t2) 197 { 198 struct timeval res; 199 200 res.tv_sec = t1.tv_sec - t2.tv_sec; 201 202 if (t1.tv_usec < t2.tv_usec) { 203 res.tv_sec--; 204 res.tv_usec = 1000000 - (t2.tv_usec - t1.tv_usec); 205 } else { 206 res.tv_usec = t1.tv_usec - t2.tv_usec; 207 } 208 209 return res; 210 } 211 212 static inline long long tst_timeval_diff_us(struct timeval t1, 213 struct timeval t2) 214 { 215 return tst_timeval_to_us(tst_timeval_diff(t1, t2)); 216 } 217 218 static inline long long tst_timeval_diff_ms(struct timeval t1, 219 struct timeval t2) 220 { 221 return tst_timeval_to_ms(tst_timeval_diff(t1, t2)); 222 } 223 224 /* 225 * Returns absolute value of difference between two timespec structures. 226 */ 227 static inline struct timespec tst_timespec_abs_diff(struct timespec t1, 228 struct timespec t2) 229 { 230 if (tst_timespec_lt(t1, t2)) 231 return tst_timespec_diff(t2, t1); 232 else 233 return tst_timespec_diff(t1, t2); 234 } 235 236 static inline long long tst_timespec_abs_diff_us(struct timespec t1, 237 struct timespec t2) 238 { 239 return tst_timespec_to_us(tst_timespec_abs_diff(t1, t2)); 240 } 241 242 static inline long long tst_timespec_abs_diff_ms(struct timespec t1, 243 struct timespec t2) 244 { 245 return tst_timespec_to_ms(tst_timespec_abs_diff(t1, t2)); 246 } 247 248 /* 249 * Exits the test with TCONF if particular timer is not supported. This is 250 * intended to be used in test setup. There is no cleanup callback parameter as 251 * you are expected to call it before initializing any resources that has to be 252 * cleaned up later. 253 * 254 * @clk_id: Posix clock to use. 255 */ 256 void tst_timer_check(clockid_t clk_id); 257 258 /* 259 * Marks a start time for given clock type. 260 * 261 * @clk_id: Posix clock to use. 262 */ 263 void tst_timer_start(clockid_t clk_id); 264 265 /* 266 * Returns true if timer started by tst_timer_start() has been running for 267 * longer than ms seconds. 268 * 269 * @ms: Time interval in miliseconds. 270 */ 271 int tst_timer_expired_ms(long long ms); 272 273 /* 274 * Marks timer end time. 275 */ 276 void tst_timer_stop(void); 277 278 /* 279 * Retuns elapsed time in struct timespec. 280 */ 281 struct timespec tst_timer_elapsed(void); 282 283 /* 284 * Returns elapsed time in miliseconds. 285 */ 286 static inline long long tst_timer_elapsed_ms(void) 287 { 288 return tst_timespec_to_ms(tst_timer_elapsed()); 289 } 290 291 /* 292 * Returns elapsed time in microseconds. 293 */ 294 static inline long long tst_timer_elapsed_us(void) 295 { 296 return tst_timespec_to_us(tst_timer_elapsed()); 297 } 298 299 #endif /* TST_TIMER */ 300