]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: fd: slightly optimize the fd_takeover double-CAS loop
authorWilly Tarreau <w@1wt.eu>
Thu, 18 Jun 2020 06:05:15 +0000 (08:05 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 18 Jun 2020 06:08:50 +0000 (08:08 +0200)
The loop in fd_takeover() around the double-CAS is conditionned on
a previous value of old_masks[0] that always matches tid_bit on the
first iteration because it does not result from the atomic op but
from a pre-loaded value. Let's set the result of the atomic op there
instead so that the conflict between threads can be detected earlier
and before performing the double-word CAS.

src/fd.c

index cd792a13e2af11e364a396d5c0c723966c32d858..b028b4cadc43ba0915e2be51d6bf8c7f6484b83d 100644 (file)
--- a/src/fd.c
+++ b/src/fd.c
@@ -367,14 +367,15 @@ int fd_takeover(int fd, void *expected_owner)
        unsigned long old_masks[2];
        unsigned long new_masks[2];
 
-       old_masks[0] = tid_bit;
-       old_masks[1] = fdtab[fd].thread_mask;
        new_masks[0] = new_masks[1] = tid_bit;
+
+       old_masks[0] = _HA_ATOMIC_OR(&fdtab[fd].running_mask, tid_bit);
+       old_masks[1] = fdtab[fd].thread_mask;
+
        /* protect ourself against a delete then an insert for the same fd,
         * if it happens, then the owner will no longer be the expected
         * connection.
         */
-       _HA_ATOMIC_OR(&fdtab[fd].running_mask, tid_bit);
        if (fdtab[fd].owner != expected_owner) {
                _HA_ATOMIC_AND(&fdtab[fd].running_mask, ~tid_bit);
                return -1;