]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: atomic: reimplement the relaxed version of x86 BTS/BTR
authorWilly Tarreau <w@1wt.eu>
Mon, 12 Apr 2021 07:58:31 +0000 (09:58 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 12 Apr 2021 08:01:44 +0000 (10:01 +0200)
Olivier spotted that I messed up during a rebase of commit 92c059c2a
("MINOR: atomic: implement native BTS/BTR for x86"), losing the x86
version of the BTS/BTR and leaving the generic version for it instead
of having this block in the #else. Since this variant is not used for
now it was easy to overlook it. Let's re-implement it here.

include/haproxy/atomic.h

index 9f566908b3b0cda48697459e92f0da4cb35132ab..792c42c0df371034670e20f30fdadce66509fe62 100644 (file)
 #define _HA_ATOMIC_FETCH_SUB(val, i)     __atomic_fetch_sub(val, i, __ATOMIC_RELAXED)
 
 #if defined(__GCC_ASM_FLAG_OUTPUTS__) && (defined(__i386__) || defined (__x86_64__))
+#define _HA_ATOMIC_BTS(val, bit)                                       \
+       ({                                                              \
+               unsigned char __ret;                                    \
+               if (sizeof(long) == 8 && sizeof(*(val)) == 8) {         \
+                       asm volatile("lock btsq %2, %0\n"               \
+                                    : "+m" (*(val)), "=@ccc"(__ret)    \
+                                    : "Ir" ((unsigned long)(bit))      \
+                                    : "cc");                           \
+               } else if (sizeof(*(val)) == 4) {                       \
+                       asm volatile("lock btsl %2, %0\n"               \
+                                    : "+m" (*(val)), "=@ccc"(__ret)    \
+                                    : "Ir" ((unsigned int)(bit))       \
+                                    : "cc");                           \
+               } else if (sizeof(*(val)) == 2) {                       \
+                       asm volatile("lock btsw %2, %0\n"               \
+                                    : "+m" (*(val)), "=@ccc"(__ret)    \
+                                    : "Ir" ((unsigned short)(bit))     \
+                                    : "cc");                           \
+               } else {                                                \
+                       typeof(*(val)) __b_bts = (1UL << (bit));        \
+                       __ret = !!(__atomic_fetch_or((val), __b_bts, __ATOMIC_RELAXED) & __b_bts); \
+               }                                                       \
+               __ret;                                                  \
+       })
+
+#define _HA_ATOMIC_BTR(val, bit)                                       \
+       ({                                                              \
+               unsigned char __ret;                                    \
+               if (sizeof(long) == 8 && sizeof(*(val)) == 8) {         \
+                       asm volatile("lock btrq %2, %0\n"               \
+                                    : "+m" (*(val)), "=@ccc"(__ret)    \
+                                    : "Ir" ((unsigned long)(bit))      \
+                                    : "cc");                           \
+               } else if (sizeof(*(val)) == 4) {                       \
+                       asm volatile("lock btrl %2, %0\n"               \
+                                    : "+m" (*(val)), "=@ccc"(__ret)    \
+                                    : "Ir" ((unsigned int)(bit))       \
+                                    : "cc");                           \
+               } else if (sizeof(*(val)) == 2) {                       \
+                       asm volatile("lock btrw %2, %0\n"               \
+                                    : "+m" (*(val)), "=@ccc"(__ret)    \
+                                    : "Ir" ((unsigned short)(bit))     \
+                                    : "cc");                           \
+               } else {                                                \
+                       typeof(*(val)) __b_bts = (1UL << (bit));        \
+                       __ret = !!(__atomic_fetch_and((val), ~__b_bts, __ATOMIC_RELAXED) & __b_bts); \
+               }                                                       \
+               __ret;                                                  \
+       })
+
+#else // not x86 or !__GCC_ASM_FLAG_OUTPUTS__
+
 #define _HA_ATOMIC_BTS(val, bit)                                       \
        ({                                                              \
                typeof(*(val)) __b_bts = (1UL << (bit));                \