[MAJOR] convert all expiration timers from timeval to ticks

This is the first attempt at moving all internal parts from
using struct timeval to integer ticks. Those provides simpler
and faster code due to simplified operations, and this change
also saved about 64 bytes per session.

A new header file has been added : include/common/ticks.h.

It is possible that some functions should finally not be inlined
because they're used quite a lot (eg: tick_first, tick_add_ifset
and tick_is_expired). More measurements are required in order to
decide whether this is interesting or not.

Some function and variable names are still subject to change for
a better overall logics.
diff --git a/include/common/appsession.h b/include/common/appsession.h
index e77396c..616766f 100644
--- a/include/common/appsession.h
+++ b/include/common/appsession.h
@@ -16,7 +16,7 @@
 typedef struct appsessions {
 	char *sessid;
 	char *serverid;
-	struct timeval expire;		/* next expiration time for this application session */
+	int   expire;		/* next expiration time for this application session (in tick) */
 	unsigned long int request_count;
 	struct list hash_list;
 } appsess;
@@ -38,7 +38,7 @@
 /* Callback for destroy */
 void destroy(appsess *data);
 
-void appsession_refresh(struct task *t, struct timeval *next);
+void appsession_refresh(struct task *t, int *next);
 int appsession_task_init(void);
 int appsession_init(void);
 void appsession_cleanup(void);
diff --git a/include/common/ticks.h b/include/common/ticks.h
new file mode 100644
index 0000000..462dcca
--- /dev/null
+++ b/include/common/ticks.h
@@ -0,0 +1,118 @@
+/*
+  include/common/ticks.h
+  Functions and macros for manipulation of expiration timers
+
+  Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation, version 2.1
+  exclusively.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+/*
+ * Using a mix of milliseconds and timeval for internal timers is expensive and
+ * overkill, because we don't need such a precision to compute timeouts.
+ * So we're converting them to "ticks". Right now, one tick equals one
+ * millisecond, but that might change in the future. Ticks are stored as 32bit
+ * values, and sorted in four 30bit-wide rotating arrays, which means that any
+ * timer may be 2^30 ms in the future, or 12.4 days. The ticks are designed to
+ * wrap after they pass 2^32. That means that we cannot directly compare them,
+ * but we can check the sign of their difference.
+ *
+ * We must both support absolute dates (well in fact, dates relative to now+/-
+ * 12 days), and intervals (for timeouts). Both types need an "eternity" magic
+ * value. For optimal code generation, we'll use zero as the magic value
+ * indicating that an expiration timer or a timeout is not set. We have to
+ * check that we don't return this value when adding timeouts to <now>. If a
+ * computation returns 0, we must increase it to 1 (which will push the timeout
+ * 1 ms further).
+ */
+
+#ifndef _COMMON_TICKS_H
+#define _COMMON_TICKS_H
+
+#include <common/config.h>
+#include <common/standard.h>
+
+#define TICK_ETERNITY   0
+
+/* right now, ticks are milliseconds. Both negative ms and negative ticks
+ * indicate eternity.
+ */
+#define MS_TO_TICKS(ms) (ms)
+#define TICKS_TO_MS(tk) (tk)
+
+/* return 1 if tick is set, otherwise 0 */
+static inline int tick_isset(int expire)
+{
+	return expire != 0;
+}
+
+/* Add <timeout> to <now>, and return the resulting expiration date.
+ * <timeout> will not be checked for null values.
+ */
+static inline int tick_add(int now, int timeout)
+{
+	now += timeout;
+	if (unlikely(!now))
+		now++;    /* unfortunate value */
+	return now;
+}
+
+/* add <timeout> to <now> if it is set, otherwise set it to eternity.
+ * Return the resulting expiration date.
+ */
+static inline int tick_add_ifset(int now, int timeout)
+{
+	if (!timeout)
+		return TICK_ETERNITY;
+	return tick_add(now, timeout);
+}
+
+/* return 1 if timer <timer> is expired at date <now>, otherwise zero */
+static inline int tick_is_expired(int timer, int now)
+{
+	if (!tick_isset(timer))
+		return 0;
+	return (timer - now) <= 0;
+}
+
+/* return the first one of the two timers, both of which may be infinite */
+static inline int tick_first(int t1, int t2)
+{
+	if (!tick_isset(t1))
+		return t2;
+	if (!tick_isset(t2))
+		return t1;
+	if ((t1 - t2) <= 0)
+		return t1;
+	else
+		return t2;
+}
+
+/* return the number of ticks remaining from <now> to <exp>, or zero if expired */
+static inline int tick_remain(int now, int exp)
+{
+	if (tick_is_expired(exp, now))
+		return 0;
+	return exp - now;
+}
+
+#endif /* _COMMON_TICKS_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/include/proto/buffers.h b/include/proto/buffers.h
index 95d63a5..c25e8f6 100644
--- a/include/proto/buffers.h
+++ b/include/proto/buffers.h
@@ -28,6 +28,7 @@
 
 #include <common/config.h>
 #include <common/memory.h>
