]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: queue: unlock as soon as possible
authorWilly Tarreau <w@1wt.eu>
Fri, 18 Jun 2021 18:12:11 +0000 (20:12 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 22 Jun 2021 16:57:18 +0000 (18:57 +0200)
There's no point keeping the server's queue lock after seeing that the
server's queue is empty, just like there's no need to keep the proxy's
lock when its queue is empty. This patch checks for emptiness and
releases these locks as soon as possible.

With this the performance increased from 524k to 530k on 16 threads
with round-robin.

src/queue.c

index 8db2da2c04568cba8bc4bbc079692c67528e3a7d..e16331f6d2a8a2f2184e80f59854a0fb4f82f3c1 100644 (file)
@@ -270,20 +270,23 @@ static struct pendconn *pendconn_process_next_strm(struct server *srv, struct pr
        u32 pkey, ppkey;
 
        p = NULL;
-       HA_SPIN_LOCK(QUEUE_LOCK, &srv->queue.lock);
-       if (srv->queue.length)
+       if (srv->queue.length) {
+               HA_SPIN_LOCK(QUEUE_LOCK, &srv->queue.lock);
                p = pendconn_first(&srv->queue.head);
+               if (!p)
+                       HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
+       }
 
        pp = NULL;
-       HA_SPIN_LOCK(QUEUE_LOCK, &px->queue.lock);
-       if (px_ok && px->queue.length)
+       if (px_ok && px->queue.length) {
+               HA_SPIN_LOCK(QUEUE_LOCK, &px->queue.lock);
                pp = pendconn_first(&px->queue.head);
+               if (!pp)
+                       HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
+       }
 
-       if (!p && !pp) {
-               HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
-               HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
+       if (!p && !pp)
                return NULL;
-       }
        else if (!pp)
                goto use_p; /*  p != NULL */
        else if (!p)
@@ -311,16 +314,18 @@ static struct pendconn *pendconn_process_next_strm(struct server *srv, struct pr
 
  use_pp:
        /* Let's switch from the server pendconn to the proxy pendconn */
+       if (p)
+               HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
        __pendconn_unlink_prx(pp);
        HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
-       HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
        _HA_ATOMIC_INC(&px->queue.idx);
        _HA_ATOMIC_DEC(&px->queue.length);
        _HA_ATOMIC_DEC(&px->totpend);
        p = pp;
        goto unlinked;
  use_p:
-       HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
+       if (pp)
+               HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock);
        __pendconn_unlink_srv(p);
        HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock);
        _HA_ATOMIC_INC(&srv->queue.idx);