]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] definitely fix regparm issues between haproxy core and ebtree
authorWilly Tarreau <w@1wt.eu>
Tue, 27 Oct 2009 20:40:18 +0000 (21:40 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 27 Oct 2009 20:53:58 +0000 (21:53 +0100)
It's a pain to enable regparm because ebtree is built in its corner
and does not depend on the rest of the config. This causes no problem
except that if the regparm settings are not exactly similar, then we
can get inconsistent function interfaces and crashes.

One solution realized in this patch consists in externalizing all
compiler settings and changing CONFIG_XXX_REGPARM into CONFIG_REGPARM
so that we ensure that any sub-component uses the same setting. Since
ebtree used a value here and not a boolean, haproxy's config has been
set to use a number too. Both haproxy's core and ebtree currently use
the same copy of the compiler.h file. That way we don't have any issue
anymore when one setting changes somewhere.

Makefile
ebtree/compiler.h [new file with mode: 0644]
ebtree/ebtree.h
include/common/compat.h
include/common/compiler.h [new file with mode: 0644]
include/common/config.h
include/common/standard.h

index 824e8e19b646a4bad41637037f56b5c4b3e63cce..64ccd50aa4b3b7e3f27ca78f21f6b6ba5bb49349 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -364,7 +364,7 @@ BUILD_OPTIONS  += $(call ignore_implicit,USE_GETSOCKNAME)
 endif
 
 ifneq ($(USE_REGPARM),)
-OPTIONS_CFLAGS += -DCONFIG_HAP_USE_REGPARM
+OPTIONS_CFLAGS += -DCONFIG_REGPARM=3
 BUILD_OPTIONS  += $(call ignore_implicit,USE_REGPARM)
 endif
 
diff --git a/ebtree/compiler.h b/ebtree/compiler.h
new file mode 100644 (file)
index 0000000..7281f09
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * ebtree/compiler.h
+ * This files contains some compiler-specific settings.
+ *
+ * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <common/compiler.h>
+
index 77813c1e829498a7a2521b27584c86ef1013e5d3..76ea1e7f9fc6d13d9b4d75abf928ce98d31ec5b8 100644 (file)
 #define _EBTREE_H
 
 #include <stdlib.h>
+#include "compiler.h"
 
 /* Note: we never need to run fls on null keys, so we can optimize the fls
  * function by removing a conditional jump.
@@ -305,74 +306,6 @@ static inline int fls64(unsigned long long x)
 #define container_of(ptr, type, name) ((type *)(((void *)(ptr)) - ((long)&((type *)0)->name)))
 #endif
 
-/*
- * Gcc >= 3 provides the ability for the program to give hints to the compiler
- * about what branch of an if is most likely to be taken. This helps the
- * compiler produce the most compact critical paths, which is generally better
- * for the cache and to reduce the number of jumps. Be very careful not to use
- * this in inline functions, because the code reordering it causes very often
- * has a negative impact on the calling functions.
- */
-#if !defined(likely)
-#if __GNUC__ < 3
-#define __builtin_expect(x,y) (x)
-#define likely(x) (x)
-#define unlikely(x) (x)
-#elif __GNUC__ < 4
-/* gcc 3.x does the best job at this */
-#define likely(x) (__builtin_expect((x) != 0, 1))
-#define unlikely(x) (__builtin_expect((x) != 0, 0))
-#else
-/* GCC 4.x is stupid, it performs the comparison then compares it to 1,
- * so we cheat in a dirty way to prevent it from doing this. This will
- * only work with ints and booleans though.
- */
-#define likely(x) (x)
-#define unlikely(x) (__builtin_expect((unsigned long)(x), 0))
-#endif
-#endif
-
-/* By default, gcc does not inline large chunks of code, but we want it to
- * respect our choices.
- */
-#if !defined(forceinline)
-#if __GNUC__ < 3
-#define forceinline inline
-#else
-#define forceinline inline __attribute__((always_inline))
-#endif
-#endif
-
-/* Support passing function parameters in registers. For this, the
- * CONFIG_EBTREE_REGPARM macro has to be set to the maximal number of registers
- * allowed. Some functions have intentionally received a regparm lower than
- * their parameter count, it is in order to avoid register clobbering where
- * they are called.
- */
-#ifndef REGPRM1
-#if CONFIG_EBTREE_REGPARM >= 1
-#define REGPRM1        __attribute__((regparm(1)))
-#else
-#define REGPRM1
-#endif
-#endif
-
-#ifndef REGPRM2
-#if CONFIG_EBTREE_REGPARM >= 2
-#define REGPRM2        __attribute__((regparm(2)))
-#else
-#define REGPRM2 REGPRM1
-#endif
-#endif
-
-#ifndef REGPRM3
-#if CONFIG_EBTREE_REGPARM >= 3
-#define REGPRM3        __attribute__((regparm(3)))
-#else
-#define REGPRM3 REGPRM2
-#endif
-#endif
-
 /* Number of bits per node, and number of leaves per node */
 #define EB_NODE_BITS          1
 #define EB_NODE_BRANCHES      (1 << EB_NODE_BITS)
index 8ddb72db9edbb6d6ed885707daa024fca2c96e92..3c939ce61f6ad8b709b04a9e6d76d0ab70dd83aa 100644 (file)
 #ifndef _COMMON_COMPAT_H
 #define _COMMON_COMPAT_H
 
-/*
- * Gcc before 3.0 needs [0] to declare a variable-size array
- */
-#if  __GNUC__  < 3
-#define VAR_ARRAY      0
-#else
-#define VAR_ARRAY
-#endif
-
 /* This is needed on Linux for Netfilter includes */
 #include <sys/socket.h>
 #include <sys/types.h>
diff --git a/include/common/compiler.h b/include/common/compiler.h
new file mode 100644 (file)
index 0000000..03d82ae
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * include/common/compiler.h
+ * This files contains some compiler-specific settings.
+ *
+ * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _COMMON_COMPILER_H
+#define _COMMON_COMPILER_H
+
+
+/*
+ * Gcc before 3.0 needs [0] to declare a variable-size array
+ */
+#ifndef VAR_ARRAY
+#if  __GNUC__  < 3
+#define VAR_ARRAY      0
+#else
+#define VAR_ARRAY
+#endif
+#endif
+
+
+/* Support passing function parameters in registers. For this, the
+ * CONFIG_REGPARM macro has to be set to the maximal number of registers
+ * allowed. Some functions have intentionally received a regparm lower than
+ * their parameter count, it is in order to avoid register clobbering where
+ * they are called.
+ */
+#ifndef REGPRM1
+#if CONFIG_REGPARM >= 1 && __GNUC__ >= 3
+#define REGPRM1        __attribute__((regparm(1)))
+#else
+#define REGPRM1
+#endif
+#endif
+
+#ifndef REGPRM2
+#if CONFIG_REGPARM >= 2 && __GNUC__ >= 3
+#define REGPRM2        __attribute__((regparm(2)))
+#else
+#define REGPRM2 REGPRM1
+#endif
+#endif
+
+#ifndef REGPRM3
+#if CONFIG_REGPARM >= 3 && __GNUC__ >= 3
+#define REGPRM3        __attribute__((regparm(3)))
+#else
+#define REGPRM3 REGPRM2
+#endif
+#endif
+
+
+/* By default, gcc does not inline large chunks of code, but we want it to
+ * respect our choices.
+ */
+#if !defined(forceinline)
+#if __GNUC__ < 3
+#define forceinline inline
+#else
+#define forceinline inline __attribute__((always_inline))
+#endif
+#endif
+
+
+/*
+ * Gcc >= 3 provides the ability for the programme to give hints to the
+ * compiler about what branch of an if is most likely to be taken. This
+ * helps the compiler produce the most compact critical paths, which is
+ * generally better for the cache and to reduce the number of jumps.
+ */
+#if !defined(likely)
+#if __GNUC__ < 3
+#define __builtin_expect(x,y) (x)
+#define likely(x) (x)
+#define unlikely(x) (x)
+#elif __GNUC__ < 4
+/* gcc 3.x does the best job at this */
+#define likely(x) (__builtin_expect((x) != 0, 1))
+#define unlikely(x) (__builtin_expect((x) != 0, 0))
+#else
+/* GCC 4.x is stupid, it performs the comparison then compares it to 1,
+ * so we cheat in a dirty way to prevent it from doing this. This will
+ * only work with ints and booleans though.
+ */
+#define likely(x) (x)
+#define unlikely(x) (__builtin_expect((unsigned long)(x), 0))
+#endif
+#endif
+
+
+#endif /* _COMMON_COMPILER_H */
index 5efa7cbb5af6f0637e426d9a93c29ba67011adbf..5833cfcdb869e38840881b38c5bef56457e08bde 100644 (file)
@@ -1,27 +1,28 @@
 /*
-  include/common/config.h
-  This files contains most of the user-configurable settings.
-
 Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation, version 2.1
-  exclusively.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
* include/common/config.h
* This files contains most of the user-configurable settings.
+ *
* Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
 #ifndef _COMMON_CONFIG_H
 #define _COMMON_CONFIG_H
 
+#include <common/compiler.h>
 #include <common/defaults.h>
 
 /* this reduces the number of calls to select() by choosing appropriate
  */
 //#undef  CONFIG_HAP_INLINE_FD_SET
 
-/* CONFIG_HAP_USE_REGPARM
- * This enables the use of register parameters for some functions where
- * it may improve performance by a measurable factor. This MUST NOT be
- * enabled on gcc < 3 because it is ignored for function pointers.
- */
-#if CONFIG_HAP_USE_REGPARM && __GNUC__ >= 3
-#define REGPRM1 __attribute__((regparm(1)))
-#define REGPRM2 __attribute__((regparm(2)))
-#define REGPRM3 __attribute__((regparm(3)))
-#else
-#define REGPRM1
-#define REGPRM2
-#define REGPRM3
-#endif
-
-/* By default, gcc does not inline large chunks of code, but we want it to
- * respect our choices.
- */
-#if !defined(forceinline)
-#if __GNUC__ < 3
-#define forceinline inline
-#else
-#define forceinline inline __attribute__((always_inline))
-#endif
-#endif
-
 #endif /* _COMMON_CONFIG_H */
index 0a6b68bf9d61da40e75cd184b1850b802f65a4a9..544a5c31511112db7ae692bcd3592fc1227f7995 100644 (file)
@@ -1,23 +1,23 @@
 /*
-  include/common/standard.h
-  This files contains some general purpose functions and macros.
-
-  Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation, version 2.1
-  exclusively.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
* include/common/standard.h
* This files contains some general purpose functions and macros.
+ *
* Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
 #ifndef _COMMON_STANDARD_H
 #define _COMMON_STANDARD_H
  * power of 2, and 0 otherwise */
 #define POWEROF2(x) (((x) & ((x)-1)) == 0)
 
-/*
- * Gcc >= 3 provides the ability for the programme to give hints to the
- * compiler about what branch of an if is most likely to be taken. This
- * helps the compiler produce the most compact critical paths, which is
- * generally better for the cache and to reduce the number of jumps.
- */
-#if !defined(likely)
-#if __GNUC__ < 3
-#define __builtin_expect(x,y) (x)
-#define likely(x) (x)
-#define unlikely(x) (x)
-#elif __GNUC__ < 4
-/* gcc 3.x does the best job at this */
-#define likely(x) (__builtin_expect((x) != 0, 1))
-#define unlikely(x) (__builtin_expect((x) != 0, 0))
-#else
-/* GCC 4.x is stupid, it performs the comparison then compares it to 1,
- * so we cheat in a dirty way to prevent it from doing this. This will
- * only work with ints and booleans though.
- */
-#define likely(x) (x)
-#define unlikely(x) (__builtin_expect((unsigned long)(x), 0))
-#endif
-#endif
-
 /*
  * copies at most <size-1> chars from <src> to <dst>. Last char is always
  * set to 0, unless <size> is 0. The number of chars copied is returned