]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: fd: centralize poll timeout computation in compute_poll_timeout()
authorWilly Tarreau <w@1wt.eu>
Wed, 17 Oct 2018 09:25:54 +0000 (11:25 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 17 Oct 2018 17:59:43 +0000 (19:59 +0200)
The 4 pollers all contain the same code used to compute the poll timeout.
This is pointless, let's centralize this into fd.h. This also gets rid of
the useless SCHEDULER_RESOLUTION macro which used to work arond a very old
linux 2.2 bug causing select() to wake up slightly before the timeout.

include/common/config.h
include/proto/fd.h
src/ev_epoll.c
src/ev_kqueue.c
src/ev_poll.c
src/ev_select.c

index ff4a50cef636047baf556f5368c4cc18031cd313..6fd85f893814d0ef15e6648caee4394169274a55 100644 (file)
 #include <common/compat.h>
 #include <common/defaults.h>
 
-/* this reduces the number of calls to select() by choosing appropriate
- * sheduler precision in milliseconds. It should be near the minimum
- * time that is needed by select() to collect all events. All timeouts
- * are rounded up by adding this value prior to pass it to select().
- */
-#define SCHEDULER_RESOLUTION    9
-
 /* CONFIG_HAP_MEM_OPTIM
  * This enables use of memory pools instead of malloc()/free(). There
  * is no reason to disable it, except perhaps for rare debugging.
index 7123377f994acd6c940635c3e222ade063babf31..03e318284e9bbed071a70adeccbb622940868c09 100644 (file)
 #include <unistd.h>
 
 #include <common/config.h>
+#include <common/ticks.h>
+#include <common/time.h>
 
 #include <types/fd.h>
+#include <types/global.h>
 
 /* public variables */
 
@@ -528,6 +531,30 @@ static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), unsigned
                HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
 }
 
+/* Computes the bounded poll() timeout based on the next expiration timer <next>
+ * by bounding it to MAX_DELAY_MS. <next> may equal TICK_ETERNITY. The pollers
+ * just needs to call this function right before polling to get their timeout
+ * value. Timeouts that are already expired (possibly due to a pending event)
+ * are accounted for in activity.poll_exp.
+ */
+static inline int compute_poll_timeout(int next)
+{
+       int wait_time;
+
+       if (!tick_isset(next))
+               wait_time = MAX_DELAY_MS;
+       else if (tick_is_expired(next, now_ms)) {
+               activity[tid].poll_exp++;
+               wait_time = 0;
+       }
+       else {
+               wait_time = TICKS_TO_MS(tick_remain(now_ms, next)) + 1;
+               if (wait_time > MAX_DELAY_MS)
+                       wait_time = MAX_DELAY_MS;
+       }
+       return wait_time;
+}
+
 /* These are replacements for FD_SET, FD_CLR, FD_ISSET, working on uints */
 static inline void hap_fd_set(int fd, unsigned int *evts)
 {
index f672c66cbf4a6f3d7fecd56644caf5d983878968..b9980dbed316546dcfe13a203671ebc71146c4ac 100644 (file)
@@ -144,21 +144,8 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
 
        thread_harmless_now();
 
-       /* compute the epoll_wait() timeout */
-       if (!exp)
-               wait_time = MAX_DELAY_MS;
-       else if (tick_is_expired(exp, now_ms)) {
-               activity[tid].poll_exp++;
-               wait_time = 0;
-       }
-       else {
-               wait_time = TICKS_TO_MS(tick_remain(now_ms, exp)) + 1;
-               if (wait_time > MAX_DELAY_MS)
-                       wait_time = MAX_DELAY_MS;
-       }
-
        /* now let's wait for polled events */
-
+       wait_time = compute_poll_timeout(exp);
        gettimeofday(&before_poll, NULL);
        status = epoll_wait(epoll_fd[tid], epoll_events, global.tune.maxpollevents, wait_time);
        tv_update_date(wait_time, status);
index e2f04f7025ad3a5ea44baae4a4188359f9c22bbb..3d21cb0349aea7a96707f0449b06217055dc7f31 100644 (file)
@@ -129,23 +129,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        }
        fd_nbupdt = 0;
 
