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.
This commit is contained in:
Willy Tarreau 2021-06-18 20:12:11 +02:00
parent 9a6d0ddbd6
commit 5b39275311

View File

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