blob: 462dccaaeac0751f2658464406353dbf7c002cca [file] [log] [blame]
Willy Tarreau0c303ee2008-07-07 00:09:58 +02001/*
2 include/common/ticks.h
3 Functions and macros for manipulation of expiration timers
4
5 Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
6
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
22/*
23 * Using a mix of milliseconds and timeval for internal timers is expensive and
24 * overkill, because we don't need such a precision to compute timeouts.
25 * So we're converting them to "ticks". Right now, one tick equals one
26 * millisecond, but that might change in the future. Ticks are stored as 32bit
27 * values, and sorted in four 30bit-wide rotating arrays, which means that any
28 * timer may be 2^30 ms in the future, or 12.4 days. The ticks are designed to
29 * wrap after they pass 2^32. That means that we cannot directly compare them,
30 * but we can check the sign of their difference.
31 *
32 * We must both support absolute dates (well in fact, dates relative to now+/-
33 * 12 days), and intervals (for timeouts). Both types need an "eternity" magic
34 * value. For optimal code generation, we'll use zero as the magic value
35 * indicating that an expiration timer or a timeout is not set. We have to
36 * check that we don't return this value when adding timeouts to <now>. If a
37 * computation returns 0, we must increase it to 1 (which will push the timeout
38 * 1 ms further).
39 */
40
41#ifndef _COMMON_TICKS_H
42#define _COMMON_TICKS_H
43
44#include <common/config.h>
45#include <common/standard.h>
46
47#define TICK_ETERNITY 0
48
49/* right now, ticks are milliseconds. Both negative ms and negative ticks
50 * indicate eternity.
51 */
52#define MS_TO_TICKS(ms) (ms)
53#define TICKS_TO_MS(tk) (tk)
54
55/* return 1 if tick is set, otherwise 0 */
56static inline int tick_isset(int expire)
57{
58 return expire != 0;
59}
60
61/* Add <timeout> to <now>, and return the resulting expiration date.
62 * <timeout> will not be checked for null values.
63 */
64static inline int tick_add(int now, int timeout)
65{
66 now += timeout;
67 if (unlikely(!now))
68 now++; /* unfortunate value */
69 return now;
70}
71
72/* add <timeout> to <now> if it is set, otherwise set it to eternity.
73 * Return the resulting expiration date.
74 */
75static inline int tick_add_ifset(int now, int timeout)
76{
77 if (!timeout)
78 return TICK_ETERNITY;
79 return tick_add(now, timeout);
80}
81
82/* return 1 if timer <timer> is expired at date <now>, otherwise zero */
83static inline int tick_is_expired(int timer, int now)
84{
85 if (!tick_isset(timer))
86 return 0;
87 return (timer - now) <= 0;
88}
89
90/* return the first one of the two timers, both of which may be infinite */
91static inline int tick_first(int t1, int t2)
92{
93 if (!tick_isset(t1))
94 return t2;
95 if (!tick_isset(t2))
96 return t1;
97 if ((t1 - t2) <= 0)
98 return t1;
99 else
100 return t2;
101}
102
103/* return the number of ticks remaining from <now> to <exp>, or zero if expired */
104static inline int tick_remain(int now, int exp)
105{
106 if (tick_is_expired(exp, now))
107 return 0;
108 return exp - now;
109}
110
111#endif /* _COMMON_TICKS_H */
112
113/*
114 * Local variables:
115 * c-indent-level: 8
116 * c-basic-offset: 8
117 * End:
118 */