-       delta_ms        = 0;
-
-       if (!exp) {
-               delta_ms        = MAX_DELAY_MS;
-               timeout.tv_sec  = (MAX_DELAY_MS / 1000);
-               timeout.tv_nsec = (MAX_DELAY_MS % 1000) * 1000000;
-       }
-       else if (!tick_is_expired(exp, now_ms)) {
-               delta_ms = TICKS_TO_MS(tick_remain(now_ms, exp)) + 1;
-               if (delta_ms > MAX_DELAY_MS)
-                       delta_ms = MAX_DELAY_MS;
-               timeout.tv_sec  = (delta_ms / 1000);
-               timeout.tv_nsec = (delta_ms % 1000) * 1000000;
-       }
-       else
-               activity[tid].poll_exp++;
-
+       /* now let's wait for events */
+       delta_ms = compute_poll_timeout(exp);
+       timeout.tv_sec  = (delta_ms / 1000);
+       timeout.tv_nsec = (delta_ms % 1000) * 1000000;
        fd = global.tune.maxpollevents;
        gettimeofday(&before_poll, NULL);
        status = kevent(kqueue_fd[tid], // int kq
index 712bdf9918a947fa06ff4012f2cf5528a65df40f..0b51e8d01a66c59bf32bd05c566fe1b65998d968 100644 (file)
@@ -193,18 +193,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        }
 
        /* now let's wait for events */
-       if (!exp)
-               wait_time = MAX_DELAY_MS;
-       else if (tick_is_expired(exp, now_ms)) {
-               activity[tid].poll_exp++;
-               wait_time = 0;
-       }
-       else {
-               wait_time = TICKS_TO_MS(tick_remain(now_ms, exp)) + 1;
-               if (wait_time > MAX_DELAY_MS)
-                       wait_time = MAX_DELAY_MS;
-       }
-
+       wait_time = compute_poll_timeout(exp);
        gettimeofday(&before_poll, NULL);
        status = poll(poll_events, nbfd, wait_time);
        tv_update_date(wait_time, status);
index d248d6d44a1d53bf23e5e5f66abf0507ebfbcd29..0f9b87ee311bb65d7d2f54241f594c70aa05d761 100644 (file)
@@ -160,25 +160,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                writenotnull |= (*(((int*)tmp_evts[DIR_WR])+i) = *(((int*)fd_evts[DIR_WR])+i)) != 0;
        }
 
-       delta_ms      = 0;
-       delta.tv_sec  = 0;
-       delta.tv_usec = 0;
-
-       if (!exp) {
-               delta_ms      = MAX_DELAY_MS;
-               delta.tv_sec  = (MAX_DELAY_MS / 1000);
-               delta.tv_usec = (MAX_DELAY_MS % 1000) * 1000;
-       }
-       else if (!tick_is_expired(exp, now_ms)) {
-               delta_ms = TICKS_TO_MS(tick_remain(now_ms, exp)) + SCHEDULER_RESOLUTION;
-               if (delta_ms > MAX_DELAY_MS)
-                       delta_ms = MAX_DELAY_MS;
-               delta.tv_sec  = (delta_ms / 1000);
-               delta.tv_usec = (delta_ms % 1000) * 1000;
-       }
-       else
-               activity[tid].poll_exp++;
-
+       /* now let's wait for events */
+       delta_ms = compute_poll_timeout(exp);
+       delta.tv_sec  = (delta_ms / 1000);
+       delta.tv_usec = (delta_ms % 1000) * 1000;
        gettimeofday(&before_poll, NULL);
        status = select(maxfd,
                        readnotnull ? tmp_evts[DIR_RD] : NULL,