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 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