Hi Devendra,

Here's a patch that I tested a little bit and apparently work for me.
Fell free to test it as well on your machine and to report here. It
fixes the build issue and allows you to run with threads.

Cheers,
Willy
>From c27bba26e5bcd772aa8b1c9a1319a2919df13f34 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w...@1wt.eu>
Date: Thu, 4 Jan 2018 18:49:31 +0100
Subject: MINOR: hathreads: add support for gcc < 4.7

Till now the use of __atomic_* gcc builtins required gcc >= 4.7. Since
some supported and quite common operating systems like CentOS 6 still
come with older versions (4.4) and the mapping to the older builtins
is reasonably simple, let's implement it.

This code is only used for gcc < 4.7. It has been quickly tested on a
machine using gcc 4.4.4 and provided expected results.

This patch should be backported to 1.8.
---
 include/common/hathreads.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/include/common/hathreads.h b/include/common/hathreads.h
index 9782ca9..503abbe 100644
--- a/include/common/hathreads.h
+++ b/include/common/hathreads.h
@@ -99,6 +99,58 @@ extern THREAD_LOCAL unsigned long tid_bit; /* The bit 
corresponding to the threa
 
 /* TODO: thread: For now, we rely on GCC builtins but it could be a good idea 
to
  * have a header file regrouping all functions dealing with threads. */
+
+#if defined(__GNUC__) && (__GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ < 7)
+/* gcc < 4.7 */
+
+#define HA_ATOMIC_ADD(val, i)        __sync_add_and_fetch(val, i)
+#define HA_ATOMIC_SUB(val, i)        __sync_sub_and_fetch(val, i)
+#define HA_ATOMIC_AND(val, flags)    __sync_and_and_fetch(val, flags)
+#define HA_ATOMIC_OR(val, flags)     __sync_or_and_fetch(val,  flags)
+
+/* the CAS is a bit complicated. The older API doesn't support returning the
+ * value and the swap's result at the same time. So here we take what looks
+ * like the safest route, consisting in using the boolean version guaranteeing
+ * that the operation was performed or not, and we snoop a previous value. If
+ * the compare succeeds, we return. If it fails, we return the previous value,
+ * but only if it differs from the expected one. If it's the same it's a race
+ * thus we try again to avoid confusing a possibly sensitive caller.
+ */
+#define HA_ATOMIC_CAS(val, old, new)                                          \
+       ({                                                                     \
+               typeof((val)) __val = (val);                                   \
+               typeof((old)) __oldp = (old);                                  \
+               typeof(*(old)) __oldv;                                         \
+               typeof((new)) __new = (new);                                   \
+               int __ret;                                                     \
+               do {                                                           \
+                       __oldv = *__val;                                       \
+                       __ret = __sync_bool_compare_and_swap(__val, *__oldp, 
__new); \
+               } while (!__ret && *__oldp == __oldv);                         \
+               if (!__ret)                                                    \
+                       *__oldp = __oldv;                                      \
+               __ret;                                                         \
+       })
+
+#define HA_ATOMIC_XCHG(val, new)                                              \
+       ({                                                                     \
+               typeof((val)) __val = (val);                                   \
+               typeof(*(val)) __old;                                          \
+               typeof((new)) __new = (new);                                   \
+               do { __old = *__val;                                           \
+               } while (!__sync_bool_compare_and_swap(__val, __old, __new));  \
+               __old;                                                         \
+       })
+#define HA_ATOMIC_STORE(val, new)                                           \
+       ({                                                                     \
+               typeof((val)) __val = (val);                                   \
+               typeof(*(val)) __old;                                          \
+               typeof((new)) __new = (new);                                   \
+               do { __old = *__val;                                           \
+               } while (!__sync_bool_compare_and_swap(__val, __old, __new));  \
+       })
+#else
+/* gcc >= 4.7 */
 #define HA_ATOMIC_CAS(val, old, new) __atomic_compare_exchange_n(val, old, 
new, 0, 0, 0)
 #define HA_ATOMIC_ADD(val, i)        __atomic_add_fetch(val, i, 0)
 #define HA_ATOMIC_SUB(val, i)        __atomic_sub_fetch(val, i, 0)
@@ -106,6 +158,8 @@ extern THREAD_LOCAL unsigned long tid_bit; /* The bit 
corresponding to the threa
 #define HA_ATOMIC_OR(val, flags)     __atomic_or_fetch(val,  flags, 0)
 #define HA_ATOMIC_XCHG(val, new)     __atomic_exchange_n(val, new, 0)
 #define HA_ATOMIC_STORE(val, new)    __atomic_store_n(val, new, 0)
+#endif
+
 #define HA_ATOMIC_UPDATE_MAX(val, new)                                 \
        ({                                                              \
                typeof(*(val)) __old = *(val);                          \
-- 
1.7.12.1

Reply via email to