+#include <common/ticks.h>
 #include <common/time.h>
 
 #include <types/buffers.h>
@@ -68,14 +69,14 @@
 /* marks the buffer as "shutdown pending" for reads and cancels the timeout */
 static inline void buffer_shutr(struct buffer *buf)
 {
-	tv_eternity(&buf->rex);
+	buf->rex = TICK_ETERNITY;
 	buf->flags |= BF_SHUTR_PENDING;
 }
 
 /* marks the buffer as "shutdown pending" for writes and cancels the timeout */
 static inline void buffer_shutw(struct buffer *buf)
 {
-	tv_eternity(&buf->wex);
+	buf->wex = TICK_ETERNITY;
 	buf->flags |= BF_SHUTW_PENDING;
 }
 
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index 68b3f11..0a20644 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -58,7 +58,7 @@
 #define HTTP_IS_VER_TOKEN(x) (http_is_ver_token[(unsigned char)(x)])
 
 int event_accept(int fd);
-void process_session(struct task *t, struct timeval *next);
+void process_session(struct task *t, int *next);
 int process_cli(struct session *t);
 int process_srv(struct session *t);
 
diff --git a/include/proto/proto_uxst.h b/include/proto/proto_uxst.h
index 642beb8..e46f35e 100644
--- a/include/proto/proto_uxst.h
+++ b/include/proto/proto_uxst.h
@@ -2,7 +2,7 @@
   include/proto/proto_uxst.h
   This file contains UNIX-stream socket protocol definitions.
 
-  Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
+  Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
   
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
 
 int uxst_event_accept(int fd);
 void uxst_add_listener(struct listener *listener);
-void process_uxst_stats(struct task *t, struct timeval *next);
+void process_uxst_stats(struct task *t, int *next);
 
 #endif /* _PROTO_PROTO_UXST_H */
 
diff --git a/include/proto/proxy.h b/include/proto/proxy.h
index 7268bfa..78f6120 100644
--- a/include/proto/proxy.h
+++ b/include/proto/proxy.h
@@ -23,11 +23,12 @@
 #define _PROTO_PROXY_H
 
 #include <common/config.h>
+#include <common/ticks.h>
 #include <common/time.h>
 #include <types/proxy.h>
 
 int start_proxies(int verbose);
-void maintain_proxies(struct timeval *next);
+void maintain_proxies(int *next);
 void soft_stop(void);
 void pause_proxy(struct proxy *p);
 void pause_proxies(void);
@@ -52,14 +53,14 @@
 /* this function initializes all timeouts for proxy p */
 static inline void proxy_reset_timeouts(struct proxy *proxy)
 {
-	tv_eternity(&proxy->timeout.client);
-	tv_eternity(&proxy->timeout.tarpit);
-	tv_eternity(&proxy->timeout.queue);
-	tv_eternity(&proxy->timeout.connect);
-	tv_eternity(&proxy->timeout.server);
-	tv_eternity(&proxy->timeout.appsession);
-	tv_eternity(&proxy->timeout.httpreq);
-	tv_eternity(&proxy->timeout.check);
+	proxy->timeout.client = TICK_ETERNITY;
+	proxy->timeout.tarpit = TICK_ETERNITY;
+	proxy->timeout.queue = TICK_ETERNITY;
+	proxy->timeout.connect = TICK_ETERNITY;
+	proxy->timeout.server = TICK_ETERNITY;
+	proxy->timeout.appsession = TICK_ETERNITY;
+	proxy->timeout.httpreq = TICK_ETERNITY;
+	proxy->timeout.check = TICK_ETERNITY;
 }
 
 #endif /* _PROTO_PROXY_H */
