]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: poller: separate the wait time from the wake events
authorWilly Tarreau <w@1wt.eu>
Tue, 28 May 2019 14:44:05 +0000 (16:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 28 May 2019 15:25:21 +0000 (17:25 +0200)
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.

include/types/fd.h
src/ev_epoll.c
src/ev_evports.c
src/ev_kqueue.c
src/ev_poll.c
src/ev_select.c
src/haproxy.c

index 3ff4f656fc39dcf7a2f700c937ca51597b0f64a8..9b54553eca51e068867272f10e32b60f64d8ec98 100644 (file)
@@ -142,7 +142,7 @@ struct fdinfo {
  *  - <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 fdinfo {
 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 */
index 039327d5a999a8c3e3729b704e916c58432169a0..6c09c0498f7725b713dc1b37a57213e4cfbdb596 100644 (file)
@@ -103,7 +103,7 @@ static void _update_fd(int fd)
 /*
  * 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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                        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;
index dbad7b790fa07fdf5edcc7098387e89c0dd3ae87..eae72d0991b547b44293744ca257393b295a0ddf 100644 (file)
@@ -96,7 +96,7 @@ static void _update_fd(int fd)
  * "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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        /*
         * 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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                        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;
index 674551e4d79acb7f3412e356559b6e4b6f4bba29..aea2ab7389dcbbac487f8d89cd3c925b9f57bce5 100644 (file)
@@ -74,7 +74,7 @@ static int _update_fd(int fd, int start)
 /*
  * 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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
                        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;
index 863b8389720b6bbd91ca09b1a1cebb898a975696..54812f53b85924b4397b15af1bf8785942af0129 100644 (file)
@@ -88,7 +88,7 @@ static void _update_fd(int fd, int *max_add_fd)
 /*
  * 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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        }
 
        /* 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);
index 3591f1eb1f134b649c2b9e2cbeb3df9a844f7c37..0ccf2f150c4c4c3598568144e015938601348e26 100644 (file)
@@ -79,7 +79,7 @@ static void _update_fd(int fd, int *max_add_fd)
 /*
  * 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 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        }
 
        /* 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();
index 306c34fa3bb24243628a1370dacdb424c890ee97..35dd514a65dc313da4deabf3c44d48ccee9e888f 100644 (file)
@@ -2505,7 +2505,7 @@ void deinit(void)
 /* 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 @@ static void run_poll_loop()
                        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 @@ static void run_poll_loop()
                                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();