blob: 82ec402ccd7f379d29d9572a9e87f0f348ecdc38 [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 Tarreaub7f694f2008-06-22 17:18:02 +020057extern struct timeval now; /* internal date is a monotonic function of real clock */
58extern struct timeval date; /* the real current date */
Willy Tarreaubaaee002006-06-26 02:48:02 +020059extern struct timeval start_date; /* the process's start date */
60
61
Willy Tarreau42aae5c2007-04-29 17:43:56 +020062/**** exported functions *************************************************/
63
64
Willy Tarreaubaaee002006-06-26 02:48:02 +020065/*
66 * adds <ms> ms to <from>, set the result to <tv> and returns a pointer <tv>
67 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020068REGPRM3 struct timeval *tv_ms_add(struct timeval *tv, const struct timeval *from, int ms);
Willy Tarreaubaaee002006-06-26 02:48:02 +020069
70/*
71 * 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 +020072 * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that.
Willy Tarreaubaaee002006-06-26 02:48:02 +020073 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020074REGPRM2 int tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +020075
76/*
Willy Tarreau8d7d1492007-04-29 10:50:43 +020077 * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
78 * assuming that TV_ETERNITY is greater than everything.
Willy Tarreaubaaee002006-06-26 02:48:02 +020079 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020080REGPRM2 int tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau5e8f0662007-02-12 00:59:08 +010081
Willy Tarreau42aae5c2007-04-29 17:43:56 +020082/**** general purpose functions and macros *******************************/
83
84
85/* tv_now: sets <tv> to the current time */
86REGPRM1 static inline struct timeval *tv_now(struct timeval *tv)
87{
88 gettimeofday(tv, NULL);
89 return tv;
90}
Willy Tarreaubaaee002006-06-26 02:48:02 +020091
Willy Tarreaub0b37bc2008-06-23 14:00:57 +020092/* tv_udpate_date: sets <date> to system time, and sets <now> to something as
93 * close as possible to real time, following a monotonic function. The main
94 * principle consists in detecting backwards and forwards time jumps and adjust
95 * an offset to correct them. This function should be called only once after
96 * each poll. The poll's timeout should be passed in <max_wait>, and the return
97 * value in <interrupted> (a non-zero value means that we have not expired the
98 * timeout).
Willy Tarreaub7f694f2008-06-22 17:18:02 +020099 */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +0200100REGPRM2 void tv_update_date(int max_wait, int interrupted);
Willy Tarreaub7f694f2008-06-22 17:18:02 +0200101
Willy Tarreaubaaee002006-06-26 02:48:02 +0200102/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200103 * sets a struct timeval to its highest value so that it can never happen
104 * note that only tv_usec is necessary to detect it since a tv_usec > 999999
105 * is normally not possible.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200106 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200107REGPRM1 static inline struct timeval *tv_eternity(struct timeval *tv)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200108{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200109 tv->tv_sec = tv->tv_usec = TV_ETERNITY;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200110 return tv;
111}
112
113/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200114 * sets a struct timeval to 0
115 *
Willy Tarreaubaaee002006-06-26 02:48:02 +0200116 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200117REGPRM1 static inline struct timeval *tv_zero(struct timeval *tv) {
118 tv->tv_sec = tv->tv_usec = 0;
119 return tv;
120}
121
122/*
123 * returns non null if tv is [eternity], otherwise 0.
124 */
125#define tv_iseternity(tv) ((tv)->tv_usec == TV_ETERNITY)
126
127/*
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200128 * returns 0 if tv is [eternity], otherwise non-zero.
129 */
130#define tv_isset(tv) ((tv)->tv_usec != TV_ETERNITY)
131
132/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200133 * returns non null if tv is [0], otherwise 0.
134 */
135#define tv_iszero(tv) (((tv)->tv_sec | (tv)->tv_usec) == 0)
136
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200137/*
138 * Converts a struct timeval to a number of milliseconds.
139 */
140REGPRM1 static inline unsigned long __tv_to_ms(const struct timeval *tv)
141{
142 unsigned long ret;
143
144 ret = tv->tv_sec * 1000;
145 ret += tv->tv_usec / 1000;
146 return ret;
147}
148
149/*
150 * Converts a struct timeval to a number of milliseconds.
151 */
152REGPRM2 static inline struct timeval * __tv_from_ms(struct timeval *tv, unsigned long ms)
153{
154 tv->tv_sec = ms / 1000;
155 tv->tv_usec = (ms % 1000) * 1000;
156 return tv;
157}
158
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200159
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200160/**** comparison functions and macros ***********************************/
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200161
162
163/* tv_cmp: compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2. */
164REGPRM2 static inline int __tv_cmp(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200165{
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200166 if ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200167 return -1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200168 else if ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200169 return 1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200170 else if ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200171 return -1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200172 else if ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200173 return 1;
174 else
175 return 0;
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100176}
177
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200178/* tv_iseq: compares <tv1> and <tv2> : returns 1 if tv1 == tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200179#define tv_iseq __tv_iseq
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200180REGPRM2 static inline int __tv_iseq(const struct timeval *tv1, const struct timeval *tv2)
181{
Willy Tarreau0481c202007-05-13 16:03:27 +0200182 return ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) &&
183 ((unsigned)tv1->tv_usec == (unsigned)tv2->tv_usec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200184}
185
186/* tv_isgt: compares <tv1> and <tv2> : returns 1 if tv1 > tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200187#define tv_isgt _tv_isgt
188REGPRM2 int _tv_isgt(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200189REGPRM2 static inline int __tv_isgt(const struct timeval *tv1, const struct timeval *tv2)
190{
Willy Tarreau0481c202007-05-13 16:03:27 +0200191 return
192 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
193 ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec) :
194 ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200195}
196
197/* tv_isge: compares <tv1> and <tv2> : returns 1 if tv1 >= tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200198#define tv_isge __tv_isge
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200199REGPRM2 static inline int __tv_isge(const struct timeval *tv1, const struct timeval *tv2)
200{
Willy Tarreau0481c202007-05-13 16:03:27 +0200201 return
202 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
203 ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec) :
204 ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200205}
206
207/* tv_islt: compares <tv1> and <tv2> : returns 1 if tv1 < tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200208#define tv_islt __tv_islt
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200209REGPRM2 static inline int __tv_islt(const struct timeval *tv1, const struct timeval *tv2)
210{
Willy Tarreau0481c202007-05-13 16:03:27 +0200211 return
212 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
213 ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec) :
214 ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200215}
216
217/* tv_isle: compares <tv1> and <tv2> : returns 1 if tv1 <= tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200218#define tv_isle _tv_isle
219REGPRM2 int _tv_isle(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200220REGPRM2 static inline int __tv_isle(const struct timeval *tv1, const struct timeval *tv2)
221{
Willy Tarreau0481c202007-05-13 16:03:27 +0200222 return
223 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
224 ((unsigned)tv1->tv_usec <= (unsigned)tv2->tv_usec) :
225 ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200226}
227
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100228/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200229 * compares <tv1> and <tv2> modulo 1ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2
230 * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that.
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100231 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200232#define tv_ms_cmp _tv_ms_cmp
233REGPRM2 int _tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2);
234REGPRM2 static inline int __tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100235{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200236 if ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) {
237 if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000)
238 return -1;
239 else if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec + 1000)
240 return 1;
241 else
242 return 0;
243 }
244 else if (((unsigned)tv2->tv_sec > (unsigned)tv1->tv_sec + 1) ||
245 (((unsigned)tv2->tv_sec == (unsigned)tv1->tv_sec + 1) &&
246 ((unsigned)tv2->tv_usec + 1000000 >= (unsigned)tv1->tv_usec + 1000)))
247 return -1;
248 else if (((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1) ||
249 (((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) &&
250 ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000)))
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100251 return 1;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200252 else
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100253 return 0;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200254}
255
256/*
257 * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
258 * assuming that TV_ETERNITY is greater than everything.
259 */
260#define tv_ms_cmp2 _tv_ms_cmp2
261REGPRM2 int _tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2);
262REGPRM2 static inline int __tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2)
263{
264 if (tv_iseternity(tv1))
265 if (tv_iseternity(tv2))
266 return 0; /* same */
267 else
268 return 1; /* tv1 later than tv2 */
269 else if (tv_iseternity(tv2))
270 return -1; /* tv2 later than tv1 */
271 return tv_ms_cmp(tv1, tv2);
272}
273
274/*
275 * compares <tv1> and <tv2> modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2,
276 * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is
277 * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace
278 * occurrences of (tv_ms_cmp2(tv,now) <= 0).
279 */
280#define tv_ms_le2 _tv_ms_le2
281REGPRM2 int _tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2);
282REGPRM2 static inline int __tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2)
283{
284 if (likely((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1))
285 return 0;
286
287 if (likely((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec))
288 return 1;
289
290 if (likely((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec)) {
291 if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000)
292 return 1;
293 else
294 return 0;
295 }
296
297 if (unlikely(((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) &&
298 ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000)))
299 return 0;
300 else
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100301 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200302}
303
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200304
305/**** operators **********************************************************/
306
307
Willy Tarreaubaaee002006-06-26 02:48:02 +0200308/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200309 * Returns the time in ms elapsed between tv1 and tv2, assuming that tv1<=tv2.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200310 * Must not be used when either argument is eternity.
311 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200312#define tv_ms_elapsed __tv_ms_elapsed
313REGPRM2 unsigned long _tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2);
314REGPRM2 static inline unsigned long __tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200315{
316 unsigned long ret;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200317
318 ret = ((signed long)(tv2->tv_sec - tv1->tv_sec)) * 1000;
319 ret += ((signed long)(tv2->tv_usec - tv1->tv_usec)) / 1000;
320 return ret;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200321}
322
323/*
324 * returns the remaining time between tv1=now and event=tv2
325 * if tv2 is passed, 0 is returned.
326 * Must not be used when either argument is eternity.
327 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200328
329#define tv_ms_remain __tv_ms_remain
330REGPRM2 unsigned long _tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2);
331REGPRM2 static inline unsigned long __tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200332{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200333 if (tv_ms_cmp(tv1, tv2) >= 0)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200334 return 0; /* event elapsed */
335
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200336 return __tv_ms_elapsed(tv1, tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200337}
338
Willy Tarreaubaaee002006-06-26 02:48:02 +0200339/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200340 * returns the remaining time between tv1=now and event=tv2
341 * if tv2 is passed, 0 is returned.
342 * Returns TIME_ETERNITY if tv2 is eternity.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200343 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200344#define tv_ms_remain2 _tv_ms_remain2
345REGPRM2 unsigned long _tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2);
346REGPRM2 static inline unsigned long __tv_ms_remain2(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_iseternity(tv2))
349 return TIME_ETERNITY;
350
351 return tv_ms_remain(tv1, tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200352}
353
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200354/*
355 * adds <inc> to <from>, set the result to <tv> and returns a pointer <tv>
356 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200357#define tv_add _tv_add
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200358REGPRM3 struct timeval *_tv_add(struct timeval *tv, const struct timeval *from, const struct timeval *inc);
359REGPRM3 static inline struct timeval *__tv_add(struct timeval *tv, const struct timeval *from, const struct timeval *inc)
360{
361 tv->tv_usec = from->tv_usec + inc->tv_usec;
362 tv->tv_sec = from->tv_sec + inc->tv_sec;
363 if (tv->tv_usec >= 1000000) {
364 tv->tv_usec -= 1000000;
365 tv->tv_sec++;
366 }
367 return tv;
368}
369
370
371/*
Willy Tarreau0481c202007-05-13 16:03:27 +0200372 * If <inc> is set, then add it to <from> and set the result to <tv>, then
373 * return 1, otherwise return 0. It is meant to be used in if conditions.
374 */
375#define tv_add_ifset _tv_add_ifset
376REGPRM3 int _tv_add_ifset(struct timeval *tv, const struct timeval *from, const struct timeval *inc);
377REGPRM3 static inline int __tv_add_ifset(struct timeval *tv, const struct timeval *from, const struct timeval *inc)
378{
379 if (tv_iseternity(inc))
380 return 0;
381 tv->tv_usec = from->tv_usec + inc->tv_usec;
382 tv->tv_sec = from->tv_sec + inc->tv_sec;
383 if (tv->tv_usec >= 1000000) {
384 tv->tv_usec -= 1000000;
385 tv->tv_sec++;
386 }
387 return 1;
388}
389
390/*
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200391 * adds <inc> to <tv> and returns a pointer <tv>
392 */
393REGPRM2 static inline struct timeval *__tv_add2(struct timeval *tv, const struct timeval *inc)
394{
395 tv->tv_usec += inc->tv_usec;
396 tv->tv_sec += inc->tv_sec;
397 if (tv->tv_usec >= 1000000) {
398 tv->tv_usec -= 1000000;
399 tv->tv_sec++;
400 }
401 return tv;
402}
403
404
405/*
406 * Computes the remaining time between tv1=now and event=tv2. if tv2 is passed,
407 * 0 is returned. The result is stored into tv.
408 */
409#define tv_remain _tv_remain
410REGPRM3 struct timeval *_tv_remain(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv);
411REGPRM3 static inline struct timeval *__tv_remain(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv)
412{
413 tv->tv_usec = tv2->tv_usec - tv1->tv_usec;
414 tv->tv_sec = tv2->tv_sec - tv1->tv_sec;
415 if ((signed)tv->tv_sec > 0) {
416 if ((signed)tv->tv_usec < 0) {
417 tv->tv_usec += 1000000;
418 tv->tv_sec--;
419 }
420 } else if (tv->tv_sec == 0) {
421 if ((signed)tv->tv_usec < 0)
422 tv->tv_usec = 0;
423 } else {
424 tv->tv_sec = 0;
425 tv->tv_usec = 0;
426 }
427 return tv;
428}
429
430
431/*
432 * Computes the remaining time between tv1=now and event=tv2. if tv2 is passed,
433 * 0 is returned. The result is stored into tv. Returns ETERNITY if tv2 is
434 * eternity.
435 */
436#define tv_remain2 _tv_remain2
437REGPRM3 struct timeval *_tv_remain2(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv);
438REGPRM3 static inline struct timeval *__tv_remain2(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv)
439{
440 if (tv_iseternity(tv2))
441 return tv_eternity(tv);
442 return __tv_remain(tv1, tv2, tv);
443}
444
445
Willy Tarreaubaaee002006-06-26 02:48:02 +0200446/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200447 * adds <ms> ms to <from>, set the result to <tv> and returns a pointer <tv>
Willy Tarreaubaaee002006-06-26 02:48:02 +0200448 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200449#define tv_ms_add _tv_ms_add
450REGPRM3 struct timeval *_tv_ms_add(struct timeval *tv, const struct timeval *from, int ms);
451REGPRM3 static inline struct timeval *__tv_ms_add(struct timeval *tv, const struct timeval *from, int ms)
452{
453 tv->tv_usec = from->tv_usec + (ms % 1000) * 1000;
454 tv->tv_sec = from->tv_sec + (ms / 1000);
455 while (tv->tv_usec >= 1000000) {
456 tv->tv_usec -= 1000000;
457 tv->tv_sec++;
458 }
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200459 return tv;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200460}
461
Willy Tarreaubaaee002006-06-26 02:48:02 +0200462
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200463/*
464 * compares <tv1> and <tv2> : returns 1 if <tv1> is before <tv2>, otherwise 0.
465 * This should be very fast because it's used in schedulers.
466 * It has been optimized to return 1 (so call it in a loop which continues
467 * as long as tv1<=tv2)
468 */
469
470#define tv_isbefore(tv1, tv2) \
471 (unlikely((unsigned)(tv1)->tv_sec < (unsigned)(tv2)->tv_sec) ? 1 : \
472 (unlikely((unsigned)(tv1)->tv_sec > (unsigned)(tv2)->tv_sec) ? 0 : \
473 unlikely((unsigned)(tv1)->tv_usec < (unsigned)(tv2)->tv_usec)))
474
475/*
476 * returns the first event between <tv1> and <tv2> into <tvmin>.
477 * a zero tv is ignored. <tvmin> is returned. If <tvmin> is known
478 * to be the same as <tv1> or <tv2>, it is recommended to use
479 * tv_bound instead.
480 */
481#define tv_min(tvmin, tv1, tv2) ({ \
482 if (tv_isbefore(tv1, tv2)) { \
483 *tvmin = *tv1; \
484 } \
485 else { \
486 *tvmin = *tv2; \
487 } \
488 tvmin; \
489})
490
491/*
492 * returns the first event between <tv1> and <tv2> into <tvmin>.
493 * a zero tv is ignored. <tvmin> is returned. This function has been
494 * optimized to be called as tv_min(a,a,b) or tv_min(b,a,b).
495 */
496#define tv_bound(tv1, tv2) ({ \
497 if (tv_isbefore(tv2, tv1)) \
498 *tv1 = *tv2; \
499 tv1; \
500})
Willy Tarreaubaaee002006-06-26 02:48:02 +0200501
Willy Tarreauc8f24f82007-11-30 18:38:35 +0100502char *human_time(int t, short hz_div);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200503
Willy Tarreau2dd0d472006-06-29 17:53:05 +0200504#endif /* _COMMON_TIME_H */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200505
506/*
507 * Local variables:
508 * c-indent-level: 8
509 * c-basic-offset: 8
510 * End:
511 */