diff --git a/include/proto/task.h b/include/proto/task.h
index cc5c180..10f6b42 100644
--- a/include/proto/task.h
+++ b/include/proto/task.h
@@ -123,13 +123,13 @@
  *   - return the date of next event in <next> or eternity.
  */
 
-void process_runnable_tasks(struct timeval *next);
+void process_runnable_tasks(int *next);
 
 /*
  * Extract all expired timers from the timer queue, and wakes up all
  * associated tasks. Returns the date of next event (or eternity).
  */
-void wake_expired_tasks(struct timeval *next);
+void wake_expired_tasks(int *next);
 
 
 #endif /* _PROTO_TASK_H */
diff --git a/include/types/buffers.h b/include/types/buffers.h
index 583c517..a9de965 100644
--- a/include/types/buffers.h
+++ b/include/types/buffers.h
@@ -2,7 +2,7 @@
   include/types/buffers.h
   Buffer management definitions, macros and inline functions.
 
-  Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
+  Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
   
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -25,9 +25,6 @@
 #include <common/config.h>
 #include <common/memory.h>
 
-#include <sys/time.h>
-#include <sys/types.h>
-
 /* The BF_* macros designate Buffer Flags, which may be ORed in the bit field
  * member 'flags' in struct buffer.
  */
@@ -65,12 +62,12 @@
 
 struct buffer {
 	unsigned int flags;             /* BF_* */
-	struct timeval rex;             /* expiration date for a read  */
-	struct timeval wex;             /* expiration date for a write */
-	struct timeval cex;             /* expiration date for a connect */
-	struct timeval rto;             /* read timeout */
-	struct timeval wto;             /* write timeout */
-	struct timeval cto;             /* connect timeout */
+	int rex;                        /* expiration date for a read, in ticks */
+	int wex;                        /* expiration date for a write, in ticks */
+	int cex;                        /* expiration date for a connect, in ticks */
+	int rto;                        /* read timeout, in ticks */
+	int wto;                        /* write timeout, in ticks */
+	int cto;                        /* connect timeout, in ticks */
 	unsigned int l;                 /* data length */
 	char *r, *w, *lr;               /* read ptr, write ptr, last read */
 	char *rlim;                     /* read limit, used for header rewriting */
diff --git a/include/types/fd.h b/include/types/fd.h
index 1f1b3b4..7d746f0 100644
--- a/include/types/fd.h
+++ b/include/types/fd.h
@@ -2,7 +2,7 @@
   include/types/fd.h
   File descriptors states.
 
-  Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
+  Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
   
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -100,7 +100,7 @@
 	int  REGPRM2 (*cond_c)(const int fd, int dir);       /* clear polling on <fd> for <dir> if set */
 	void REGPRM1    (*rem)(const int fd);                /* remove any polling on <fd> */
 	void REGPRM1    (*clo)(const int fd);                /* mark <fd> as closed */
-    	void REGPRM2   (*poll)(struct poller *p, struct timeval *exp); /* the poller itself */
+    	void REGPRM2   (*poll)(struct poller *p, int exp);   /* the poller itself */
 	int  REGPRM1   (*init)(struct poller *p);            /* poller initialization */
 	void REGPRM1   (*term)(struct poller *p);            /* termination of this poller */
 	int  REGPRM1   (*test)(struct poller *p);            /* pre-init check of the poller */
diff --git a/include/types/global.h b/include/types/global.h
index 1636954..38b194c 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -66,7 +66,7 @@
 		int maxaccept;     /* max number of consecutive accept() */
 	} tune;
 	struct listener stats_sock; /* unix socket listener for statistics */
-	struct timeval stats_timeout;
+	int stats_timeout;          /* in ticks */
 };
 
 extern struct global global;
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index 5b0914f..cc647a6 100644
--- a/include/types/proto_http.h
+++ b/include/types/proto_http.h
@@ -2,7 +2,7 @@
   include/types/proto_http.h
   This file contains HTTP protocol definitions.
 
