blob: 7dbed6d732d11bc4669382a3e516c9d859d1020c [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 Tarreaue6313a32008-06-29 13:47:25 +020057extern unsigned int now_ms; /* internal date in milliseconds (may wrap) */
Willy Tarreaub7f694f2008-06-22 17:18:02 +020058extern struct timeval now; /* internal date is a monotonic function of real clock */
59extern struct timeval date; /* the real current date */
Willy Tarreaubaaee002006-06-26 02:48:02 +020060extern struct timeval start_date; /* the process's start date */
61
62
Willy Tarreau42aae5c2007-04-29 17:43:56 +020063/**** exported functions *************************************************/
64
65
Willy Tarreaubaaee002006-06-26 02:48:02 +020066/*
67 * adds <ms> ms to <from>, set the result to <tv> and returns a pointer <tv>
68 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020069REGPRM3 struct timeval *tv_ms_add(struct timeval *tv, const struct timeval *from, int ms);
Willy Tarreaubaaee002006-06-26 02:48:02 +020070
71/*
72 * 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 +020073 * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that.
Willy Tarreaubaaee002006-06-26 02:48:02 +020074 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020075REGPRM2 int tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +020076
77/*
Willy Tarreau8d7d1492007-04-29 10:50:43 +020078 * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
79 * assuming that TV_ETERNITY is greater than everything.
Willy Tarreaubaaee002006-06-26 02:48:02 +020080 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +020081REGPRM2 int tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau5e8f0662007-02-12 00:59:08 +010082
Willy Tarreau42aae5c2007-04-29 17:43:56 +020083/**** general purpose functions and macros *******************************/
84
85
86/* tv_now: sets <tv> to the current time */
87REGPRM1 static inline struct timeval *tv_now(struct timeval *tv)
88{
89 gettimeofday(tv, NULL);
90 return tv;
91}
Willy Tarreaubaaee002006-06-26 02:48:02 +020092
Willy Tarreaub0b37bc2008-06-23 14:00:57 +020093/* tv_udpate_date: sets <date> to system time, and sets <now> to something as
94 * close as possible to real time, following a monotonic function. The main
95 * principle consists in detecting backwards and forwards time jumps and adjust
96 * an offset to correct them. This function should be called only once after
97 * each poll. The poll's timeout should be passed in <max_wait>, and the return
98 * value in <interrupted> (a non-zero value means that we have not expired the
99 * timeout).
Willy Tarreaub7f694f2008-06-22 17:18:02 +0200100 */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +0200101REGPRM2 void tv_update_date(int max_wait, int interrupted);
Willy Tarreaub7f694f2008-06-22 17:18:02 +0200102
Willy Tarreaubaaee002006-06-26 02:48:02 +0200103/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200104 * sets a struct timeval to its highest value so that it can never happen
105 * note that only tv_usec is necessary to detect it since a tv_usec > 999999
106 * is normally not possible.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200107 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200108REGPRM1 static inline struct timeval *tv_eternity(struct timeval *tv)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200109{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200110 tv->tv_sec = tv->tv_usec = TV_ETERNITY;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200111 return tv;
112}
113
114/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200115 * sets a struct timeval to 0
116 *
Willy Tarreaubaaee002006-06-26 02:48:02 +0200117 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200118REGPRM1 static inline struct timeval *tv_zero(struct timeval *tv) {
119 tv->tv_sec = tv->tv_usec = 0;
120 return tv;
121}
122
123/*
124 * returns non null if tv is [eternity], otherwise 0.
125 */
126#define tv_iseternity(tv) ((tv)->tv_usec == TV_ETERNITY)
127
128/*
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200129 * returns 0 if tv is [eternity], otherwise non-zero.
130 */
131#define tv_isset(tv) ((tv)->tv_usec != TV_ETERNITY)
132
133/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200134 * returns non null if tv is [0], otherwise 0.
135 */
136#define tv_iszero(tv) (((tv)->tv_sec | (tv)->tv_usec) == 0)
137
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200138/*
139 * Converts a struct timeval to a number of milliseconds.
140 */
141REGPRM1 static inline unsigned long __tv_to_ms(const struct timeval *tv)
142{
143 unsigned long ret;
144
145 ret = tv->tv_sec * 1000;
146 ret += tv->tv_usec / 1000;
147 return ret;
148}
149
150/*
151 * Converts a struct timeval to a number of milliseconds.
152 */
153REGPRM2 static inline struct timeval * __tv_from_ms(struct timeval *tv, unsigned long ms)
154{
155 tv->tv_sec = ms / 1000;
156 tv->tv_usec = (ms % 1000) * 1000;
157 return tv;
158}
159
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200160
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200161/**** comparison functions and macros ***********************************/
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200162
163
164/* tv_cmp: compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2. */
165REGPRM2 static inline int __tv_cmp(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200166{
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200167 if ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200168 return -1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200169 else if ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200170 return 1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200171 else if ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200172 return -1;
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200173 else if ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200174 return 1;
175 else
176 return 0;
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100177}
178
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200179/* tv_iseq: compares <tv1> and <tv2> : returns 1 if tv1 == tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200180#define tv_iseq __tv_iseq
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200181REGPRM2 static inline int __tv_iseq(const struct timeval *tv1, const struct timeval *tv2)
182{
Willy Tarreau0481c202007-05-13 16:03:27 +0200183 return ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) &&
184 ((unsigned)tv1->tv_usec == (unsigned)tv2->tv_usec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200185}
186
187/* tv_isgt: compares <tv1> and <tv2> : returns 1 if tv1 > tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200188#define tv_isgt _tv_isgt
189REGPRM2 int _tv_isgt(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200190REGPRM2 static inline int __tv_isgt(const struct timeval *tv1, const struct timeval *tv2)
191{
Willy Tarreau0481c202007-05-13 16:03:27 +0200192 return
193 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
194 ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec) :
195 ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200196}
197
198/* tv_isge: compares <tv1> and <tv2> : returns 1 if tv1 >= tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200199#define tv_isge __tv_isge
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200200REGPRM2 static inline int __tv_isge(const struct timeval *tv1, const struct timeval *tv2)
201{
Willy Tarreau0481c202007-05-13 16:03:27 +0200202 return
203 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
204 ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec) :
205 ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200206}
207
208/* tv_islt: compares <tv1> and <tv2> : returns 1 if tv1 < tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200209#define tv_islt __tv_islt
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200210REGPRM2 static inline int __tv_islt(const struct timeval *tv1, const struct timeval *tv2)
211{
Willy Tarreau0481c202007-05-13 16:03:27 +0200212 return
213 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
214 ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec) :
215 ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200216}
217
218/* tv_isle: compares <tv1> and <tv2> : returns 1 if tv1 <= tv2, otherwise 0 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200219#define tv_isle _tv_isle
220REGPRM2 int _tv_isle(const struct timeval *tv1, const struct timeval *tv2);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200221REGPRM2 static inline int __tv_isle(const struct timeval *tv1, const struct timeval *tv2)
222{
Willy Tarreau0481c202007-05-13 16:03:27 +0200223 return
224 ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ?
225 ((unsigned)tv1->tv_usec <= (unsigned)tv2->tv_usec) :
226 ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200227}
228
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100229/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200230 * compares <tv1> and <tv2> modulo 1ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2
231 * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that.
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100232 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200233#define tv_ms_cmp _tv_ms_cmp
234REGPRM2 int _tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2);
235REGPRM2 static inline int __tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100236{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200237 if ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) {
238 if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000)
239 return -1;
240 else if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec + 1000)
241 return 1;
242 else
243 return 0;
244 }
245 else if (((unsigned)tv2->tv_sec > (unsigned)tv1->tv_sec + 1) ||
246 (((unsigned)tv2->tv_sec == (unsigned)tv1->tv_sec + 1) &&
247 ((unsigned)tv2->tv_usec + 1000000 >= (unsigned)tv1->tv_usec + 1000)))
248 return -1;
249 else if (((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1) ||
250 (((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) &&
251 ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000)))
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100252 return 1;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200253 else
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100254 return 0;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200255}
256
257/*
258 * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
259 * assuming that TV_ETERNITY is greater than everything.
260 */
261#define tv_ms_cmp2 _tv_ms_cmp2
262REGPRM2 int _tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2);
263REGPRM2 static inline int __tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2)
264{
265 if (tv_iseternity(tv1))
266 if (tv_iseternity(tv2))
267 return 0; /* same */
268 else
269 return 1; /* tv1 later than tv2 */
270 else if (tv_iseternity(tv2))
271 return -1; /* tv2 later than tv1 */
272 return tv_ms_cmp(tv1, tv2);
273}
274
275/*
276 * compares <tv1> and <tv2> modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2,
277 * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is
278 * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace
279 * occurrences of (tv_ms_cmp2(tv,now) <= 0).
280 */
281#define tv_ms_le2 _tv_ms_le2
282REGPRM2 int _tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2);
283REGPRM2 static inline int __tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2)
284{
285 if (likely((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1))
286 return 0;
287
288 if (likely((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec))
289 return 1;
290
291 if (likely((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec)) {
292 if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000)
293 return 1;
294 else
295 return 0;
296 }
297
298 if (unlikely(((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) &&
299 ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000)))
300 return 0;
301 else
Willy Tarreau5e8f0662007-02-12 00:59:08 +0100302 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200303}
304
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200305
306/**** operators **********************************************************/
307
308
Willy Tarreaubaaee002006-06-26 02:48:02 +0200309/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200310 * Returns the time in ms elapsed between tv1 and tv2, assuming that tv1<=tv2.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200311 * Must not be used when either argument is eternity.
312 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200313#define tv_ms_elapsed __tv_ms_elapsed
314REGPRM2 unsigned long _tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2);
315REGPRM2 static inline unsigned long __tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200316{
317 unsigned long ret;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200318
319 ret = ((signed long)(tv2->tv_sec - tv1->tv_sec)) * 1000;
320 ret += ((signed long)(tv2->tv_usec - tv1->tv_usec)) / 1000;
321 return ret;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200322}
323
324/*
325 * returns the remaining time between tv1=now and event=tv2
326 * if tv2 is passed, 0 is returned.
327 * Must not be used when either argument is eternity.
328 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200329
330#define tv_ms_remain __tv_ms_remain
331REGPRM2 unsigned long _tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2);
332REGPRM2 static inline unsigned long __tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200333{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200334 if (tv_ms_cmp(tv1, tv2) >= 0)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200335 return 0; /* event elapsed */
336
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200337 return __tv_ms_elapsed(tv1, tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200338}
339
Willy Tarreaubaaee002006-06-26 02:48:02 +0200340/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200341 * returns the remaining time between tv1=now and event=tv2
342 * if tv2 is passed, 0 is returned.
343 * Returns TIME_ETERNITY if tv2 is eternity.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200344 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200345#define tv_ms_remain2 _tv_ms_remain2
346REGPRM2 unsigned long _tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2);
347REGPRM2 static inline unsigned long __tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200348{
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200349 if (tv_iseternity(tv2))
350 return TIME_ETERNITY;
351
352 return tv_ms_remain(tv1, tv2);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200353}
354
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200355/*
356 * adds <inc> to <from>, set the result to <tv> and returns a pointer <tv>
357 */
Willy Tarreau0481c202007-05-13 16:03:27 +0200358#define tv_add _tv_add
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200359REGPRM3 struct timeval *_tv_add(struct timeval *tv, const struct timeval *from, const struct timeval *inc);
360REGPRM3 static inline struct timeval *__tv_add(struct timeval *tv, const struct timeval *from, const struct timeval *inc)
361{
362 tv->tv_usec = from->tv_usec + inc->tv_usec;
363 tv->tv_sec = from->tv_sec + inc->tv_sec;
364 if (tv->tv_usec >= 1000000) {
365 tv->tv_usec -= 1000000;
366 tv->tv_sec++;
367 }
368 return tv;
369}
370
371
372/*
Willy Tarreau0481c202007-05-13 16:03:27 +0200373 * If <inc> is set, then add it to <from> and set the result to <tv>, then
374 * return 1, otherwise return 0. It is meant to be used in if conditions.
375 */
376#define tv_add_ifset _tv_add_ifset
377REGPRM3 int _tv_add_ifset(struct timeval *tv, const struct timeval *from, const struct timeval *inc);
378REGPRM3 static inline int __tv_add_ifset(struct timeval *tv, const struct timeval *from, const struct timeval *inc)
379{
380 if (tv_iseternity(inc))
381 return 0;
382 tv->tv_usec = from->tv_usec + inc->tv_usec;
383 tv->tv_sec = from->tv_sec + inc->tv_sec;
384 if (tv->tv_usec >= 1000000) {
385 tv->tv_usec -= 1000000;
386 tv->tv_sec++;
387 }
388 return 1;
389}
390
391/*
Willy Tarreau49fa3a12007-05-12 22:29:44 +0200392 * adds <inc> to <tv> and returns a pointer <tv>
393 */
394REGPRM2 static inline struct timeval *__tv_add2(struct timeval *tv, const struct timeval *inc)
395{
396 tv->tv_usec += inc->tv_usec;
397 tv->tv_sec += inc->tv_sec;
398 if (tv->tv_usec >= 1000000) {
399 tv->tv_usec -= 1000000;
400 tv->tv_sec++;
401 }
402 return tv;
403}
404
405
406/*
407 * Computes the remaining time between tv1=now and event=tv2. if tv2 is passed,
408 * 0 is returned. The result is stored into tv.
409 */
410#define tv_remain _tv_remain
411REGPRM3 struct timeval *_tv_remain(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv);
412REGPRM3 static inline struct timeval *__tv_remain(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv)
413{
414 tv->tv_usec = tv2->tv_usec - tv1->tv_usec;
415 tv->tv_sec = tv2->tv_sec - tv1->tv_sec;
416 if ((signed)tv->tv_sec > 0) {
417 if ((signed)tv->tv_usec < 0) {
418 tv->tv_usec += 1000000;
419 tv->tv_sec--;
420 }
421 } else if (tv->tv_sec == 0) {
422 if ((signed)tv->tv_usec < 0)
423 tv->tv_usec = 0;
424 } else {
425 tv->tv_sec = 0;
426 tv->tv_usec = 0;
427 }
428 return tv;
429}
430
431
432/*
433 * Computes the remaining time between tv1=now and event=tv2. if tv2 is passed,
434 * 0 is returned. The result is stored into tv. Returns ETERNITY if tv2 is
435 * eternity.
436 */
437#define tv_remain2 _tv_remain2
438REGPRM3 struct timeval *_tv_remain2(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv);
439REGPRM3 static inline struct timeval *__tv_remain2(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tv)
440{
441 if (tv_iseternity(tv2))
442 return tv_eternity(tv);
443 return __tv_remain(tv1, tv2, tv);
444}
445
446
Willy Tarreaubaaee002006-06-26 02:48:02 +0200447/*
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200448 * adds <ms> ms to <from>, set the result to <tv> and returns a pointer <tv>
Willy Tarreaubaaee002006-06-26 02:48:02 +0200449 */
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200450#define tv_ms_add _tv_ms_add
451REGPRM3 struct timeval *_tv_ms_add(struct timeval *tv, const struct timeval *from, int ms);
452REGPRM3 static inline struct timeval *__tv_ms_add(struct timeval *tv, const struct timeval *from, int ms)
453{
454 tv->tv_usec = from->tv_usec + (ms % 1000) * 1000;
455 tv->tv_sec = from->tv_sec + (ms / 1000);
456 while (tv->tv_usec >= 1000000) {
457 tv->tv_usec -= 1000000;
458 tv->tv_sec++;
459 }
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200460 return tv;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200461}
462
Willy Tarreaubaaee002006-06-26 02:48:02 +0200463
Willy Tarreaua6a6a932007-04-28 22:40:08 +0200464/*
465 * compares <tv1> and <tv2> : returns 1 if <tv1> is before <tv2>, otherwise 0.
466 * This should be very fast because it's used in schedulers.
467 * It has been optimized to return 1 (so call it in a loop which continues
468 * as long as tv1<=tv2)
469 */
470
471#define tv_isbefore(tv1, tv2) \
472 (unlikely((unsigned)(tv1)->tv_sec < (unsigned)(tv2)->tv_sec) ? 1 : \
473 (unlikely((unsigned)(tv1)->tv_sec > (unsigned)(tv2)->tv_sec) ? 0 : \
474 unlikely((unsigned)(tv1)->tv_usec < (unsigned)(tv2)->tv_usec)))
475
476/*
477 * returns the first event between <tv1> and <tv2> into <tvmin>.
478 * a zero tv is ignored. <tvmin> is returned. If <tvmin> is known
479 * to be the same as <tv1> or <tv2>, it is recommended to use
480 * tv_bound instead.
481 */
482#define tv_min(tvmin, tv1, tv2) ({ \
483 if (tv_isbefore(tv1, tv2)) { \
484 *tvmin = *tv1; \
485 } \
486 else { \
487 *tvmin = *tv2; \
488 } \
489 tvmin; \
490})
491
492/*
493 * returns the first event between <tv1> and <tv2> into <tvmin>.
494 * a zero tv is ignored. <tvmin> is returned. This function has been
495 * optimized to be called as tv_min(a,a,b) or tv_min(b,a,b).
496 */
497#define tv_bound(tv1, tv2) ({ \
498 if (tv_isbefore(tv2, tv1)) \
499 *tv1 = *tv2; \
500 tv1; \
501})
Willy Tarreaubaaee002006-06-26 02:48:02 +0200502
Willy Tarreauc8f24f82007-11-30 18:38:35 +0100503char *human_time(int t, short hz_div);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200504
Willy Tarreau2dd0d472006-06-29 17:53:05 +0200505#endif /* _COMMON_TIME_H */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200506
507/*
508 * Local variables:
509 * c-indent-level: 8
510 * c-basic-offset: 8
511 * End:
512 */