Add compatibility support for older intel cpus
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 8 Oct 2009 03:48:37 +0000 (23:48 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 8 Oct 2009 03:48:37 +0000 (23:48 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Makefile.am
README
configure.ac
tests/Makefile.am
urcu-pointer.c
urcu/arch_ppc.h
urcu/arch_s390.h
urcu/arch_x86.h
urcu/uatomic_arch_ppc.h
urcu/uatomic_arch_s390.h
urcu/uatomic_arch_x86.h

index 623c193ff4397c1bafe85e976beab9faaa1cb4e5..f7d64f67bdf10caf37910ff5be957872dbceb88b 100644 (file)
@@ -9,29 +9,38 @@ include_HEADERS = urcu.h $(top_srcdir)/urcu-*.h
 nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h urcu/rculist.h urcu/system.h
 nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic_arch.h
 
-EXTRA_DIST = $(top_srcdir)/urcu/arch_*.h $(top_srcdir)/urcu/uatomic_arch_*.h gpl-2.0.txt lgpl-2.1.txt lgpl-relicensing.txt README LICENSE
+EXTRA_DIST = $(top_srcdir)/urcu/arch_*.h $(top_srcdir)/urcu/uatomic_arch_*.h \
+               gpl-2.0.txt lgpl-2.1.txt lgpl-relicensing.txt \
+               README LICENSE compat_arch_x86.c
+
+if COMPAT_ARCH
+COMPAT=compat_arch_@ARCHTYPE@.c
+else
+COMPAT=
+endif
+
 
 lib_LTLIBRARIES = liburcu.la liburcu-mb.la liburcu-defer.la liburcu-qsbr.la liburcu-bp.la
 
-liburcu_la_SOURCES = urcu.c urcu-pointer.c
+liburcu_la_SOURCES = urcu.c urcu-pointer.c $(COMPAT)
 
-liburcu_mb_la_SOURCES = urcu.c urcu-pointer.c
+liburcu_mb_la_SOURCES = urcu.c urcu-pointer.c $(COMPAT)
 liburcu_mb_la_CFLAGS = -DURCU_MB
 
-liburcu_bp_la_SOURCES = urcu-bp.c urcu-pointer.c
+liburcu_bp_la_SOURCES = urcu-bp.c urcu-pointer.c $(COMPAT)
 
-liburcu_defer_la_SOURCES = urcu-defer.c
+liburcu_defer_la_SOURCES = urcu-defer.c $(COMPAT)
 
-liburcu_qsbr_la_SOURCES = urcu-qsbr.c urcu-pointer.c
+liburcu_qsbr_la_SOURCES = urcu-qsbr.c urcu-pointer.c $(COMPAT)
 
 *.h *.c: urcu/arch.h urcu/uatomic_arch.h
 
 urcu/arch.h: $(top_srcdir)/urcu/arch_@ARCHTYPE@.h
-       mkdir -p $(top_builddir)/urcu
+       $(MKDIR_P) $(top_builddir)/urcu
        cp -f $(top_srcdir)/urcu/arch_@ARCHTYPE@.h $(top_builddir)/urcu/arch.h
 
 urcu/uatomic_arch.h: $(top_srcdir)/urcu/uatomic_arch_@ARCHTYPE@.h
-       mkdir -p $(top_builddir)/urcu
+       $(MKDIR_P) $(top_builddir)/urcu
        cp -f $(top_srcdir)/urcu/uatomic_arch_@ARCHTYPE@.h $(top_builddir)/urcu/uatomic_arch.h
 
 clean-local:
diff --git a/README b/README
index f9437dba2857856b726cc4539b6deeafaf09f668..0f92ac690f1ce884139b18557cea062e893abc80 100644 (file)
--- a/README
+++ b/README
@@ -9,20 +9,22 @@ BUILDING
        make
        make install
 
-       Note:   Forcing 32-bit build:
+       Hints:  Forcing 32-bit build:
                * CFLAGS=-m32 ./configure
 
                Forcing 64-bit build:
                * CFLAGS=-m64 ./configure
 
+               Forcing a 32-bit build with down to 386 compatibility:
+               * CFLAGS=-m32 ./configure --target=i386-pc-linux-gnu
+
 ARCHITECTURES SUPPORTED
 -----------------------
 
-Currently, x86 (only P6+), x86 64, PowerPC 32/64 and S390 are
+Currently, x86 (i386, i486, i586, i686), x86 64, PowerPC 32/64 and S390 are
 supported. The current use of sys_futex() makes it Linux-dependent, although
 this portability limitation might go away in a near future by using the pthread
-cond vars. Also, the restriction against i386, i486 and Pentium might go away if
-we integrate some of glibc runtime CPU-detection tests.
+cond vars.
 
 QUICK START GUIDE
 -----------------
@@ -136,3 +138,13 @@ Usage of DEBUG_YIELD
 
        DEBUG_YIELD is used to add random delays in the code for testing
        purposes.
+
+SMP support
+
+       By default the library is configured to use synchronization primitives
+       adequate for SMP systems. On uniprocessor systems, support for SMP
+       systems can be disabled with:
+
+               ./configure --disable-smp-support
+
+       theoretically yielding slightly better performance.
index 4d0cbec8887a3e0b869c55c92ef9fe3a33283419..422b11b31f721a7ba32adc3a6e55d52067e1a3ee 100644 (file)
@@ -4,8 +4,12 @@
 
 AC_INIT([userspace-rcu], [0.2.3-alpha], [mathieu dot desnoyers at polymtl dot ca])
 AC_CONFIG_AUX_DIR([config])
+AC_CANONICAL_TARGET
+AC_CANONICAL_HOST
 AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip])
 AC_CONFIG_SRCDIR([urcu.h])
