• Home
  • History
  • Annotate
  • 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