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 /* 38 * Converts timespec to microseconds. 39 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 */ 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 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 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 */ 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 */ 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