MEDIUM: poller: separate the wait time from the wake events

We have been abusing the do_poll()'s timeout for a while, making it zero
whenever there is some known activity. The problem this poses is that it
complicates activity diagnostic by incrementing the poll_exp field for
each known activity. It also requires extra computations that could be
avoided.

This change passes a "wake" argument to say that the poller must not
sleep. This simplifies the operations and allows one to differenciate
expirations from activity.
diff --git a/include/types/fd.h b/include/types/fd.h
index 3ff4f65..9b54553 100644
--- a/include/types/fd.h
+++ b/include/types/fd.h
@@ -142,7 +142,7 @@
  *  - <private> is initialized by the poller's init() function, and cleaned by
  *    the term() function.
  *  - clo() should be used to do indicate the poller that fd will be closed.
- *  - poll() calls the poller, expiring at <exp>
+ *  - poll() calls the poller, expiring at <exp>, or immediately if <wake> is set
  *  - flags indicate what the poller supports (HAP_POLL_F_*)
  */
 
@@ -151,7 +151,7 @@
 struct poller {
 	void   *private;                                     /* any private data for the poller */
 	void REGPRM1   (*clo)(const int fd);                 /* mark <fd> as closed */
-    	void REGPRM2   (*poll)(struct poller *p, int exp);   /* the poller itself */
+	void REGPRM3   (*poll)(struct poller *p, int exp, int wake);  /* 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/src/ev_epoll.c b/src/ev_epoll.c
index 039327d..6c09c04 100644
--- a/src/ev_epoll.c
+++ b/src/ev_epoll.c
@@ -103,7 +103,7 @@
 /*
  * Linux epoll() poller
  */
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
 {
 	int status;
 	int fd;
@@ -147,7 +147,7 @@
 	thread_harmless_now();
 
 	/* now let's wait for polled events */
-	wait_time = compute_poll_timeout(exp);
+	wait_time = wake ? 0 : compute_poll_timeout(exp);
 	tv_entering_poll();
 	activity_count_runtime();
 	do {
@@ -160,7 +160,7 @@
 			break;
 		if (timeout || !wait_time)
 			break;
-		if (signal_queue_len)
+		if (signal_queue_len || wake)
 			break;
 		if (tick_isset(exp) && tick_is_expired(exp, now_ms))
 			break;
diff --git a/src/ev_evports.c b/src/ev_evports.c
index dbad7b7..eae72d0 100644
--- a/src/ev_evports.c
+++ b/src/ev_evports.c
@@ -96,7 +96,7 @@
  * "src/fd.c" for more information.
  */
 
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
 {
 	int i;
 	int wait_time;
@@ -144,7 +144,7 @@
 	/*
 	 * Determine how long to wait for events to materialise on the port.
 	 */
-	wait_time = compute_poll_timeout(exp);
+	wait_time = wake ? 0 : compute_poll_timeout(exp);
 	tv_entering_poll();
 	activity_count_runtime();
 
@@ -183,7 +183,7 @@
 			break;
 		if (timeout || !wait_time)
 			break;
-		if (signal_queue_len)
+		if (signal_queue_len || wake)
 			break;
 		if (tick_isset(exp) && tick_is_expired(exp, now_ms))
 			break;
diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c
index 674551e..aea2ab7 100644
--- a/src/ev_kqueue.c
+++ b/src/ev_kqueue.c
@@ -74,7 +74,7 @@
 /*
  * kqueue() poller
  */
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
 {
 	int status;
 	int count, fd, wait_time;
@@ -132,7 +132,7 @@
 	fd_nbupdt = 0;
 
 	/* now let's wait for events */
-	wait_time = compute_poll_timeout(exp);
+	wait_time = wake ? 0 : compute_poll_timeout(exp);
 	fd = global.tune.maxpollevents;
 	tv_entering_poll();
 	activity_count_runtime();
@@ -155,7 +155,7 @@
 			break;
 		if (timeout || !wait_time)
 			break;
-		if (signal_queue_len)
+		if (signal_queue_len || wake)
 			break;
 		if (tick_isset(exp) && tick_is_expired(exp, now_ms))
 			break;
diff --git a/src/ev_poll.c b/src/ev_poll.c
index 863b838..54812f5 100644
--- a/src/ev_poll.c
+++ b/src/ev_poll.c
@@ -88,7 +88,7 @@
 /*
  * Poll() poller
  */
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
 {
 	int status;
 	int fd;
@@ -194,7 +194,7 @@
 	}
 
 	/* now let's wait for events */
-	wait_time = compute_poll_timeout(exp);
+	wait_time = wake ? 0 : compute_poll_timeout(exp);
 	tv_entering_poll();
 	activity_count_runtime();
 	status = poll(poll_events, nbfd, wait_time);
diff --git a/src/ev_select.c b/src/ev_select.c
index 3591f1e..0ccf2f1 100644
--- a/src/ev_select.c
+++ b/src/ev_select.c
@@ -79,7 +79,7 @@
 /*
  * Select() poller
  */
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
 {
 	int status;
 	int fd, i;
@@ -162,7 +162,7 @@
 	}
 
 	/* now let's wait for events */
-	delta_ms = compute_poll_timeout(exp);
+	delta_ms = wake ? 0 : compute_poll_timeout(exp);
 	delta.tv_sec  = (delta_ms / 1000);
 	delta.tv_usec = (delta_ms % 1000) * 1000;
 	tv_entering_poll();
diff --git a/src/haproxy.c b/src/haproxy.c
index 306c34f..35dd514 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2505,7 +2505,7 @@
 /* Runs the polling loop */
 static void run_poll_loop()
 {
-	int next, exp;
+	int next, wake;
 
 	tv_update_date(0,1);
 	while (1) {
@@ -2525,7 +2525,7 @@
 			break;
 
 		/* expire immediately if events are pending */
-		exp = now_ms;
+		wake = 1;
 		if (fd_cache_mask & tid_bit)
 			activity[tid].wake_cache++;
 		else if (active_tasks_mask & tid_bit)
@@ -2539,11 +2539,11 @@
 				activity[tid].wake_tasks++;
 				_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
 			} else
-				exp = next;
+				wake = 0;
 		}
 
 		/* The poller will ensure it returns around <next> */
-		cur_poller.poll(&cur_poller, exp);
+		cur_poller.poll(&cur_poller, next, wake);
 		if (sleeping_thread_mask & tid_bit)
 			_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
 		fd_process_cached_events();