+
+AH_TEMPLATE([CONFIG_SMP], [Enable SMP support. With SMP support enabled, uniprocessors are also supported. With SMP support disabled, UP systems work fine, but the behavior of SMP systems is undefined.])
 AC_CONFIG_HEADERS([config.h])
 
 # Checks for programs.
@@ -24,12 +28,15 @@ AC_FUNC_MMAP
 AC_CHECK_FUNCS([bzero gettimeofday munmap strtoul])
 
 # Find arch type
-case $host_cpu in
+case $target_cpu in
+       i386) ARCHTYPE="x86"; SUBARCHTYPE="x86compat" ;;
+       i486) ARCHTYPE="x86"; SUBARCHTYPE="x86compat" ;;
+       i586) ARCHTYPE="x86"; SUBARCHTYPE="x86compat" ;;
+       i686) ARCHTYPE="x86"; SUBARCHTYPE="x86compat" ;;
        x86_64) ARCHTYPE="x86";;
-       i586) ARCHTYPE="x86" ;;
-       i686) ARCHTYPE="x86" ;;
        powerpc) ARCHTYPE="ppc" ;;
        ppc64) ARCHTYPE="ppc" ;;
+       powerpc64) ARCHTYPE="ppc" ;;
        ppc) ARCHTYPE="ppc" ;;
        s390) ARCHTYPE="s390" ;;
        s390x) ARCHTYPE="s390" ;;
@@ -40,9 +47,25 @@ if test "$ARCHTYPE" = "unknown"; then
        AC_MSG_ERROR([Unable to detect the architecture.])
 fi
 AC_SUBST(ARCHTYPE)
+AC_SUBST(SUBARCHTYPE)
 
 AM_CONDITIONAL([GCC_API], [test "x$ARCHTYPE" != xx86 -a "x$ARCHTYPE" != xppc])
 