-  Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
+  Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
   
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -240,7 +240,7 @@
 	char *srv_cookie;		/* cookie presented by the server, in capture mode */
 	int status;			/* HTTP status from the server, negative if from proxy */
 	unsigned int flags;             /* transaction flags */
-	struct timeval exp;             /* expiration date for the transaction (generally a request) */
+	int exp;                        /* expiration date for the transaction (generally a request), int ticks */
 };
 
 /* This structure is used by http_find_header() to return values of headers.
diff --git a/include/types/protocols.h b/include/types/protocols.h
index 971a2a6..745b440 100644
--- a/include/types/protocols.h
+++ b/include/types/protocols.h
@@ -83,8 +83,8 @@
 	struct listener *next;		/* next address for the same proxy, or NULL */
 	struct list proto_list;         /* list in the protocol header */
 	int (*accept)(int fd);		/* accept() function passed to fdtab[] */
-	void (*handler)(struct task *t, struct timeval *next); /* protocol handler */
-	struct timeval *timeout;	/* pointer to client-side timeout */
+	void (*handler)(struct task *t, int *next); /* protocol handler */
+	int  *timeout;                  /* pointer to client-side timeout */
 	void *private;			/* any private data which may be used by accept() */
 	union {				/* protocol-dependant access restrictions */
 		struct {		/* UNIX socket permissions */
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 10a69b5..2a84aaf 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -182,14 +182,14 @@
 	int monitor_uri_len;			/* length of the string above. 0 if unused */
 	struct list mon_fail_cond;              /* list of conditions to fail monitoring requests (chained) */
 	struct {				/* WARNING! check proxy_reset_timeouts() in proxy.h !!! */
-		struct timeval client;		/* client I/O timeout (in milliseconds) */
-		struct timeval tarpit;          /* tarpit timeout, defaults to connect if unspecified */
-		struct timeval queue;           /* queue timeout, defaults to connect if unspecified */
-		struct timeval connect;		/* connect timeout (in milliseconds) */
-		struct timeval server;		/* server I/O timeout (in milliseconds) */
-		struct timeval appsession;	/* appsession cookie expiration */
-		struct timeval httpreq;		/* maximum time for complete HTTP request */
-		struct timeval check;		/* maximum time for complete check */
+		int client;                     /* client I/O timeout (in ticks) */
+		int tarpit;                     /* tarpit timeout, defaults to connect if unspecified */
+		int queue;                      /* queue timeout, defaults to connect if unspecified */
+		int connect;                    /* connect timeout (in ticks) */
+		int server;                     /* server I/O timeout (in ticks) */
+		int appsession;                 /* appsession cookie expiration */
+		int httpreq;                    /* maximum time for complete HTTP request */
+		int check;                      /* maximum time for complete check */
 	} timeout;
 	char *id;				/* proxy id */
 	struct list pendconns;			/* pending connections with no server assigned yet */
@@ -224,7 +224,7 @@
 	signed char logfac1, logfac2;		/* log facility for both servers. -1 = disabled */
 	int loglev1, loglev2;			/* log level for each server, 7 by default */
 	int to_log;				/* things to be logged (LW_*) */
-	struct timeval stop_time;		/* date to stop listening, when stopping != 0 */
+	int stop_time;                          /* date to stop listening, when stopping != 0 (int ticks) */
 	int nb_reqadd, nb_rspadd;
 	struct hdr_exp *req_exp;		/* regular expressions for request headers */
 	struct hdr_exp *rsp_exp;		/* regular expressions for response headers */
diff --git a/include/types/task.h b/include/types/task.h
index 4e579c1..ae9166e 100644
--- a/include/types/task.h
+++ b/include/types/task.h
@@ -36,8 +36,8 @@
 struct task {
 	struct eb32_node eb;		/* ebtree node used to hold the task in the wait queue */
 	int state;			/* task state : IDLE or RUNNING */
-	struct timeval expire;		/* next expiration time for this task, use only for fast sorting */
-	void (*process)(struct task *t, struct timeval *next);	/* the function which processes the task */
+	unsigned int expire;		/* next expiration time for this task */
+	void (*process)(struct task *t, int *next);  /* the function which processes the task */
 	void *context;			/* the task's context */
 	int nice;			/* the task's current nice value from -1024 to +1024 */
 };