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