+AM_CONDITIONAL([COMPAT_ARCH], [test "x$SUBARCHTYPE" == xx86compat ])
+
+AC_ARG_ENABLE([smp-support], [  --disable-smp-support   Disable SMP support. Warning: only use this
+                          on uniprocessor systems. [[default=enabled]]], [def_smp_support=$enableval], [def_smp_support="yes"])
+
+[
+if test "$def_smp_support" = "no"; then
+       echo "SMP support disabled."
+else
+]
+       AC_DEFINE([CONFIG_SMP], [1])
+[
+       echo "SMP support enabled."
+fi
+]
 
 AC_CONFIG_FILES([
        Makefile
index b1be5b1902214625c0c25584cf94dd6a68d4a689..983ee6777890819ced85bc519aae9b30f8e91266 100644 (file)
@@ -13,15 +13,21 @@ noinst_PROGRAMS = test_urcu test_urcu_dynamic_link test_urcu_timing \
 
 noinst_HEADERS = rcutorture.h
 
-URCU_SIGNAL=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c
+if COMPAT_ARCH
+COMPAT=$(top_builddir)/compat_arch_@ARCHTYPE@.c
+else
+COMPAT=
+endif
+
+URCU_SIGNAL=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c $(COMPAT)
 # URCU_SIGNAL_YIELD uses urcu.c but -DDEBUG_YIELD must be defined
-URCU_SIGNAL_YIELD=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c
+URCU_SIGNAL_YIELD=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c $(COMPAT)
 # URCU_MB uses urcu.c but -DURCU_MB must be defined
-URCU_MB=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c
-URCU_BP=$(top_builddir)/urcu-bp.c $(top_builddir)/urcu-pointer.c
-URCU_QSBR=$(top_builddir)/urcu-qsbr.c $(top_builddir)/urcu-pointer.c
+URCU_MB=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c $(COMPAT)
+URCU_BP=$(top_builddir)/urcu-bp.c $(top_builddir)/urcu-pointer.c $(COMPAT)
+URCU_QSBR=$(top_builddir)/urcu-qsbr.c $(top_builddir)/urcu-pointer.c $(COMPAT)
 # -DURCU_MB must be defined
-URCU_MB_DEFER=$(top_builddir)/urcu.c $(top_builddir)/urcu-defer.c $(top_builddir)/urcu-pointer.c
+URCU_MB_DEFER=$(top_builddir)/urcu.c $(top_builddir)/urcu-defer.c $(top_builddir)/urcu-pointer.c $(COMPAT)
 
 
 if GCC_API
index da8b1ea7e76d0c702af5adb37f32361597525022..79ee72a08e7110ba67a44b80f834096543eaa379 100644 (file)
@@ -50,5 +50,9 @@ void *rcu_xchg_pointer_sym(void **p, void *v)
 void *rcu_cmpxchg_pointer_sym(void **p, void *old, void *_new)
 {
        wmb();
-       return uatomic_cmpxchg(p, old, _new);
+       if (likely(URCU_CAS_AVAIL()))
+               return uatomic_cmpxchg(p, old, _new);
+
+       /* Compatibility for i386. Old-timer. */
+       return compat_uatomic_cmpxchg(p, old, _new);
 }
index edd1139cf761d28889b5561b44a9ddd32f52440b..40a4359417872c0099a59d0d01d8ac2065447a26 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <urcu/compiler.h>
+#include "config.h"
 
 #define CONFIG_HAVE_FENCE 1
 #define CONFIG_HAVE_MEM_COHERENCY
@@ -53,9 +54,6 @@
 #define rmc()  barrier()
 #define wmc()  barrier()
 
-/* Assume SMP machine, given we don't have this information */
-#define CONFIG_SMP 1
-
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
 #define smp_rmb()      rmb()
index 71717686c77f23589e8664981aa1126a4248896c..1a43c6cff6a22847f288241fed60db77b3fcb933 100644 (file)
  */
 
 #include <compiler.h>
+#include "config.h"
 
 #define CONFIG_HAVE_MEM_COHERENCY
-/* Assume SMP machine, given we don't have this information */
-#define CONFIG_SMP 1
 
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG  (__SIZEOF_LONG__ * 8)
index 66b27d5574df9d0b90820e0020282ec79616167f..806878e26791132b1813c1ca25197efee59b06ce 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <urcu/compiler.h>
+#include "config.h"
 
 /* Assume P4 or newer */
 #define CONFIG_HAVE_FENCE 1
@@ -63,9 +64,6 @@
 #define rmc()  barrier()
 #define wmc()  barrier()
 
-/* Assume SMP machine, given we don't have this information */
-#define CONFIG_SMP 1
-
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
 #define smp_rmb()      rmb()
index 40de9ff9909dc10327bb75e29aca9e33f7743f41..68b5faaf7c0510f41455bb4ac1b08edbccda8102 100644 (file)
@@ -228,4 +228,7 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val,
 #define uatomic_inc(addr)              uatomic_add((addr), 1)
 #define uatomic_dec(addr)              uatomic_add((addr), -1)
 
+#define URCU_CAS_AVAIL()       1
+#define compat_uatomic_cmpxchg(ptr, old, _new) uatomic_cmpxchg(ptr, old, _new)
+
 #endif /* _URCU_ARCH_UATOMIC_PPC_H */
index 917dbf2f471941457adcfff198f25c1f08747ce9..b37e5f0fbf4a771aec326e04e3c6abc468f4a4ff 100644 (file)
@@ -217,4 +217,6 @@ unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
                                               (unsigned long)(new),    \
                                               sizeof(*(addr)))
 
+#define URCU_CAS_AVAIL()       1
+
 #endif /* _URCU_ARCH_ATOMIC_S390_H */
index 43de9e6be5543bb90811f373007b0fa88b6f1af6..fccea8e2d350321ebe9cbf4517a68866e4b5fa19 100644 (file)
@@ -397,4 +397,20 @@ void _uatomic_dec(void *addr, int len)
 
 #define uatomic_dec(addr)      (_uatomic_dec((addr), sizeof(*(addr))))
 
+#if (BITS_PER_LONG == 64)
+#define URCU_CAS_AVAIL()       1
+#define compat_uatomic_cmpxchg(ptr, old, _new) uatomic_cmpxchg(ptr, old, _new)
+#else
+extern int __urcu_cas_avail;
+#define URCU_CAS_AVAIL()       __urcu_cas_avail
+
+extern unsigned long _compat_uatomic_cmpxchg(void *addr, unsigned long old,
+                             unsigned long _new, int len);
+
+#define compat_uatomic_cmpxchg(addr, old, _new)                                     \
+       ((__typeof__(*(addr))) _uatomic_cmpxchg((addr), (unsigned long)(old),\
+                                               (unsigned long)(_new),       \
+                                               sizeof(*(addr))))
+#endif
+
 #endif /* _URCU_ARCH_UATOMIC_X86_H */
This page took 0.030823 seconds and 4 git commands to generate.