From 5b3927531145384bad8d2b46ca21f017afde81c7 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 18 Jun 2021 20:12:11 +0200 Subject: [PATCH] MEDIUM: queue: unlock as soon as possible 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 | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/queue.c b/src/queue.c index 8db2da2c0..e16331f6d 100644 --- a/src/queue.c +++ b/src/queue.c @@ -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 (!p && !pp) { - HA_SPIN_UNLOCK(QUEUE_LOCK, &px->queue.lock); - HA_SPIN_UNLOCK(QUEUE_LOCK, &srv->queue.lock); - return NULL; + if (!pp) + HA_SPIN_UNLOCK(QUEUE_LOCK, &px->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);