Hi guys,

On Thu, Jan 04, 2018 at 11:20:32PM +0100, Lukas Tribus wrote:
> On Thu, Jan 4, 2018 at 11:11 PM, Angelo Hongens <ang...@hongens.nl> wrote:
> > On 03-01-2018 17:39, Lukas Tribus wrote:
> >>
> >> To compile Haproxy 1.8 with threads, at least GCC 4.7 is needed.
> >> CentOs 6 only ships GCC 4.4.7, therefor compilation fails.
> >> You can disable thread support, by adding USE_THREAD= to the make
> >> command (nothing comes after the equal sign):
> >
> >
> > I'm no packaging expert, but 1.8 seems to build fine on my CentOS6 build box
> > without any errors.
> >
> > I'm running gcc version 4.4.7 20120313 on CentOS 6.9.
> >
> > Here's my spec file for building RPM packages:
> >
> > https://github.com/AxisNL/haproxy-rpmbuild/blob/master/SPECS/haproxy-1.8.3.el6.spec
> >
> > Am I doing something strange?? :-)
> 
> Your are using the older build TARGET=linux26, which is for kernels
> older than 2.6.28. It doesn't enable newer features for example thread
> support (which would cause the build issue).
> For kernels >= 2.6.28 (which CentOs 6 is) we have the linux2628 build target.
> 
> Willy is working on thread support for the older kernel though, so the
> build issue will be fixed soon.

And by the way Angelo if you want to test the patch on your centos, please
find it attached. I'm just thinking that after all I should probably merge
it and in the worst case we'll improve it later, given that it at least
works for me.

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