blob: abc1ccfa3f356ea4307a340fd26f52ec274e8502 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
Willy Tarreau2dd0d472006-06-29 17:53:05 +02002 include/common/time.h
Willy Tarreaubaaee002006-06-26 02:48:02 +02003 Time calculation functions and macros.
4
Willy Tarreaub7f694f2008-06-22 17:18:02 +02005 Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
Willy Tarreaubaaee002006-06-26 02:48:02 +02006
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation, version 2.1
10 exclusively.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
Willy Tarreau2dd0d472006-06-29 17:53:05 +020022#ifndef _COMMON_TIME_H
23#define _COMMON_TIME_H
Willy Tarreaubaaee002006-06-26 02:48:02 +020024
25#include <stdlib.h>
26#include <sys/time.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020027#include <common/config.h>
Willy Tarreau42aae5c2007-04-29 17:43:56 +020028#include <common/standard.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020029
Krzysztof Oledzki85130942007-10-22 16:21:10 +020030#define SEC 1
31#define MINUTE (60 * SEC)
32#define HOUR (60 * MINUTE)
33#define DAY (24 * HOUR)
34
Willy Tarreaua6a6a932007-04-28 22:40:08 +020035/* eternity when exprimed in timeval */
36#ifndef TV_ETERNITY
37#define TV_ETERNITY (~0UL)
38#endif
39
40/* eternity when exprimed in ms */
41#ifndef TV_ETERNITY_MS
42#define TV_ETERNITY_MS (-1)
43#endif
44
45#define TIME_ETERNITY (TV_ETERNITY_MS)
46
Willy Tarreaub0b37bc2008-06-23 14:00:57 +020047/* we want to be able to detect time jumps. Fix the maximum wait time to a low
48 * value so that we know the time has changed if we wait longer.
49 */
50#define MAX_DELAY_MS 1000
51
Willy Tarreaubaaee002006-06-26 02:48:02 +020052
53/* returns the lowest delay amongst <old> and <new>, and respects TIME_ETERNITY */
54#define MINTIME(old, new) (((new)<0)?(old):(((old)<0||(new)<(old))?(new):(old)))
55#define SETNOW(a) (*a=now)
56
Willy Tarreau75590582009-03-05 14:54:50 +010057extern unsigned int curr_sec_ms; /* millisecond of current second (0..999) */
58extern unsigned int curr_sec_ms_scaled; /* millisecond of current second (0..2^32-1) */
Willy Tarreaue6313a32008-06-29 13:47:25 +020059extern unsigned int now_ms; /* internal date in milliseconds (may wrap) */
Willy Tarreaub7f694f2008-06-22 17:18:02 +020060extern struct timeval now; /* internal date is a monotonic function of real clock */
61extern struct timeval date; /* the real current date */
Willy Tarreaubaaee002006-06-26 02:48:02 +020062extern struct timeval start_date; /* the process's start date */
63
64
Willy Tarreau42aae5c2007-04-29 17:43:56 +020065/**** exported functions *************************************************/
66
67
Willy Tarreaubaaee002006-06-26 02:48:02 +020068/*
69 * adds <ms> ms to <from>, set the result to <tv> and returns a pointer <tv>
70 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020071REGPRM3 struct timeval *tv_ms_add(struct timeval *tv, const struct timeval *from, int ms);
Willy Tarreaubaaee002006-06-26 02:48:02 +020072
73/*
74 * compares <tv1> and <tv2> modulo 1ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2
Willy Tarreau42aae5c2007-04-29 17:43:56 +020075 * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that.
Willy Tarreaubaaee002006-06-26 02:48:02 +020076 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020077REGPRM2 int tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +020078
79/*
Willy Tarreau8d7d1492007-04-29 10:50:43 +020080 * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
81 * assuming that TV_ETERNITY is greater than everything.
Willy Tarreaubaaee002006-06-26 02:48:02 +020082 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020083REGPRM2 int tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau5e8f0662007-02-12 00:59:08 +010084
Willy Tarreau42aae5c2007-04-29 17:43:56 +020085/**** general purpose functions and macros *******************************/
86
87
88/* tv_now: sets <tv> to the current time */
89REGPRM1 static inline struct timeval *tv_now(struct timeval *tv)
90{
91 gettimeofday(tv, NULL);
92 return tv;
93}
Willy Tarreaubaaee002006-06-26 02:48:02 +020094
Willy Tarreaub0b37bc2008-06-23 14:00:57 +020095/* tv_udpate_date: sets <date> to system time, and sets <now> to something as
96 * close as possible to real time, following a monotonic function. The main
97 * principle consists in detecting backwards and forwards time jumps and adjust
98 * an offset to correct them. This function should be called only once after
99 * each poll. The poll's timeout should be passed in <max_wait>, and the return
100 * value in <interrupted> (a non-zero value means that we have not expired the
101 * timeout).
Willy Tarreaub7f694f2008-06-22 17:18:02 +0200102 */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +0200103REGPRM2 void tv_update_date(int max_wait, int interrupted);
Willy Tarreaub7f694f2008-06-22 17:18:02 +0200104
Willy Tarreaubaaee002006-06-26 02:48:02 +0200105/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200106 * sets a struct timeval to its highest value so that it can never happen
107 * note that only tv_usec is necessary to detect it since a tv_usec > 999999
108 * is normally not possible.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200109 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200110REGPRM1 static inline struct timeval *tv_eternity(struct timeval *tv)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200111{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200112 tv->tv_sec = tv->tv_usec = TV_ETERNITY;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200113 return tv;
114}
115
116/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200117 * sets a struct timeval to 0
118 *
Willy Tarreaubaaee002006-06-26 02:48:02 +0200119 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200120REGPRM1 static inline struct timeval *tv_zero(struct timeval *tv) {
121 tv->tv_sec = tv->tv_usec = 0;
122 return tv;
123}
124
125/*
126 * returns non null if tv is [eternity], otherwise 0.
127 */
128#define tv_iseternity(tv) ((tv)->tv_usec == TV_ETERNITY)
129
130/*
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200131 * returns 0 if tv is [eternity], otherwise non-zero.
132 */
133#define tv_isset(tv) ((tv)->tv_usec != TV_ETERNITY)
134
135/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200136 * returns non null if tv is [0], otherwise 0.
137 */
138#define tv_iszero(tv) (((tv)->tv_sec | (tv)->tv_usec) == 0)
139
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200140/*
141 * Converts a struct timeval to a number of milliseconds.
142 */
143REGPRM1 static inline unsigned long __tv_to_ms(const struct timeval *tv)
144{
145 unsigned long ret;
146
147 ret = tv->tv_sec * 1000;
148 ret += tv->tv_usec / 1000;
149 return ret;
150}
151
152/*
153 * Converts a struct timeval to a number of milliseconds.
154 */
155REGPRM2 static inline struct timeval * __tv_from_ms(struct timeval *tv, unsigned long ms)
156{
157 tv->tv_sec = ms / 1000;
158 tv->tv_usec = (ms % 1000) * 1000;
159 return tv;
160}
161
Willy Tarreau776cd872009-03-05 00:34:01 +0100162/* Return a number of 1024Hz ticks between 0 and 1023 for input number of
163 * usecs between 0 and 999999. This function has been optimized to remove
164 * any divide and multiply, as it is completely optimized away by the compiler
165 * on CPUs which don't have a fast multiply. Its avg error rate is 305 ppm,
166 * which is almost twice as low as a direct usec to ms conversion. This version
167 * also has the benefit of returning 1024 for 1000000.
168 */
169REGPRM1 static inline unsigned int __usec_to_1024th(unsigned int usec)
170{
171 return (usec * 1073 + 742516) >> 20;
172}
173
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200174
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200175/**** comparison functions and macros ***********************************/
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200176
177
178/* tv_cmp: compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2. */
179REGPRM2 static inline int __tv_cmp(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200180{
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200181 if ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200182 return -1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200183 else if ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200184 return 1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200185 else if ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200186 return -1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200187 else if ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200188 return 1;
189 else
190 return 0;
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100191}
192
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200193/* tv_iseq: compares <tv1> and <tv2> : returns 1 if tv1 == tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200194#define tv_iseq __tv_iseq
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200195REGPRM2 static inline int __tv_iseq(const struct timeval *tv1, const struct timeval *tv2)
196{
Willy Tarreau0481c202007-05-13 16:03:27 +0200197 return ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) &&
198 ((unsigned)tv1->tv_usec == (unsigned)tv2->tv_usec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200199}
200
201/* tv_isgt: compares <tv1> and <tv2> : returns 1 if tv1 > tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200202#define tv_isgt _tv_isgt
203REGPRM2 int _tv_isgt(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200204REGPRM2 static inline int __tv_isgt(const struct timeval *tv1, const struct timeval *tv2)
205{
Willy Tarreau0481c202007-05-13 16:03:27 +0200206 return
207 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
208 ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec) :
209 ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200210}
211
212/* tv_isge: compares <tv1> and <tv2> : returns 1 if tv1 >= tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200213#define tv_isge __tv_isge
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200214REGPRM2 static inline int __tv_isge(const struct timeval *tv1, const struct timeval *tv2)
215{
Willy Tarreau0481c202007-05-13 16:03:27 +0200216 return
217 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
218 ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec) :
219 ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200220}
221
222/* tv_islt: compares <tv1> and <tv2> : returns 1 if tv1 < tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200223#define tv_islt __tv_islt
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200224REGPRM2 static inline int __tv_islt(const struct timeval *tv1, const struct timeval *tv2)
225{
Willy Tarreau0481c202007-05-13 16:03:27 +0200226 return
227 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
228 ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec) :
229 ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200230}
231
232/* tv_isle: compares <tv1> and <tv2> : returns 1 if tv1 <= tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200233#define tv_isle _tv_isle
234REGPRM2 int _tv_isle(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200235REGPRM2 static inline int __tv_isle(const struct timeval *tv1, const struct timeval *tv2)
236{
Willy Tarreau0481c202007-05-13 16:03:27 +0200237 return
238 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
239 ((unsigned)tv1->tv_usec <= (unsigned)tv2->tv_usec) :
240 ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200241}
242
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100243/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200244 * compares <tv1> and <tv2> modulo 1ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2
245 * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that.
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100246 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200247#define tv_ms_cmp _tv_ms_cmp
248REGPRM2 int _tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2);
249REGPRM2 static inline int __tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100250{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200251 if ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) {
252 if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000)
253 return -1;
254 else if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec + 1000)
255 return 1;
256 else
257 return 0;
258 }
259 else if (((unsigned)tv2->tv_sec > (unsigned)tv1->tv_sec + 1) ||
260 (((unsigned)tv2->tv_sec == (unsigned)tv1->tv_sec + 1) &&
261 ((unsigned)tv2->tv_usec + 1000000 >= (unsigned)tv1->tv_usec + 1000)))
262 return -1;
263 else if (((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1) ||
264 (((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) &&
265 ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000)))
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100266 return 1;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200267 else
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100268 return 0;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200269}
270
271/*
272 * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
273 * assuming that TV_ETERNITY is greater than everything.
274 */
275#define tv_ms_cmp2 _tv_ms_cmp2
276REGPRM2 int _tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2);
277REGPRM2 static inline int __tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2)
278{
279 if (tv_iseternity(tv1))
280 if (tv_iseternity(tv2))
281 return 0; /* same */
282 else
283 return 1; /* tv1 later than tv2 */
284 else if (tv_iseternity(tv2))
285 return -1; /* tv2 later than tv1 */
286 return tv_ms_cmp(tv1, tv2);
287}
288
289/*
290 * compares <tv1> and <tv2> modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2,
291 * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is
292 * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace
293 * occurrences of (tv_ms_cmp2(tv,now) <= 0).
294 */
295#define tv_ms_le2 _tv_ms_le2
296REGPRM2 int _tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2);
297REGPRM2 static inline int __tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2)
298{
299 if (likely((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1))
300 return 0;
301
302 if (likely((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec))
303 return 1;
304
305 if (likely((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec)) {
306 if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000)
307 return 1;
308 else
309 return 0;
310 }
311
312 if (unlikely(((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) &&
313 ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000)))
314 return 0;
315 else
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100316 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200317}
318
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200319
320/**** operators **********************************************************/
321
322
Willy Tarreaubaaee002006-06-26 02:48:02 +0200323/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200324 * Returns the time in ms elapsed between tv1 and tv2, assuming that tv1<=tv2.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200325 * Must not be used when either argument is eternity.
326 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200327#define tv_ms_elapsed __tv_ms_elapsed
328REGPRM2 unsigned long _tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2);
329REGPRM2 static inline unsigned long __tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200330{
331 unsigned long ret;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200332
333 ret = ((signed long)(tv2->tv_sec - tv1->tv_sec)) * 1000;
334 ret += ((signed long)(tv2->tv_usec - tv1->tv_usec)) / 1000;
335 return ret;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200336}
337
338/*
339 * returns the remaining time between tv1=now and event=tv2
340 * if tv2 is passed, 0 is returned.
341 * Must not be used when either argument is eternity.
342 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200343
344#define tv_ms_remain __tv_ms_remain
345REGPRM2 unsigned long _tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2);
346REGPRM2 static inline unsigned long __tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200347{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200348 if (tv_ms_cmp(tv1, tv2) >= 0)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200349 return 0; /* event elapsed */
350
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200351 return __tv_ms_elapsed(tv1, tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200352}
353
Willy Tarreaubaaee002006-06-26 02:48:02 +0200354/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200355 * returns the remaining time between tv1=now and event=tv2
356 * if tv2 is passed, 0 is returned.
357 * Returns TIME_ETERNITY if tv2 is eternity.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200358 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200359#define tv_ms_remain2 _tv_ms_remain2
360REGPRM2 unsigned long _tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2);
361REGPRM2 static inline unsigned long __tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200362{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200363 if (tv_iseternity(tv2))
364 return TIME_ETERNITY;
365
366 return tv_ms_remain(tv1, tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200367}
368
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200369/*
370 * adds <inc> to <from>, set the result to <tv> and returns a pointer <tv>
371 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200372#define tv_add _tv_add
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200373REGPRM3 struct timeval *_tv_add(struct timeval *tv, const struct timeval *from, const struct timeval *inc);
374REGPRM3 static inline struct timeval *__tv_add(struct timeval *tv, const struct timeval *from, const struct timeval *inc)
375{
376 tv->tv_usec = from->tv_usec + inc->tv_usec;
377 tv->tv_sec = from->tv_sec + inc->tv_sec;
378 if (tv->tv_usec >= 1000000) {
379 tv->tv_usec -= 1000000;
380 tv->tv_sec++;
381 }
382 return tv;
383}
384
385
386/*
Willy Tarreau0481c202007-05-13 16:03:27 +0200387 * If <inc> is set, then add it to <from> and set the result to <tv>, then
388 * return 1, otherwise return 0. It is meant to be used in if conditions.
389 */
390#define tv_add_ifset _tv_add_ifset
391REGPRM3 int _tv_add_ifset(struct timeval *tv, const struct timeval *from, const struct timeval *inc);
392REGPRM3 static inline int __tv_add_ifset(struct timeval *tv, const struct timeval *from, const struct timeval *inc)
393{
394 if (tv_iseternity(inc))
395 return 0;
396 tv->tv_usec = from->tv_usec + inc->tv_usec;
397 tv->tv_sec = from->tv_sec + inc->tv_sec;
398 if (tv->tv_usec >= 1000000) {
399 tv->tv_usec -= 1000000;
400 tv->tv_sec++;
401 }
402 return 1;
403}
404
405/*
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200406 * adds <inc> to <tv> and returns a pointer <tv>
407 */
408REGPRM2 static inline struct timeval *__tv_add2(struct timeval *tv, const struct timeval *inc)
409{
410 tv->tv_usec += inc->tv_usec;
411 tv->tv_sec += inc->tv_sec;
412 if (tv->tv_usec >= 1000000) {
413 tv->tv_usec -= 1000000;
414 tv->tv_sec++;
415 }
416 return tv;
417}
418
419
420/*
421 * Computes the remaining time between tv1=now and event=tv2. if tv2 is passed,
422 * 0 is returned. The result is stored into tv.
423 */
424#define tv_remain _tv_remain
425REGPRM3 struct timeval *_tv_remain(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv);
426REGPRM3 static inline struct timeval *__tv_remain(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv)
427{
428 tv->tv_usec = tv2->tv_usec - tv1->tv_usec;
429 tv->tv_sec = tv2->tv_sec - tv1->tv_sec;
430 if ((signed)tv->tv_sec > 0) {
431 if ((signed)tv->tv_usec < 0) {
432 tv->tv_usec += 1000000;
433 tv->tv_sec--;
434 }
435 } else if (tv->tv_sec == 0) {
436 if ((signed)tv->tv_usec < 0)
437 tv->tv_usec = 0;
438 } else {
439 tv->tv_sec = 0;
440 tv->tv_usec = 0;
441 }
442 return tv;
443}
444
445
446/*
447 * Computes the remaining time between tv1=now and event=tv2. if tv2 is passed,
448 * 0 is returned. The result is stored into tv. Returns ETERNITY if tv2 is
449 * eternity.
450 */
451#define tv_remain2 _tv_remain2
452REGPRM3 struct timeval *_tv_remain2(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv);
453REGPRM3 static inline struct timeval *__tv_remain2(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv)
454{
455 if (tv_iseternity(tv2))
456 return tv_eternity(tv);
457 return __tv_remain(tv1, tv2, tv);
458}
459
460
Willy Tarreaubaaee002006-06-26 02:48:02 +0200461/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200462 * adds <ms> ms to <from>, set the result to <tv> and returns a pointer <tv>
Willy Tarreaubaaee002006-06-26 02:48:02 +0200463 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200464#define tv_ms_add _tv_ms_add
465REGPRM3 struct timeval *_tv_ms_add(struct timeval *tv, const struct timeval *from, int ms);
466REGPRM3 static inline struct timeval *__tv_ms_add(struct timeval *tv, const struct timeval *from, int ms)
467{
468 tv->tv_usec = from->tv_usec + (ms % 1000) * 1000;
469 tv->tv_sec = from->tv_sec + (ms / 1000);
470 while (tv->tv_usec >= 1000000) {
471 tv->tv_usec -= 1000000;
472 tv->tv_sec++;
473 }
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200474 return tv;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200475}
476
Willy Tarreaubaaee002006-06-26 02:48:02 +0200477
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200478/*
479 * compares <tv1> and <tv2> : returns 1 if <tv1> is before <tv2>, otherwise 0.
480 * This should be very fast because it's used in schedulers.
481 * It has been optimized to return 1 (so call it in a loop which continues
482 * as long as tv1<=tv2)
483 */
484
485#define tv_isbefore(tv1, tv2) \
486 (unlikely((unsigned)(tv1)->tv_sec < (unsigned)(tv2)->tv_sec) ? 1 : \
487 (unlikely((unsigned)(tv1)->tv_sec > (unsigned)(tv2)->tv_sec) ? 0 : \
488 unlikely((unsigned)(tv1)->tv_usec < (unsigned)(tv2)->tv_usec)))
489
490/*
491 * returns the first event between <tv1> and <tv2> into <tvmin>.
492 * a zero tv is ignored. <tvmin> is returned. If <tvmin> is known
493 * to be the same as <tv1> or <tv2>, it is recommended to use
494 * tv_bound instead.
495 */
496#define tv_min(tvmin, tv1, tv2) ({ \
497 if (tv_isbefore(tv1, tv2)) { \
498 *tvmin = *tv1; \
499 } \
500 else { \
501 *tvmin = *tv2; \
502 } \
503 tvmin; \
504})
505
506/*
507 * returns the first event between <tv1> and <tv2> into <tvmin>.
508 * a zero tv is ignored. <tvmin> is returned. This function has been
509 * optimized to be called as tv_min(a,a,b) or tv_min(b,a,b).
510 */
511#define tv_bound(tv1, tv2) ({ \
512 if (tv_isbefore(tv2, tv1)) \
513 *tv1 = *tv2; \
514 tv1; \
515})
Willy Tarreaubaaee002006-06-26 02:48:02 +0200516
Willy Tarreauc8f24f82007-11-30 18:38:35 +0100517char *human_time(int t, short hz_div);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200518
Willy Tarreau2dd0d472006-06-29 17:53:05 +0200519#endif /* _COMMON_TIME_H */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200520
521/*
522 * Local variables:
523 * c-indent-level: 8
524 * c-basic-offset: 8
525 * End:
526 */