* [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins
@ 2010-02-15 19:04 Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 01/12] use kernel style makefile output Paolo Bonzini
` (12 more replies)
0 siblings, 13 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
So here we go with v2. Changes are:
- tests/api.h also symlinked
- uatomic_gcc.h renamed to uatomic_defaults.h as even architectures
that don't want __sync_* builtins use it
- improved comments about mc/rmc/wmc in urcu/arch_defaults.h
- changed BITS_PER_LONG patch since __SIZEOF_LONG__ was newer than I
thought, placed this patch at the end so you can omit it easily
if NACKed (requires GCC 3.4 on 64-bit systems, nothing on 32-bit)
- added back assembly code for PPC and S390 so that those platforms
do not need __sync_* builtins (SPARC and x86 didn't already in v1)
- added implementation of uatomic_exchange using __sync_bool_compare_and_swap
(same trick S390 is using in the assembly implementation)
- patch 11 is new
As in v1, the last patch is not to be committed. In the next days/week,
I'll try to build it on more machines and using old GCCs, but I cannot
promise anything right now...
Paolo Bonzini (12):
use kernel style makefile output
use autoconf symbolic linking
add urcu/arch_defaults.h
define sync_core for x86 PIC
remove compat_uatomic_cmpxchg #define from non-x86
add uatomic_defaults.h, use it for default definitions
use uatomic_defaults.h for common fallback implementations
move whether atomic byte/short exists to uatomic_arch_*.h
add Alpha support
support compiling on unknown architectures
avoid multiple evaluation of STORE_SHARED argument
centralize definition of BITS_PER_LONG
test uatomic_defaults.h
Makefile.am | 15 +--
configure.ac | 24 +++-
tests/Makefile.am | 12 --
tests/test_uatomic.c | 13 +--
urcu/arch_alpha.h | 48 ++++++
urcu/arch_defaults.h | 132 ++++++++++++++++
urcu/arch_ppc.h | 54 +------
urcu/arch_s390.h | 50 +------
urcu/arch_sparc64.h | 55 +-------
urcu/arch_x86.h | 68 ++-------
urcu/compiler.h | 8 +
urcu/system.h | 4 +-
urcu/uatomic_arch_alpha.h | 32 ++++
urcu/uatomic_arch_ppc.h | 29 +----
urcu/uatomic_arch_s390.h | 71 +---------
urcu/uatomic_arch_sparc64.h | 112 +-------------
urcu/uatomic_arch_x86.h | 41 ++----
urcu/uatomic_defaults.h | 354 +++++++++++++++++++++++++++++++++++++++++++
18 files changed, 634 insertions(+), 488 deletions(-)
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 01/12] use kernel style makefile output
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 02/12] use autoconf symbolic linking Paolo Bonzini
` (11 subsequent siblings)
12 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
A breath of fresh air. Requires Automake 1.11, but the
patch degrades gracefully.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
configure.ac | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index 48f906d..c797831 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,6 +7,8 @@ AC_CONFIG_AUX_DIR([config])
AC_CANONICAL_TARGET
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
AC_CONFIG_SRCDIR([urcu.h])
AM_PROG_MKDIR_P
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 02/12] use autoconf symbolic linking
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 01/12] use kernel style makefile output Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 03/12] add urcu/arch_defaults.h Paolo Bonzini
` (10 subsequent siblings)
12 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
Instead of copying. This is less error-prone while developing and
lets Automake handle more stuff.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
Makefile.am | 13 -------------
configure.ac | 15 +++++++++++++--
tests/Makefile.am | 12 ------------
3 files changed, 13 insertions(+), 27 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 4f915e1..2ede9e0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,16 +38,3 @@ liburcu_signal_la_CFLAGS = -DRCU_SIGNAL
liburcu_bp_la_SOURCES = urcu-bp.c urcu-pointer.c $(COMPAT)
liburcu_defer_la_SOURCES = urcu-defer.c $(COMPAT)
-
-$(top_srcdir)/*.h $(top_srcdir)/*.c: urcu/arch.h urcu/uatomic_arch.h
-
-urcu/arch.h: $(top_srcdir)/urcu/arch_ at ARCHTYPE@.h
- $(mkdir_p) $(top_builddir)/urcu
- cp -f $(top_srcdir)/urcu/arch_ at ARCHTYPE@.h $(top_builddir)/urcu/arch.h
-
-urcu/uatomic_arch.h: $(top_srcdir)/urcu/uatomic_arch_ at ARCHTYPE@.h
- $(mkdir_p) $(top_builddir)/urcu
- cp -f $(top_srcdir)/urcu/uatomic_arch_ at ARCHTYPE@.h $(top_builddir)/urcu/uatomic_arch.h
-
-clean-local:
- rm -f urcu/arch.h urcu/uatomic_arch.h
diff --git a/configure.ac b/configure.ac
index c797831..ab6f3a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,14 @@ esac
if test "$ARCHTYPE" = "unknown"; then
AC_MSG_ERROR([Unable to detect the architecture.])
fi
+UATOMICSRC=urcu/uatomic_arch_$ARCHTYPE.h
+ARCHSRC=urcu/arch_$ARCHTYPE.h
+if test "x$ARCHTYPE" != xx86 -a "x$ARCHTYPE" != xppc; then
+ APISRC=tests/api_gcc.h
+else
+ APISRC=tests/api_$ARCHTYPE.h
+fi
+
AC_SUBST(ARCHTYPE)
AC_SUBST(SUBARCHTYPE)
@@ -95,8 +103,6 @@ AC_TRY_COMPILE(
AM_CONDITIONAL([COMPAT_FUTEX], [ test "x$compat_futex_test" = "x1" ])
-AM_CONDITIONAL([GCC_API], [test "x$ARCHTYPE" != xx86 -a "x$ARCHTYPE" != xppc])
-
AM_CONDITIONAL([COMPAT_ARCH], [test "x$SUBARCHTYPE" = xx86compat ])
[
@@ -204,6 +210,11 @@ AC_CHECK_FUNCS(
CFLAGS=$saved_CFLAGS
+AC_CONFIG_LINKS([
+ urcu/arch.h:$ARCHSRC
+ urcu/uatomic_arch.h:$UATOMICSRC
+ tests/api.h:$APISRC
+])
AC_CONFIG_FILES([
Makefile
tests/Makefile
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 02e0583..17b89db 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -40,12 +40,6 @@ URCU_MB_LIB=$(top_builddir)/liburcu-mb.la
URCU_SIGNAL_LIB=$(top_builddir)/liburcu-signal.la
URCU_BP_LIB=$(top_builddir)/liburcu-bp.la
-if GCC_API
-APIHEADER=api_gcc.h
-else
-APIHEADER=api_ at ARCHTYPE@.h
-endif
-
EXTRA_DIST = $(top_srcdir)/tests/api_*.h
@@ -156,9 +150,3 @@ test_urcu_bp_dynamic_link_SOURCES = test_urcu_bp.c $(URCU_BP)
test_urcu_bp_dynamic_link_CFLAGS = -DDYNAMIC_LINK_TEST $(AM_CFLAGS)
urcutorture.c: api.h
-
-api.h: $(APIHEADER)
- cp -f $(srcdir)/$(APIHEADER) api.h
-
-clean-local:
- rm -f api.h
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 03/12] add urcu/arch_defaults.h
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 01/12] use kernel style makefile output Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 02/12] use autoconf symbolic linking Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-18 2:57 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 04/12] define sync_core for x86 PIC Paolo Bonzini
` (9 subsequent siblings)
12 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
Most of the memory barrier definitions are shared between all
architectures, especially smp_* and mc/rmc/wmc. Put them in
a common file.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/arch_defaults.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++
urcu/arch_ppc.h | 50 +------------------
urcu/arch_s390.h | 38 +--------------
urcu/arch_sparc64.h | 51 +------------------
urcu/arch_x86.h | 64 ++----------------------
5 files changed, 145 insertions(+), 190 deletions(-)
create mode 100644 urcu/arch_defaults.h
diff --git a/urcu/arch_defaults.h b/urcu/arch_defaults.h
new file mode 100644
index 0000000..21cc3c1
--- /dev/null
+++ b/urcu/arch_defaults.h
@@ -0,0 +1,132 @@
+#ifndef _URCU_ARCH_DEFAULTS_H
+#define _URCU_ARCH_DEFAULTS_H
+
+/*
+ * arch_defaults.h: common definitions for multiple architectures.
+ *
+ * Copyright (c) 2010 Paolo Bonzini <pbonzini at redhat.com>
+ *
+ * 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; either
+ * version 2.1 of the License, or (at your option) any later version.
+*
+ * 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 <urcu/compiler.h>
+#include <urcu/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
+#if !defined(mc) && !defined(rmc) && !defined(wmc)
+#define CONFIG_HAVE_MEM_COHERENCY
+/*
+ * Architectures with cache coherency must _not_ define mc/rmc/wmc.
+ *
+ * For them, mc/rmc/wmc are implemented with a * simple compiler barrier;
+ * in addition, we provide defaults for mb (using GCC builtins) as well as
+ * rmb and wmb (defaulting to mb).
+ */
+
+#ifndef mb
+#define mb() __sync_synchronize()
+#endif
+
+#ifndef rmb
+#define rmb() mb()
+#endif
+
+#ifndef wmb
+#define wmb() mb()
+#endif
+
+#define mc() barrier()
+#define rmc() barrier()
+#define wmc() barrier()
+#else
+/*
+ * Architectures without cache coherency need something like the following:
+ *
+ * #define mc() arch_cache_flush()
+ * #define rmc() arch_cache_flush_read()
+ * #define wmc() arch_cache_flush_write()
+ *
+ * Of these, only mc is mandatory. rmc and wmc default to mc. mb/rmb/wmb
+ * use these definitions by default:
+ *
+ * #define mb() mc()
+ * #define rmb() rmc()
+ * #define wmb() wmc()
+ */
+
+#ifndef mb
+#define mb() mc()
+#endif
+
+#ifndef rmb
+#define rmb() rmc()
+#endif
+
+#ifndef wmb
+#define wmb() wmc()
+#endif
+
+#ifndef rmc
+#define rmc() mc()
+#endif
+
+#ifndef wmc
+#define wmc() mc()
+#endif
+#endif
+
+/* Nop everywhere except on alpha. */
+#ifndef read_barrier_depends
+#define read_barrier_depends()
+#endif
+
+#ifdef CONFIG_RCU_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#define smp_mc() mc()
+#define smp_rmc() rmc()
+#define smp_wmc() wmc()
+#define smp_read_barrier_depends() read_barrier_depends()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#define smp_mc() barrier()
+#define smp_rmc() barrier()
+#define smp_wmc() barrier()
+#define smp_read_barrier_depends()
+#endif
+
+#ifndef cpu_relax
+#define cpu_relax() barrier()
+#endif
+
+#ifndef sync_core
+#define sync_core() mb()
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _URCU_ARCH_DEFAULTS_H */
diff --git a/urcu/arch_ppc.h b/urcu/arch_ppc.h
index c1762ae..f925d07 100644
--- a/urcu/arch_ppc.h
+++ b/urcu/arch_ppc.h
@@ -29,8 +29,6 @@
extern "C" {
#endif
-#define CONFIG_HAVE_MEM_COHERENCY
-
/* Include size of POWER5+ L3 cache lines: 256 bytes */
#define CACHE_LINE_SIZE 256
@@ -39,55 +37,11 @@ extern "C" {
#endif
#define mb() asm volatile("sync":::"memory")
-#define rmb() asm volatile("sync":::"memory")
-#define wmb() asm volatile("sync"::: "memory")
-
-/*
- * Architectures without cache coherency need something like the following:
- *
- * #define mb() mc()
- * #define rmb() rmc()
- * #define wmb() wmc()
- * #define mc() arch_cache_flush()
- * #define rmc() arch_cache_flush_read()
- * #define wmc() arch_cache_flush_write()
- */
-
-#define mc() barrier()
-#define rmc() barrier()
-#define wmc() barrier()
-
-#ifdef CONFIG_RCU_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_mc() mc()
-#define smp_rmc() rmc()
-#define smp_wmc() wmc()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_mc() barrier()
-#define smp_rmc() barrier()
-#define smp_wmc() barrier()
-#endif
-
-/* Nop everywhere except on alpha. */
-#define smp_read_barrier_depends()
-
-static inline void cpu_relax(void)
-{
- barrier();
-}
/*
* Serialize core instruction execution. Also acts as a compiler barrier.
*/
-static inline void sync_core()
-{
- asm volatile("isync" : : : "memory");
-}
+#define sync_core() asm volatile("isync" : : : "memory")
#define mftbl() \
({ \
@@ -123,4 +77,6 @@ static inline cycles_t get_cycles (void)
}
#endif
+#include <urcu/arch_defaults.h>
+
#endif /* _URCU_ARCH_PPC_H */
diff --git a/urcu/arch_s390.h b/urcu/arch_s390.h
index 22a1853..0982112 100644
--- a/urcu/arch_s390.h
+++ b/urcu/arch_s390.h
@@ -35,8 +35,6 @@
extern "C" {
#endif
-#define CONFIG_HAVE_MEM_COHERENCY
-
#define CACHE_LINE_SIZE 128
#ifndef __SIZEOF_LONG__
@@ -52,40 +50,6 @@ extern "C" {
#endif
#define mb() __asm__ __volatile__("bcr 15,0" : : : "memory")
-#define rmb() __asm__ __volatile__("bcr 15,0" : : : "memory")
-#define wmb() __asm__ __volatile__("bcr 15,0" : : : "memory")
-#define mc() barrier()
-#define rmc() barrier()
-#define wmc() barrier()
-
-#ifdef CONFIG_RCU_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_mc() mc()
-#define smp_rmc() rmc()
-#define smp_wmc() wmc()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_mc() barrier()
-#define smp_rmc() barrier()
-#define smp_wmc() barrier()
-#endif
-
-/* Nop everywhere except on alpha. */
-#define smp_read_barrier_depends()
-
-static inline void cpu_relax(void)
-{
- barrier();
-}
-
-static inline void sync_core()
-{
- __asm__ __volatile__("bcr 15,0" : : : "memory");
-}
typedef unsigned long long cycles_t;
@@ -102,4 +66,6 @@ static inline cycles_t get_cycles (void)
}
#endif
+#include <urcu/arch_defaults.h>
+
#endif /* _URCU_ARCH_S390_H */
diff --git a/urcu/arch_sparc64.h b/urcu/arch_sparc64.h
index 54c4c3c..c906168 100644
--- a/urcu/arch_sparc64.h
+++ b/urcu/arch_sparc64.h
@@ -29,8 +29,6 @@
extern "C" {
#endif
-#define CONFIG_HAVE_MEM_COHERENCY
-
#define CACHE_LINE_SIZE 256
#ifndef BITS_PER_LONG
@@ -50,53 +48,6 @@ __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
#define rmb() membar_safe("#LoadLoad")
#define wmb() membar_safe("#StoreStore")
-/*
- * Architectures without cache coherency need something like the following:
- *
- * #define mb() mc()
- * #define rmb() rmc()
- * #define wmb() wmc()
- * #define mc() arch_cache_flush()
- * #define rmc() arch_cache_flush_read()
- * #define wmc() arch_cache_flush_write()
- */
-
-#define mc() barrier()
-#define rmc() barrier()
-#define wmc() barrier()
-
-#ifdef CONFIG_RCU_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_mc() mc()
-#define smp_rmc() rmc()
-#define smp_wmc() wmc()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_mc() barrier()
-#define smp_rmc() barrier()
-#define smp_wmc() barrier()
-#endif
-
-/* Nop everywhere except on alpha. */
-#define smp_read_barrier_depends()
-
-static inline void cpu_relax(void)
-{
- barrier();
-}
-
-/*
- * Serialize core instruction execution. Also acts as a compiler barrier.
- */
-static inline void sync_core()
-{
- mb();
-}
-
typedef unsigned long long cycles_t;
static inline cycles_t get_cycles (void)
@@ -108,4 +59,6 @@ static inline cycles_t get_cycles (void)
}
#endif
+#include <urcu/arch_defaults.h>
+
#endif /* _URCU_ARCH_SPARC64_H */
diff --git a/urcu/arch_x86.h b/urcu/arch_x86.h
index 4abac2b..bc03379 100644
--- a/urcu/arch_x86.h
+++ b/urcu/arch_x86.h
@@ -29,8 +29,6 @@
extern "C" {
#endif
-#define CONFIG_HAVE_MEM_COHERENCY
-
#define CACHE_LINE_SIZE 128
#ifdef CONFIG_RCU_HAVE_FENCE
@@ -47,68 +45,16 @@ extern "C" {
#define wmb() asm volatile("lock; addl $0,0(%%esp)"::: "memory")
#endif
-/*
- * Architectures without cache coherency need something like the following:
- *
- * #define mb() mc()
- * #define rmb() rmc()
- * #define wmb() wmc()
- * #define mc() arch_cache_flush()
- * #define rmc() arch_cache_flush_read()
- * #define wmc() arch_cache_flush_write()
- */
-
-#define mc() barrier()
-#define rmc() barrier()
-#define wmc() barrier()
-
-#ifdef CONFIG_RCU_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_mc() mc()
-#define smp_rmc() rmc()
-#define smp_wmc() wmc()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_mc() barrier()
-#define smp_rmc() barrier()
-#define smp_wmc() barrier()
-#endif
-
-/* Nop everywhere except on alpha. */
-#define smp_read_barrier_depends()
-
-static inline void rep_nop(void)
-{
- asm volatile("rep; nop" : : : "memory");
-}
-
-static inline void cpu_relax(void)
-{
- rep_nop();
-}
+#define cpu_relax() asm volatile("rep; nop" : : : "memory");
/*
* Serialize core instruction execution. Also acts as a compiler barrier.
- */
-#ifdef __PIC__
-/*
- * Cannot use cpuid because it clobbers the ebx register and clashes
- * with -fPIC :
+ * Cannot use cpuid on PIC because it clobbers the ebx register;
* error: PIC register 'ebx' clobbered in 'asm'
*/
-static inline void sync_core(void)
-{
- mb();
-}
-#else
-static inline void sync_core(void)
-{
+#ifndef __PIC__
+#define sync_core() \
asm volatile("cpuid" : : : "memory", "eax", "ebx", "ecx", "edx");
-}
#endif
#define rdtscll(val) \
@@ -133,4 +79,6 @@ static inline cycles_t get_cycles(void)
}
#endif
+#include <urcu/arch_defaults.h>
+
#endif /* _URCU_ARCH_X86_H */
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 04/12] define sync_core for x86 PIC
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (2 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 03/12] add urcu/arch_defaults.h Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 05/12] remove compat_uatomic_cmpxchg #define from non-x86 Paolo Bonzini
` (8 subsequent siblings)
12 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
Pushing/popping the reserved ebx register is surely less expensive
than a memory barrier.
Note that since ebx is a callee-save register, this is even safe for
signals (i.e. it would be safe even if we needed the value that cpuid
puts in %%ebx).
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/arch_x86.h | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/urcu/arch_x86.h b/urcu/arch_x86.h
index bc03379..eac0d19 100644
--- a/urcu/arch_x86.h
+++ b/urcu/arch_x86.h
@@ -49,9 +49,13 @@ extern "C" {
/*
* Serialize core instruction execution. Also acts as a compiler barrier.
- * Cannot use cpuid on PIC because it clobbers the ebx register;
- * error: PIC register 'ebx' clobbered in 'asm'
+ * On PIC ebx cannot be clobbered
*/
+#ifdef __PIC__
+#define sync_core() \
+ asm volatile("push %%ebx; cpuid; pop %%ebx" \
+ : : : "memory", "eax", "ecx", "edx");
+#endif
#ifndef __PIC__
#define sync_core() \
asm volatile("cpuid" : : : "memory", "eax", "ebx", "ecx", "edx");
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 05/12] remove compat_uatomic_cmpxchg #define from non-x86
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (3 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 04/12] define sync_core for x86 PIC Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 06/12] add uatomic_defaults.h, use it for default definitions Paolo Bonzini
` (7 subsequent siblings)
12 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
This is unused everywhere except on x86.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/uatomic_arch_ppc.h | 2 --
urcu/uatomic_arch_s390.h | 2 --
urcu/uatomic_arch_sparc64.h | 2 --
3 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/urcu/uatomic_arch_ppc.h b/urcu/uatomic_arch_ppc.h
index 2322c97..8da192e 100644
--- a/urcu/uatomic_arch_ppc.h
+++ b/urcu/uatomic_arch_ppc.h
@@ -235,8 +235,6 @@ 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 compat_uatomic_cmpxchg(ptr, old, _new) uatomic_cmpxchg(ptr, old, _new)
-
#ifdef __cplusplus
}
#endif
diff --git a/urcu/uatomic_arch_s390.h b/urcu/uatomic_arch_s390.h
index fdfabfd..614867f 100644
--- a/urcu/uatomic_arch_s390.h
+++ b/urcu/uatomic_arch_s390.h
@@ -218,8 +218,6 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
#define uatomic_inc(addr) uatomic_add((addr), 1)
#define uatomic_dec(addr) uatomic_add((addr), -1)
-#define compat_uatomic_cmpxchg(ptr, old, _new) uatomic_cmpxchg(ptr, old, _new)
-
#ifdef __cplusplus
}
#endif
diff --git a/urcu/uatomic_arch_sparc64.h b/urcu/uatomic_arch_sparc64.h
index 3aa3b7d..d443d4f 100644
--- a/urcu/uatomic_arch_sparc64.h
+++ b/urcu/uatomic_arch_sparc64.h
@@ -179,8 +179,6 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
#define uatomic_inc(addr) uatomic_add((addr), 1)
#define uatomic_dec(addr) uatomic_add((addr), -1)
-#define compat_uatomic_cmpxchg(ptr, old, _new) uatomic_cmpxchg(ptr, old, _new)
-
#ifdef __cplusplus
}
#endif
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 06/12] add uatomic_defaults.h, use it for default definitions
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (4 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 05/12] remove compat_uatomic_cmpxchg #define from non-x86 Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-18 3:10 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 07/12] use uatomic_defaults.h for common fallback implementations Paolo Bonzini
` (6 subsequent siblings)
12 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
uatomic_defaults.h can be included by uatomic_arch_*.h to provide useful
default definitions. uatomic_arch_*.h can define whatever builtins
it wants to override, then uatomic_defaults.h will provide what is not
already defined, as follows:
- uatomic_cmpxchg will use __sync_val_compare_and_swap builtins;
- uatomic_add_return will use __sync_fetch_and_add if uatomic_arch_*.h
did not provide a definition of uatomic_cmpxchg. If it did, we assume
__sync builtins are buggy or otherwise undesirable on this platform,
so uatomic_defaults.h will implement uatomic_add_return in terms of
uatomic_cmpxchg too.
- uatomic_xchg is like uatomic_add_return. However, since GCC does
not provide an adequate builtin, it needs to use a compare-and-swap
loop using __sync_bool_compare_and_swap if uatomic_cmpxchg is not
provided.
- uatomic_sub_return/uatomic_add/uatomic_sub will be implemented
in terms of uatomic_add_return;
- uatomic_inc/uatomic_dec will be implemented in terms of uatomic_add.
After this patch, uatomic_defaults.h is already used for the latter two
categories.
The hunk in tests/test_uatomic.c is only needed for bisectability
and will be removed later.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
Makefile.am | 2 +-
tests/test_uatomic.c | 2 +
urcu/uatomic_arch_ppc.h | 15 +--
urcu/uatomic_arch_s390.h | 15 +--
urcu/uatomic_arch_sparc64.h | 15 +--
urcu/uatomic_arch_x86.h | 26 ++---
urcu/uatomic_defaults.h | 262 +++++++++++++++++++++++++++++++++++++++++++
7 files changed, 280 insertions(+), 57 deletions(-)
create mode 100644 urcu/uatomic_defaults.h
diff --git a/Makefile.am b/Makefile.am
index 2ede9e0..c91dfe9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,7 @@ SUBDIRS = . tests
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 urcu/urcu-futex.h
+ urcu/rculist.h urcu/system.h urcu/urcu-futex.h urcu/uatomic_defaults.h
nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic_arch.h urcu/config.h
EXTRA_DIST = $(top_srcdir)/urcu/arch_*.h $(top_srcdir)/urcu/uatomic_arch_*.h \
diff --git a/tests/test_uatomic.c b/tests/test_uatomic.c
index 68cb6df..c0f36fe 100644
--- a/tests/test_uatomic.c
+++ b/tests/test_uatomic.c
@@ -1,5 +1,7 @@
#include <stdio.h>
#include <assert.h>
+
+#define UATOMIC_NO_LINK_ERROR
#include <urcu/uatomic_arch.h>
#if (defined(__i386__) || defined(__x86_64__))
diff --git a/urcu/uatomic_arch_ppc.h b/urcu/uatomic_arch_ppc.h
index 8da192e..b42bfdb 100644
--- a/urcu/uatomic_arch_ppc.h
+++ b/urcu/uatomic_arch_ppc.h
@@ -47,9 +47,6 @@ extern "C" {
#define ILLEGAL_INSTR ".long 0xd00d00"
-#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
-#define uatomic_read(addr) LOAD_SHARED(*(addr))
-
/*
* Using a isync as second barrier for exchange to provide acquire semantic.
* According to uatomic_ops/sysdeps/gcc/powerpc.h, the documentation is "fairly
@@ -225,18 +222,10 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val,
(unsigned long)(v), \
sizeof(*(addr))))
-/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
-
-#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
-
-#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
-#define uatomic_sub(addr, v) (void)uatomic_sub_return((addr), (v))
-
-#define uatomic_inc(addr) uatomic_add((addr), 1)
-#define uatomic_dec(addr) uatomic_add((addr), -1)
-
#ifdef __cplusplus
}
#endif
+#include <urcu/uatomic_defaults.h>
+
#endif /* _URCU_ARCH_UATOMIC_PPC_H */
diff --git a/urcu/uatomic_arch_s390.h b/urcu/uatomic_arch_s390.h
index 614867f..8f1523c 100644
--- a/urcu/uatomic_arch_s390.h
+++ b/urcu/uatomic_arch_s390.h
@@ -78,9 +78,6 @@ struct __uatomic_dummy {
};
#define __hp(x) ((struct __uatomic_dummy *)(x))
-#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
-#define uatomic_read(addr) LOAD_SHARED(*(addr))
-
/* xchg */
static inline __attribute__((always_inline))
@@ -208,18 +205,10 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
(unsigned long)(v), \
sizeof(*(addr))))
-/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
-
-#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
-
-#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
-#define uatomic_sub(addr, v) (void)uatomic_sub_return((addr), (v))
-
-#define uatomic_inc(addr) uatomic_add((addr), 1)
-#define uatomic_dec(addr) uatomic_add((addr), -1)
-
#ifdef __cplusplus
}
#endif
+#include <urcu/uatomic_defaults.h>
+
#endif /* _URCU_UATOMIC_ARCH_S390_H */
diff --git a/urcu/uatomic_arch_sparc64.h b/urcu/uatomic_arch_sparc64.h
index d443d4f..0c16eaf 100644
--- a/urcu/uatomic_arch_sparc64.h
+++ b/urcu/uatomic_arch_sparc64.h
@@ -39,9 +39,6 @@ extern "C" {
#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
#endif
-#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
-#define uatomic_read(addr) LOAD_SHARED(*(addr))
-
/* cmpxchg */
static inline __attribute__((always_inline))
@@ -169,18 +166,10 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
(unsigned long)(v), \
sizeof(*(addr))))
-/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
-
-#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
-
-#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
-#define uatomic_sub(addr, v) (void)uatomic_sub_return((addr), (v))
-
-#define uatomic_inc(addr) uatomic_add((addr), 1)
-#define uatomic_dec(addr) uatomic_add((addr), -1)
-
#ifdef __cplusplus
}
#endif
+#include <urcu/uatomic_defaults.h>
+
#endif /* _URCU_ARCH_UATOMIC_PPC_H */
diff --git a/urcu/uatomic_arch_x86.h b/urcu/uatomic_arch_x86.h
index 3bfe86d..8a81995 100644
--- a/urcu/uatomic_arch_x86.h
+++ b/urcu/uatomic_arch_x86.h
@@ -49,7 +49,11 @@ struct __uatomic_dummy {
#define __hp(x) ((struct __uatomic_dummy *)(x))
#define _uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
+
+#if 0
+/* Read is atomic even in compat mode */
#define _uatomic_read(addr) LOAD_SHARED(*(addr))
+#endif
/* cmpxchg */
@@ -176,7 +180,7 @@ unsigned long __uatomic_exchange(void *addr, unsigned long val, int len)
((__typeof__(*(addr))) __uatomic_exchange((addr), (unsigned long)(v), \
sizeof(*(addr))))
-/* uatomic_add_return, uatomic_sub_return */
+/* uatomic_add_return */
static inline __attribute__((always_inline))
unsigned long __uatomic_add_return(void *addr, unsigned long val,
@@ -241,9 +245,7 @@ unsigned long __uatomic_add_return(void *addr, unsigned long val,
(unsigned long)(v), \
sizeof(*(addr))))
-#define _uatomic_sub_return(addr, v) _uatomic_add_return((addr), -(v))
-
-/* uatomic_add, uatomic_sub */
+/* uatomic_add */
static inline __attribute__((always_inline))
void __uatomic_add(void *addr, unsigned long val, int len)
@@ -297,8 +299,6 @@ void __uatomic_add(void *addr, unsigned long val, int len)
#define _uatomic_add(addr, v) \
(__uatomic_add((addr), (unsigned long)(v), sizeof(*(addr))))
-#define _uatomic_sub(addr, v) _uatomic_add((addr), -(v))
-
/* uatomic_inc */
@@ -449,24 +449,17 @@ extern unsigned long _compat_uatomic_xchg(void *addr,
(unsigned long)(v), \
sizeof(*(addr))))
-#define compat_uatomic_sub_return(addr, v) \
- compat_uatomic_add_return((addr), -(v))
#define compat_uatomic_add(addr, v) \
((void)compat_uatomic_add_return((addr), (v)))
-#define compat_uatomic_sub(addr, v) \
- ((void)compat_uatomic_sub_return((addr), (v)))
#define compat_uatomic_inc(addr) \
(compat_uatomic_add((addr), 1))
#define compat_uatomic_dec(addr) \
- (compat_uatomic_sub((addr), 1))
+ (compat_uatomic_add((addr), -1))
#else
#define UATOMIC_COMPAT(insn) (_uatomic_##insn)
#endif
-/* Read is atomic even in compat mode */
-#define uatomic_read(addr) _uatomic_read(addr)
-
#define uatomic_set(addr, v) \
UATOMIC_COMPAT(set(addr, v))
#define uatomic_cmpxchg(addr, old, _new) \
@@ -475,10 +468,7 @@ extern unsigned long _compat_uatomic_xchg(void *addr,
UATOMIC_COMPAT(xchg(addr, v))
#define uatomic_add_return(addr, v) \
UATOMIC_COMPAT(add_return(addr, v))
-#define uatomic_sub_return(addr, v) \
- UATOMIC_COMPAT(sub_return(addr, v))
#define uatomic_add(addr, v) UATOMIC_COMPAT(add(addr, v))
-#define uatomic_sub(addr, v) UATOMIC_COMPAT(sub(addr, v))
#define uatomic_inc(addr) UATOMIC_COMPAT(inc(addr))
#define uatomic_dec(addr) UATOMIC_COMPAT(dec(addr))
@@ -486,4 +476,6 @@ extern unsigned long _compat_uatomic_xchg(void *addr,
}
#endif
+#include <urcu/uatomic_defaults.h>
+
#endif /* _URCU_ARCH_UATOMIC_X86_H */
diff --git a/urcu/uatomic_defaults.h b/urcu/uatomic_defaults.h
new file mode 100644
index 0000000..93467dd
--- /dev/null
+++ b/urcu/uatomic_defaults.h
@@ -0,0 +1,262 @@
+#ifndef _URCU_UATOMIC_GCC_H
+#define _URCU_UATOMIC_GCC_H
+
+/*
+ * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
+ * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
+ * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P.
+ * Copyright (c) 2009 Mathieu Desnoyers
+ * Copyright (c) 2010 Paolo Bonzini
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program
+ * for any purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ * Code inspired from libuatomic_ops-1.2, inherited in part from the
+ * Boehm-Demers-Weiser conservative garbage collector.
+ */
+
+#include <urcu/compiler.h>
+#include <urcu/system.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef BITS_PER_LONG
+#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
+#endif
+
+#ifndef uatomic_set
+#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
+#endif
+
+#ifndef uatomic_read
+#define uatomic_read(addr) LOAD_SHARED(*(addr))
+#endif
+
+#if !defined __OPTIMIZE__ || defined UATOMIC_NO_LINK_ERROR
+static inline __attribute__((always_inline))
+void _uatomic_link_error()
+{
+#ifdef ILLEGAL_INSTR
+ /* generate an illegal instruction. Cannot catch this with linker tricks
+ * when optimizations are disabled. */
+ __asm__ __volatile__(ILLEGAL_INSTR);
+#else
+ __builtin_trap ();
+#endif
+}
+#else
+extern void _uatomic_link_error ();
+#endif
+
+/* cmpxchg */
+
+#ifndef uatomic_cmpxchg
+static inline __attribute__((always_inline))
+unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
+ unsigned long _new, int len)
+{
+ switch (len) {
+ case 4:
+ return __sync_val_compare_and_swap_4(addr, old, _new);
+#if (BITS_PER_LONG == 64)
+ case 8:
+ return __sync_val_compare_and_swap_8(addr, old, _new);
+#endif
+ }
+ _uatomic_link_error();
+ return 0;
+}
+
+
+#define uatomic_cmpxchg(addr, old, _new) \
+ ((__typeof__(*(addr))) _uatomic_cmpxchg((addr), (unsigned long)(old),\
+ (unsigned long)(_new), \
+ sizeof(*(addr))))
+
+
+/* uatomic_add_return */
+
+#ifndef uatomic_add_return
+static inline __attribute__((always_inline))
+unsigned long _uatomic_add_return(void *addr, unsigned long val,
+ int len)
+{
+ switch (len) {
+ case 4:
+ return __sync_add_and_fetch_4(addr, val);
+#if (BITS_PER_LONG == 64)
+ case 8:
+ return __sync_add_and_fetch_8(addr, val);
+#endif
+ }
+ _uatomic_link_error();
+ return 0;
+}
+
+
+#define uatomic_add_return(addr, v) \
+ ((__typeof__(*(addr))) _uatomic_add_return((addr), \
+ (unsigned long)(v), \
+ sizeof(*(addr))))
+#endif
+
+#ifndef uatomic_xchg
+/* xchg */
+
+static inline __attribute__((always_inline))
+unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
+{
+ switch (len) {
+ case 4:
+ {
+ unsigned int old;
+
+ do
+ old = uatomic_read((unsigned int *)addr);
+ while (!__sync_bool_compare_and_swap_4(addr, old, val));
+
+ return old;
+ }
+#if (BITS_PER_LONG == 64)
+ case 8:
+ {
+ unsigned long old;
+
+ do
+ old = uatomic_read((unsigned long *)addr);
+ while (!__sync_bool_compare_and_swap_8(addr, old, val));
+
+ return old;
+ }
+#endif
+ }
+ _uatomic_link_error();
+ return 0;
+}
+
+#define uatomic_xchg(addr, v) \
+ ((__typeof__(*(addr))) _uatomic_exchange((addr), (unsigned long)(v), \
+ sizeof(*(addr))))
+#endif
+
+#else
+
+#ifndef uatomic_add_return
+/* uatomic_add_return */
+
+static inline __attribute__((always_inline))
+unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
+{
+ switch (len) {
+ case 4:
+ {
+ unsigned int old, oldt;
+
+ oldt = uatomic_read((unsigned int *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, old + val, 4);
+ } while (oldt != old);
+
+ return old + val;
+ }
+#if (BITS_PER_LONG == 64)
+ case 8:
+ {
+ unsigned long old, oldt;
+
+ oldt = uatomic_read((unsigned long *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, old + val, 8);
+ } while (oldt != old);
+
+ return old + val;
+ }
+#endif
+ }
+ _uatomic_link_error();
+ return 0;
+}
+
+#define uatomic_add_return(addr, v) \
+ ((__typeof__(*(addr))) _uatomic_add_return((addr), \
+ (unsigned long)(v), \
+ sizeof(*(addr))))
+#endif
+
+#ifndef uatomic_xchg
+/* xchg */
+
+static inline __attribute__((always_inline))
+unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
+{
+ switch (len) {
+ case 4:
+ {
+ unsigned int old, oldt;
+
+ oldt = uatomic_read((unsigned int *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, val, 4);
+ } while (oldt != old);
+
+ return old;
+ }
+#if (BITS_PER_LONG == 64)
+ case 8:
+ {
+ unsigned long old, oldt;
+
+ oldt = uatomic_read((unsigned long *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, val, 8);
+ } while (oldt != old);
+
+ return old;
+ }
+#endif
+ }
+ _uatomic_link_error();
+ return 0;
+}
+
+#define uatomic_xchg(addr, v) \
+ ((__typeof__(*(addr))) _uatomic_exchange((addr), (unsigned long)(v), \
+ sizeof(*(addr))))
+#endif
+
+#endif
+
+/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
+
+#ifndef uatomic_add
+#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
+#endif
+
+#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
+#define uatomic_sub(addr, v) uatomic_add((addr), -(v))
+
+#ifndef uatomic_inc
+#define uatomic_inc(addr) uatomic_add((addr), 1)
+#endif
+
+#ifndef uatomic_dec
+#define uatomic_dec(addr) uatomic_add((addr), -1)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _URCU_UATOMIC_GCC_H */
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 07/12] use uatomic_defaults.h for common fallback implementations
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (5 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 06/12] add uatomic_defaults.h, use it for default definitions Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 08/12] move whether atomic byte/short exists to uatomic_arch_*.h Paolo Bonzini
` (5 subsequent siblings)
12 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
And now, really remove the code for S390/SPARC, using the fallback
implementation of uatomic_defaults.h.
We keep custom per-arch macros to provide support for compilers back to
early GCC 3.x versions; however future ports may not support this at least
in the beginning, and unknown architectures will always try using the
GCC builtins.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/uatomic_arch_s390.h | 42 ----------------------
urcu/uatomic_arch_sparc64.h | 83 -------------------------------------------
2 files changed, 0 insertions(+), 125 deletions(-)
diff --git a/urcu/uatomic_arch_s390.h b/urcu/uatomic_arch_s390.h
index 8f1523c..2f9b532 100644
--- a/urcu/uatomic_arch_s390.h
+++ b/urcu/uatomic_arch_s390.h
@@ -163,48 +163,6 @@ unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
(unsigned long)(_new), \
sizeof(*(addr)))
-/* uatomic_add_return */
-
-static inline __attribute__((always_inline))
-unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
-{
- switch (len) {
- case 4:
- {
- unsigned int old, oldt;
-
- oldt = uatomic_read((unsigned int *)addr);
- do {
- old = oldt;
- oldt = _uatomic_cmpxchg(addr, old, old + val, 4);
- } while (oldt != old);
-
- return old + val;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- unsigned long old, oldt;
-
- oldt = uatomic_read((unsigned long *)addr);
- do {
- old = oldt;
- oldt = _uatomic_cmpxchg(addr, old, old + val, 8);
- } while (oldt != old);
-
- return old + val;
- }
-#endif
- }
- __builtin_trap();
- return 0;
-}
-
-#define uatomic_add_return(addr, v) \
- ((__typeof__(*(addr))) _uatomic_add_return((addr), \
- (unsigned long)(v), \
- sizeof(*(addr))))
-
#ifdef __cplusplus
}
#endif
diff --git a/urcu/uatomic_arch_sparc64.h b/urcu/uatomic_arch_sparc64.h
index 0c16eaf..ef6572e 100644
--- a/urcu/uatomic_arch_sparc64.h
+++ b/urcu/uatomic_arch_sparc64.h
@@ -83,89 +83,6 @@ unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
(unsigned long)(_new), \
sizeof(*(addr))))
-/* xchg */
-
-static inline __attribute__((always_inline))
-unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
-{
- switch (len) {
- case 4:
- {
- unsigned int old, oldt;
-
- oldt = uatomic_read((unsigned int *)addr);
- do {
- old = oldt;
- oldt = _uatomic_cmpxchg(addr, old, val, 4);
- } while (oldt != old);
-
- return old;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- unsigned long old, oldt;
-
- oldt = uatomic_read((unsigned long *)addr);
- do {
- old = oldt;
- oldt = _uatomic_cmpxchg(addr, old, val, 8);
- } while (oldt != old);
-
- return old;
- }
-#endif
- }
- __builtin_trap();
- return 0;
-}
-
-#define uatomic_xchg(addr, v) \
- ((__typeof__(*(addr))) _uatomic_exchange((addr), (unsigned long)(v), \
- sizeof(*(addr))))
-
-/* uatomic_add_return */
-
-static inline __attribute__((always_inline))
-unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
-{
- switch (len) {
- case 4:
- {
- unsigned int old, oldt;
-
- oldt = uatomic_read((unsigned int *)addr);
- do {
- old = oldt;
- oldt = _uatomic_cmpxchg(addr, old, old + val, 4);
- } while (oldt != old);
-
- return old + val;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- unsigned long old, oldt;
-
- oldt = uatomic_read((unsigned long *)addr);
- do {
- old = oldt;
- oldt = _uatomic_cmpxchg(addr, old, old + val, 8);
- } while (oldt != old);
-
- return old + val;
- }
-#endif
- }
- __builtin_trap();
- return 0;
-}
-
-#define uatomic_add_return(addr, v) \
- ((__typeof__(*(addr))) _uatomic_add_return((addr), \
- (unsigned long)(v), \
- sizeof(*(addr))))
-
#ifdef __cplusplus
}
#endif
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 08/12] move whether atomic byte/short exists to uatomic_arch_*.h
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (6 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 07/12] use uatomic_defaults.h for common fallback implementations Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-18 3:12 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 09/12] add Alpha support Paolo Bonzini
` (4 subsequent siblings)
12 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
And add more generic implementations to uatomic_defaults.h.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
tests/test_uatomic.c | 15 +------
urcu/uatomic_arch_x86.h | 3 +
urcu/uatomic_defaults.h | 96 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 101 insertions(+), 13 deletions(-)
diff --git a/tests/test_uatomic.c b/tests/test_uatomic.c
index c0f36fe..5682655 100644
--- a/tests/test_uatomic.c
+++ b/tests/test_uatomic.c
@@ -1,21 +1,10 @@
#include <stdio.h>
#include <assert.h>
-
-#define UATOMIC_NO_LINK_ERROR
#include <urcu/uatomic_arch.h>
-#if (defined(__i386__) || defined(__x86_64__))
-#define HAS_ATOMIC_BYTE
-#define HAS_ATOMIC_SHORT
-#endif
-
struct testvals {
-#ifdef HAS_ATOMIC_BYTE
unsigned char c;
-#endif
-#ifdef HAS_ATOMIC_SHORT
unsigned short s;
-#endif
unsigned int i;
unsigned long l;
};
@@ -54,10 +43,10 @@ do { \
int main(int argc, char **argv)
{
-#ifdef HAS_ATOMIC_BYTE
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
do_test(&vals.c);
#endif
-#ifdef HAS_ATOMIC_SHORT
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
do_test(&vals.s);
#endif
do_test(&vals.i);
diff --git a/urcu/uatomic_arch_x86.h b/urcu/uatomic_arch_x86.h
index 8a81995..f2d0c19 100644
--- a/urcu/uatomic_arch_x86.h
+++ b/urcu/uatomic_arch_x86.h
@@ -23,6 +23,9 @@
#include <urcu/compiler.h>
#include <urcu/system.h>
+#define UATOMIC_HAS_ATOMIC_BYTE
+#define UATOMIC_HAS_ATOMIC_SHORT
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/urcu/uatomic_defaults.h b/urcu/uatomic_defaults.h
index 93467dd..2d0af6e 100644
--- a/urcu/uatomic_defaults.h
+++ b/urcu/uatomic_defaults.h
@@ -64,6 +64,14 @@ unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
unsigned long _new, int len)
{
switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+ case 1:
+ return __sync_val_compare_and_swap_1(addr, old, _new);
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+ case 2:
+ return __sync_val_compare_and_swap_2(addr, old, _new);
+#endif
case 4:
return __sync_val_compare_and_swap_4(addr, old, _new);
#if (BITS_PER_LONG == 64)
@@ -90,6 +98,14 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val,
int len)
{
switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+ case 1:
+ return __sync_add_and_fetch_1(addr, val);
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+ case 2:
+ return __sync_add_and_fetch_2(addr, val);
+#endif
case 4:
return __sync_add_and_fetch_4(addr, val);
#if (BITS_PER_LONG == 64)
@@ -115,6 +131,30 @@ static inline __attribute__((always_inline))
unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
{
switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+ case 1:
+ {
+ unsigned char old;
+
+ do
+ old = uatomic_read((unsigned char *)addr);
+ while (!__sync_bool_compare_and_swap_1(addr, old, val));
+
+ return old;
+ }
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+ case 2:
+ {
+ unsigned short old;
+
+ do
+ old = uatomic_read((unsigned short *)addr);
+ while (!__sync_bool_compare_and_swap_2(addr, old, val));
+
+ return old;
+ }
+#endif
case 4:
{
unsigned int old;
@@ -156,6 +196,34 @@ static inline __attribute__((always_inline))
unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
{
switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+ case 1:
+ {
+ unsigned char old, oldt;
+
+ oldt = uatomic_read((unsigned char *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, old + val, 1);
+ } while (oldt != old);
+
+ return old + val;
+ }
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+ case 2:
+ {
+ unsigned short old, oldt;
+
+ oldt = uatomic_read((unsigned short *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, old + val, 2);
+ } while (oldt != old);
+
+ return old + val;
+ }
+#endif
case 4:
{
unsigned int old, oldt;
@@ -200,6 +268,34 @@ static inline __attribute__((always_inline))
unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
{
switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+ case 1:
+ {
+ unsigned char old, oldt;
+
+ oldt = uatomic_read((unsigned char *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, val, 1);
+ } while (oldt != old);
+
+ return old;
+ }
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+ case 2:
+ {
+ unsigned short old, oldt;
+
+ oldt = uatomic_read((unsigned short *)addr);
+ do {
+ old = oldt;
+ oldt = _uatomic_cmpxchg(addr, old, val, 2);
+ } while (oldt != old);
+
+ return old;
+ }
+#endif
case 4:
{
unsigned int old, oldt;
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 09/12] add Alpha support
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (7 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 08/12] move whether atomic byte/short exists to uatomic_arch_*.h Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-18 3:21 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 10/12] support compiling on unknown architectures Paolo Bonzini
` (3 subsequent siblings)
12 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
And you already know what needs to be special-cased for Alpha...
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
configure.ac | 1 +
urcu/arch_alpha.h | 48 +++++++++++++++++++++++++++++++++++++++++++++
urcu/uatomic_arch_alpha.h | 32 ++++++++++++++++++++++++++++++
3 files changed, 81 insertions(+), 0 deletions(-)
create mode 100644 urcu/arch_alpha.h
create mode 100644 urcu/uatomic_arch_alpha.h
diff --git a/configure.ac b/configure.ac
index ab6f3a2..1ce19d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,7 @@ case $host_cpu in
s390) ARCHTYPE="s390" ;;
s390x) ARCHTYPE="s390" ;;
sparc64) ARCHTYPE="sparc64" ;;
+ alpha*) ARCHTYPE="alpha" ;;
*) ARCHTYPE="unknown";;
esac
diff --git a/urcu/arch_alpha.h b/urcu/arch_alpha.h
new file mode 100644
index 0000000..4d521de
--- /dev/null
+++ b/urcu/arch_alpha.h
@@ -0,0 +1,48 @@
+#ifndef _URCU_ARCH_ALPHA_H
+#define _URCU_ARCH_ALPHA_H
+
+/*
+ * arch_ppc.h: trivial definitions for the Alpha architecture.
+ *
+ * Copyright (c) 2010 Paolo Bonzini <pbonzini at redhat.com>
+ *
+ * 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; either
+ * version 2.1 of the License, or (at your option) any later version.
+*
+ * 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 <urcu/compiler.h>
+#include <urcu/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define mb() asm volatile("mb":::"memory")
+#define wmb() asm volatile("wmb":::"memory")
+#define read_barrier_depends() asm volatile("mb":::"memory")
+
+typedef unsigned long long cycles_t;
+
+static inline cycles_t get_cycles (void)
+{
+ return 0; /* not supported */
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <urcu/arch_defaults.h>
+
+#endif /* _URCU_ARCH_ALPHA_H */
diff --git a/urcu/uatomic_arch_alpha.h b/urcu/uatomic_arch_alpha.h
new file mode 100644
index 0000000..6d002cb
--- /dev/null
+++ b/urcu/uatomic_arch_alpha.h
@@ -0,0 +1,32 @@
+#ifndef _URCU_UATOMIC_ARCH_ALPHA_H
+#define _URCU_UATOMIC_ARCH_ALPHA_H
+
+/*
+ * Atomic exchange operations for the Alpha architecture. Let GCC do it.
+ *
+ * Copyright (c) 2010 Paolo Bonzini <pbonzini at redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <urcu/compiler.h>
+#include <urcu/system.h>
+#include <urcu/uatomic_defaults.h>
+
+#endif /* _URCU_UATOMIC_ARCH_ALPHA_H */
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 10/12] support compiling on unknown architectures
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (8 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 09/12] add Alpha support Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-18 3:22 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 11/12] avoid multiple evaluation of STORE_SHARED argument Paolo Bonzini
` (2 subsequent siblings)
12 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
The new defaults mean that, for example, ia64 support comes for free.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
configure.ac | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index 1ce19d0..871e600 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,11 +54,13 @@ case $host_cpu in
*) ARCHTYPE="unknown";;
esac
-if test "$ARCHTYPE" = "unknown"; then
- AC_MSG_ERROR([Unable to detect the architecture.])
+if test "$ARCHTYPE" != "unknown"; then
+ UATOMICSRC=urcu/uatomic_arch_$ARCHTYPE.h
+ ARCHSRC=urcu/arch_$ARCHTYPE.h
+else
+ UATOMICSRC=urcu/uatomic_defaults.h
+ ARCHSRC=urcu/arch_defaults.h
fi
-UATOMICSRC=urcu/uatomic_arch_$ARCHTYPE.h
-ARCHSRC=urcu/arch_$ARCHTYPE.h
if test "x$ARCHTYPE" != xx86 -a "x$ARCHTYPE" != xppc; then
APISRC=tests/api_gcc.h
else
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 11/12] avoid multiple evaluation of STORE_SHARED argument
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (9 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 10/12] support compiling on unknown architectures Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-18 3:28 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 13/12] test uatomic_defaults.h Paolo Bonzini
12 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/system.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/urcu/system.h b/urcu/system.h
index e36a13b..0c3152f 100644
--- a/urcu/system.h
+++ b/urcu/system.h
@@ -46,9 +46,9 @@
*/
#define STORE_SHARED(x, v) \
({ \
- _STORE_SHARED(x, v); \
+ typeof(x) _v = _STORE_SHARED(x, v); \
smp_wmc(); \
- (v); \
+ _v; \
})
#endif /* _URCU_SYSTEM_H */
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (10 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 11/12] avoid multiple evaluation of STORE_SHARED argument Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
2010-02-18 3:25 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 13/12] test uatomic_defaults.h Paolo Bonzini
12 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
Use __SIZEOF_LONG__, defined by GCC 4.3 or later, or _LP64, defined
by GCC 3.4 or later. The GCC 3.4 requirement is only for 64-bit
systems.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/arch_ppc.h | 4 ----
urcu/arch_s390.h | 12 ------------
urcu/arch_sparc64.h | 4 ----
urcu/compiler.h | 8 ++++++++
urcu/uatomic_arch_ppc.h | 12 ------------
urcu/uatomic_arch_s390.h | 12 ------------
urcu/uatomic_arch_sparc64.h | 12 ------------
urcu/uatomic_arch_x86.h | 12 ------------
urcu/uatomic_defaults.h | 4 ----
9 files changed, 8 insertions(+), 72 deletions(-)
diff --git a/urcu/arch_ppc.h b/urcu/arch_ppc.h
index f925d07..41e6a7c 100644
--- a/urcu/arch_ppc.h
+++ b/urcu/arch_ppc.h
@@ -32,10 +32,6 @@ extern "C" {
/* Include size of POWER5+ L3 cache lines: 256 bytes */
#define CACHE_LINE_SIZE 256
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
#define mb() asm volatile("sync":::"memory")
/*
diff --git a/urcu/arch_s390.h b/urcu/arch_s390.h
index 0982112..889fc0d 100644
--- a/urcu/arch_s390.h
+++ b/urcu/arch_s390.h
@@ -37,18 +37,6 @@ extern "C" {
#define CACHE_LINE_SIZE 128
-#ifndef __SIZEOF_LONG__
-#ifdef __s390x__
-#define __SIZEOF_LONG__ 8
-#else
-#define __SIZEOF_LONG__ 4
-#endif
-#endif
-
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
#define mb() __asm__ __volatile__("bcr 15,0" : : : "memory")
typedef unsigned long long cycles_t;
diff --git a/urcu/arch_sparc64.h b/urcu/arch_sparc64.h
index c906168..c10afeb 100644
--- a/urcu/arch_sparc64.h
+++ b/urcu/arch_sparc64.h
@@ -31,10 +31,6 @@ extern "C" {
#define CACHE_LINE_SIZE 256
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
/*
* Inspired from the Linux kernel. Workaround Spitfire bug #51.
*/
diff --git a/urcu/compiler.h b/urcu/compiler.h
index aab2c5c..5b7bb30 100644
--- a/urcu/compiler.h
+++ b/urcu/compiler.h
@@ -47,4 +47,12 @@
#define min(a,b) ((a)<(b)?(a):(b))
#endif
+#if defined(__SIZEOF_LONG__)
+#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
+#elif defined(_LP64)
+#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
+
#endif /* _URCU_COMPILER_H */
diff --git a/urcu/uatomic_arch_ppc.h b/urcu/uatomic_arch_ppc.h
index b42bfdb..801c41c 100644
--- a/urcu/uatomic_arch_ppc.h
+++ b/urcu/uatomic_arch_ppc.h
@@ -27,24 +27,12 @@
extern "C" {
#endif
-#ifndef __SIZEOF_LONG__
-#ifdef __powerpc64__
-#define __SIZEOF_LONG__ 8
-#else
-#define __SIZEOF_LONG__ 4
-#endif
-#endif
-
#ifdef __NO_LWSYNC__
#define LWSYNC_OPCODE "sync\n"
#else
#define LWSYNC_OPCODE "lwsync\n"
#endif
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
#define ILLEGAL_INSTR ".long 0xd00d00"
/*
diff --git a/urcu/uatomic_arch_s390.h b/urcu/uatomic_arch_s390.h
index 2f9b532..44bcb97 100644
--- a/urcu/uatomic_arch_s390.h
+++ b/urcu/uatomic_arch_s390.h
@@ -36,18 +36,6 @@
extern "C" {
#endif
-#ifndef __SIZEOF_LONG__
-#ifdef __s390x__
-#define __SIZEOF_LONG__ 8
-#else
-#define __SIZEOF_LONG__ 4
-#endif
-#endif
-
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define COMPILER_HAVE_SHORT_MEM_OPERAND
#endif
diff --git a/urcu/uatomic_arch_sparc64.h b/urcu/uatomic_arch_sparc64.h
index ef6572e..df66cd1 100644
--- a/urcu/uatomic_arch_sparc64.h
+++ b/urcu/uatomic_arch_sparc64.h
@@ -27,18 +27,6 @@
extern "C" {
#endif
-#ifndef __SIZEOF_LONG__
-#ifdef __LP64__
-#define __SIZEOF_LONG__ 8
-#else
-#define __SIZEOF_LONG__ 4
-#endif
-#endif
-
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
/* cmpxchg */
static inline __attribute__((always_inline))
diff --git a/urcu/uatomic_arch_x86.h b/urcu/uatomic_arch_x86.h
index f2d0c19..269618c 100644
--- a/urcu/uatomic_arch_x86.h
+++ b/urcu/uatomic_arch_x86.h
@@ -30,18 +30,6 @@
extern "C" {
#endif
-#ifndef __SIZEOF_LONG__
-#if defined(__x86_64__) || defined(__amd64__)
-#define __SIZEOF_LONG__ 8
-#else
-#define __SIZEOF_LONG__ 4
-#endif
-#endif
-
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
/*
* Derived from AO_compare_and_swap() and AO_test_and_set_full().
*/
diff --git a/urcu/uatomic_defaults.h b/urcu/uatomic_defaults.h
index 2d0af6e..5c93261 100644
--- a/urcu/uatomic_defaults.h
+++ b/urcu/uatomic_defaults.h
@@ -28,10 +28,6 @@
extern "C" {
#endif
-#ifndef BITS_PER_LONG
-#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
-#endif
-
#ifndef uatomic_set
#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
#endif
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 13/12] test uatomic_defaults.h
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
` (11 preceding siblings ...)
2010-02-15 19:04 ` [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG Paolo Bonzini
@ 2010-02-15 19:04 ` Paolo Bonzini
12 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-15 19:04 UTC (permalink / raw)
Not-signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/uatomic_arch_x86.h | 442 -----------------------------------------------
1 files changed, 0 insertions(+), 442 deletions(-)
diff --git a/urcu/uatomic_arch_x86.h b/urcu/uatomic_arch_x86.h
index 269618c..8a60433 100644
--- a/urcu/uatomic_arch_x86.h
+++ b/urcu/uatomic_arch_x86.h
@@ -25,448 +25,6 @@
#define UATOMIC_HAS_ATOMIC_BYTE
#define UATOMIC_HAS_ATOMIC_SHORT
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Derived from AO_compare_and_swap() and AO_test_and_set_full().
- */
-
-struct __uatomic_dummy {
- unsigned long v[10];
-};
-#define __hp(x) ((struct __uatomic_dummy *)(x))
-
-#define _uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
-
-#if 0
-/* Read is atomic even in compat mode */
-#define _uatomic_read(addr) LOAD_SHARED(*(addr))
-#endif
-
-/* cmpxchg */
-
-static inline __attribute__((always_inline))
-unsigned long __uatomic_cmpxchg(void *addr, unsigned long old,
- unsigned long _new, int len)
-{
- switch (len) {
- case 1:
- {
- unsigned char result = old;
-
- __asm__ __volatile__(
- "lock; cmpxchgb %2, %1"
- : "+a"(result), "+m"(*__hp(addr))
- : "q"((unsigned char)_new)
- : "memory");
- return result;
- }
- case 2:
- {
- unsigned short result = old;
-
- __asm__ __volatile__(
- "lock; cmpxchgw %2, %1"
- : "+a"(result), "+m"(*__hp(addr))
- : "r"((unsigned short)_new)
- : "memory");
- return result;
- }
- case 4:
- {
- unsigned int result = old;
-
- __asm__ __volatile__(
- "lock; cmpxchgl %2, %1"
- : "+a"(result), "+m"(*__hp(addr))
- : "r"((unsigned int)_new)
- : "memory");
- return result;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- unsigned long result = old;
-
- __asm__ __volatile__(
- "lock; cmpxchgq %2, %1"
- : "+a"(result), "+m"(*__hp(addr))
- : "r"((unsigned long)_new)
- : "memory");
- return result;
- }
-#endif
- }
- /* generate an illegal instruction. Cannot catch this with linker tricks
- * when optimizations are disabled. */
- __asm__ __volatile__("ud2");
- return 0;
-}
-
-#define _uatomic_cmpxchg(addr, old, _new) \
- ((__typeof__(*(addr))) __uatomic_cmpxchg((addr), (unsigned long)(old),\
- (unsigned long)(_new), \
- sizeof(*(addr))))
-
-/* xchg */
-
-static inline __attribute__((always_inline))
-unsigned long __uatomic_exchange(void *addr, unsigned long val, int len)
-{
- /* Note: the "xchg" instruction does not need a "lock" prefix. */
- switch (len) {
- case 1:
- {
- unsigned char result;
- __asm__ __volatile__(
- "xchgb %0, %1"
- : "=q"(result), "+m"(*__hp(addr))
- : "0" ((unsigned char)val)
- : "memory");
- return result;
- }
- case 2:
- {
- unsigned short result;
- __asm__ __volatile__(
- "xchgw %0, %1"
- : "=r"(result), "+m"(*__hp(addr))
- : "0" ((unsigned short)val)
- : "memory");
- return result;
- }
- case 4:
- {
- unsigned int result;
- __asm__ __volatile__(
- "xchgl %0, %1"
- : "=r"(result), "+m"(*__hp(addr))
- : "0" ((unsigned int)val)
- : "memory");
- return result;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- unsigned long result;
- __asm__ __volatile__(
- "xchgq %0, %1"
- : "=r"(result), "+m"(*__hp(addr))
- : "0" ((unsigned long)val)
- : "memory");
- return result;
- }
-#endif
- }
- /* generate an illegal instruction. Cannot catch this with linker tricks
- * when optimizations are disabled. */
- __asm__ __volatile__("ud2");
- return 0;
-}
-
-#define _uatomic_xchg(addr, v) \
- ((__typeof__(*(addr))) __uatomic_exchange((addr), (unsigned long)(v), \
- sizeof(*(addr))))
-
-/* uatomic_add_return */
-
-static inline __attribute__((always_inline))
-unsigned long __uatomic_add_return(void *addr, unsigned long val,
- int len)
-{
- switch (len) {
- case 1:
- {
- unsigned char result = val;
-
- __asm__ __volatile__(
- "lock; xaddb %1, %0"
- : "+m"(*__hp(addr)), "+q" (result)
- :
- : "memory");
- return result + (unsigned char)val;
- }
- case 2:
- {
- unsigned short result = val;
-
- __asm__ __volatile__(
- "lock; xaddw %1, %0"
- : "+m"(*__hp(addr)), "+r" (result)
- :
- : "memory");
- return result + (unsigned short)val;
- }
- case 4:
- {
- unsigned int result = val;
-
- __asm__ __volatile__(
- "lock; xaddl %1, %0"
- : "+m"(*__hp(addr)), "+r" (result)
- :
- : "memory");
- return result + (unsigned int)val;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- unsigned long result = val;
-
- __asm__ __volatile__(
- "lock; xaddq %1, %0"
- : "+m"(*__hp(addr)), "+r" (result)
- :
- : "memory");
- return result + (unsigned long)val;
- }
-#endif
- }
- /* generate an illegal instruction. Cannot catch this with linker tricks
- * when optimizations are disabled. */
- __asm__ __volatile__("ud2");
- return 0;
-}
-
-#define _uatomic_add_return(addr, v) \
- ((__typeof__(*(addr))) __uatomic_add_return((addr), \
- (unsigned long)(v), \
- sizeof(*(addr))))
-
-/* uatomic_add */
-
-static inline __attribute__((always_inline))
-void __uatomic_add(void *addr, unsigned long val, int len)
-{
- switch (len) {
- case 1:
- {
- __asm__ __volatile__(
- "lock; addb %1, %0"
- : "=m"(*__hp(addr))
- : "iq" ((unsigned char)val)
- : "memory");
- return;
- }
- case 2:
- {
- __asm__ __volatile__(
- "lock; addw %1, %0"
- : "=m"(*__hp(addr))
- : "ir" ((unsigned short)val)
- : "memory");
- return;
- }
- case 4:
- {
- __asm__ __volatile__(
- "lock; addl %1, %0"
- : "=m"(*__hp(addr))
- : "ir" ((unsigned int)val)
- : "memory");
- return;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- __asm__ __volatile__(
- "lock; addq %1, %0"
- : "=m"(*__hp(addr))
- : "er" ((unsigned long)val)
- : "memory");
- return;
- }
-#endif
- }
- /* generate an illegal instruction. Cannot catch this with linker tricks
- * when optimizations are disabled. */
- __asm__ __volatile__("ud2");
- return;
-}
-
-#define _uatomic_add(addr, v) \
- (__uatomic_add((addr), (unsigned long)(v), sizeof(*(addr))))
-
-
-/* uatomic_inc */
-
-static inline __attribute__((always_inline))
-void __uatomic_inc(void *addr, int len)
-{
- switch (len) {
- case 1:
- {
- __asm__ __volatile__(
- "lock; incb %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
- case 2:
- {
- __asm__ __volatile__(
- "lock; incw %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
- case 4:
- {
- __asm__ __volatile__(
- "lock; incl %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- __asm__ __volatile__(
- "lock; incq %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
-#endif
- }
- /* generate an illegal instruction. Cannot catch this with linker tricks
- * when optimizations are disabled. */
- __asm__ __volatile__("ud2");
- return;
-}
-
-#define _uatomic_inc(addr) (__uatomic_inc((addr), sizeof(*(addr))))
-
-/* uatomic_dec */
-
-static inline __attribute__((always_inline))
-void __uatomic_dec(void *addr, int len)
-{
- switch (len) {
- case 1:
- {
- __asm__ __volatile__(
- "lock; decb %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
- case 2:
- {
- __asm__ __volatile__(
- "lock; decw %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
- case 4:
- {
- __asm__ __volatile__(
- "lock; decl %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
-#if (BITS_PER_LONG == 64)
- case 8:
- {
- __asm__ __volatile__(
- "lock; decq %0"
- : "=m"(*__hp(addr))
- :
- : "memory");
- return;
- }
-#endif
- }
- /* generate an illegal instruction. Cannot catch this with linker tricks
- * when optimizations are disabled. */
- __asm__ __volatile__("ud2");
- return;
-}
-
-#define _uatomic_dec(addr) (__uatomic_dec((addr), sizeof(*(addr))))
-
-#if ((BITS_PER_LONG != 64) && defined(CONFIG_RCU_COMPAT_ARCH))
-extern int __rcu_cas_avail;
-extern int __rcu_cas_init(void);
-
-#define UATOMIC_COMPAT(insn) \
- ((likely(__rcu_cas_avail > 0)) \
- ? (_uatomic_##insn) \
- : ((unlikely(__rcu_cas_avail < 0) \
- ? ((__rcu_cas_init() > 0) \
- ? (_uatomic_##insn) \
- : (compat_uatomic_##insn)) \
- : (compat_uatomic_##insn))))
-
-extern unsigned long _compat_uatomic_set(void *addr,
- unsigned long _new, int len);
-#define compat_uatomic_set(addr, _new) \
- ((__typeof__(*(addr))) _compat_uatomic_set((addr), \
- (unsigned long)(_new), \
- sizeof(*(addr))))
-
-
-extern unsigned long _compat_uatomic_xchg(void *addr,
- unsigned long _new, int len);
-#define compat_uatomic_xchg(addr, _new) \
- ((__typeof__(*(addr))) _compat_uatomic_xchg((addr), \
- (unsigned long)(_new), \
- sizeof(*(addr))))
-
-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))) _compat_uatomic_cmpxchg((addr), \
- (unsigned long)(old), \
- (unsigned long)(_new), \
- sizeof(*(addr))))
-
-extern unsigned long _compat_uatomic_xchg(void *addr,
- unsigned long _new, int len);
-#define compat_uatomic_add_return(addr, v) \
- ((__typeof__(*(addr))) _compat_uatomic_add_return((addr), \
- (unsigned long)(v), \
- sizeof(*(addr))))
-
-#define compat_uatomic_add(addr, v) \
- ((void)compat_uatomic_add_return((addr), (v)))
-#define compat_uatomic_inc(addr) \
- (compat_uatomic_add((addr), 1))
-#define compat_uatomic_dec(addr) \
- (compat_uatomic_add((addr), -1))
-
-#else
-#define UATOMIC_COMPAT(insn) (_uatomic_##insn)
-#endif
-
-#define uatomic_set(addr, v) \
- UATOMIC_COMPAT(set(addr, v))
-#define uatomic_cmpxchg(addr, old, _new) \
- UATOMIC_COMPAT(cmpxchg(addr, old, _new))
-#define uatomic_xchg(addr, v) \
- UATOMIC_COMPAT(xchg(addr, v))
-#define uatomic_add_return(addr, v) \
- UATOMIC_COMPAT(add_return(addr, v))
-#define uatomic_add(addr, v) UATOMIC_COMPAT(add(addr, v))
-#define uatomic_inc(addr) UATOMIC_COMPAT(inc(addr))
-#define uatomic_dec(addr) UATOMIC_COMPAT(dec(addr))
-
-#ifdef __cplusplus
-}
-#endif
-
#include <urcu/uatomic_defaults.h>
#endif /* _URCU_ARCH_UATOMIC_X86_H */
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 03/12] add urcu/arch_defaults.h
2010-02-15 19:04 ` [ltt-dev] [PATCH 03/12] add urcu/arch_defaults.h Paolo Bonzini
@ 2010-02-18 2:57 ` Mathieu Desnoyers
0 siblings, 0 replies; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 2:57 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> Most of the memory barrier definitions are shared between all
> architectures, especially smp_* and mc/rmc/wmc. Put them in
> a common file.
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> ---
> urcu/arch_defaults.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++
Can we re-brand "defaults" into "generic" ? It would bring me the warm
feeling of knowing where I stand, coming from a Linux kernel background.
;)
And unless I'm wrong, it seems to be more a "generic" support than a
"default implementation", although the difference is small.
Thanks,
Mathieu
> urcu/arch_ppc.h | 50 +------------------
> urcu/arch_s390.h | 38 +--------------
> urcu/arch_sparc64.h | 51 +------------------
> urcu/arch_x86.h | 64 ++----------------------
> 5 files changed, 145 insertions(+), 190 deletions(-)
> create mode 100644 urcu/arch_defaults.h
>
> diff --git a/urcu/arch_defaults.h b/urcu/arch_defaults.h
> new file mode 100644
> index 0000000..21cc3c1
> --- /dev/null
> +++ b/urcu/arch_defaults.h
> @@ -0,0 +1,132 @@
> +#ifndef _URCU_ARCH_DEFAULTS_H
> +#define _URCU_ARCH_DEFAULTS_H
> +
> +/*
> + * arch_defaults.h: common definitions for multiple architectures.
> + *
> + * Copyright (c) 2010 Paolo Bonzini <pbonzini at redhat.com>
> + *
> + * 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; either
> + * version 2.1 of the License, or (at your option) any later version.
> +*
> + * 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 <urcu/compiler.h>
> +#include <urcu/config.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef CACHE_LINE_SIZE
> +#define CACHE_LINE_SIZE 64
> +#endif
> +
> +#if !defined(mc) && !defined(rmc) && !defined(wmc)
> +#define CONFIG_HAVE_MEM_COHERENCY
> +/*
> + * Architectures with cache coherency must _not_ define mc/rmc/wmc.
> + *
> + * For them, mc/rmc/wmc are implemented with a * simple compiler barrier;
> + * in addition, we provide defaults for mb (using GCC builtins) as well as
> + * rmb and wmb (defaulting to mb).
> + */
> +
> +#ifndef mb
> +#define mb() __sync_synchronize()
> +#endif
> +
> +#ifndef rmb
> +#define rmb() mb()
> +#endif
> +
> +#ifndef wmb
> +#define wmb() mb()
> +#endif
> +
> +#define mc() barrier()
> +#define rmc() barrier()
> +#define wmc() barrier()
> +#else
> +/*
> + * Architectures without cache coherency need something like the following:
> + *
> + * #define mc() arch_cache_flush()
> + * #define rmc() arch_cache_flush_read()
> + * #define wmc() arch_cache_flush_write()
> + *
> + * Of these, only mc is mandatory. rmc and wmc default to mc. mb/rmb/wmb
> + * use these definitions by default:
> + *
> + * #define mb() mc()
> + * #define rmb() rmc()
> + * #define wmb() wmc()
> + */
> +
> +#ifndef mb
> +#define mb() mc()
> +#endif
> +
> +#ifndef rmb
> +#define rmb() rmc()
> +#endif
> +
> +#ifndef wmb
> +#define wmb() wmc()
> +#endif
> +
> +#ifndef rmc
> +#define rmc() mc()
> +#endif
> +
> +#ifndef wmc
> +#define wmc() mc()
> +#endif
> +#endif
> +
> +/* Nop everywhere except on alpha. */
> +#ifndef read_barrier_depends
> +#define read_barrier_depends()
> +#endif
> +
> +#ifdef CONFIG_RCU_SMP
> +#define smp_mb() mb()
> +#define smp_rmb() rmb()
> +#define smp_wmb() wmb()
> +#define smp_mc() mc()
> +#define smp_rmc() rmc()
> +#define smp_wmc() wmc()
> +#define smp_read_barrier_depends() read_barrier_depends()
> +#else
> +#define smp_mb() barrier()
> +#define smp_rmb() barrier()
> +#define smp_wmb() barrier()
> +#define smp_mc() barrier()
> +#define smp_rmc() barrier()
> +#define smp_wmc() barrier()
> +#define smp_read_barrier_depends()
> +#endif
> +
> +#ifndef cpu_relax
> +#define cpu_relax() barrier()
> +#endif
> +
> +#ifndef sync_core
> +#define sync_core() mb()
> +#endif
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _URCU_ARCH_DEFAULTS_H */
> diff --git a/urcu/arch_ppc.h b/urcu/arch_ppc.h
> index c1762ae..f925d07 100644
> --- a/urcu/arch_ppc.h
> +++ b/urcu/arch_ppc.h
> @@ -29,8 +29,6 @@
> extern "C" {
> #endif
>
> -#define CONFIG_HAVE_MEM_COHERENCY
> -
> /* Include size of POWER5+ L3 cache lines: 256 bytes */
> #define CACHE_LINE_SIZE 256
>
> @@ -39,55 +37,11 @@ extern "C" {
> #endif
>
> #define mb() asm volatile("sync":::"memory")
> -#define rmb() asm volatile("sync":::"memory")
> -#define wmb() asm volatile("sync"::: "memory")
> -
> -/*
> - * Architectures without cache coherency need something like the following:
> - *
> - * #define mb() mc()
> - * #define rmb() rmc()
> - * #define wmb() wmc()
> - * #define mc() arch_cache_flush()
> - * #define rmc() arch_cache_flush_read()
> - * #define wmc() arch_cache_flush_write()
> - */
> -
> -#define mc() barrier()
> -#define rmc() barrier()
> -#define wmc() barrier()
> -
> -#ifdef CONFIG_RCU_SMP
> -#define smp_mb() mb()
> -#define smp_rmb() rmb()
> -#define smp_wmb() wmb()
> -#define smp_mc() mc()
> -#define smp_rmc() rmc()
> -#define smp_wmc() wmc()
> -#else
> -#define smp_mb() barrier()
> -#define smp_rmb() barrier()
> -#define smp_wmb() barrier()
> -#define smp_mc() barrier()
> -#define smp_rmc() barrier()
> -#define smp_wmc() barrier()
> -#endif
> -
> -/* Nop everywhere except on alpha. */
> -#define smp_read_barrier_depends()
> -
> -static inline void cpu_relax(void)
> -{
> - barrier();
> -}
>
> /*
> * Serialize core instruction execution. Also acts as a compiler barrier.
> */
> -static inline void sync_core()
> -{
> - asm volatile("isync" : : : "memory");
> -}
> +#define sync_core() asm volatile("isync" : : : "memory")
>
> #define mftbl() \
> ({ \
> @@ -123,4 +77,6 @@ static inline cycles_t get_cycles (void)
> }
> #endif
>
> +#include <urcu/arch_defaults.h>
> +
> #endif /* _URCU_ARCH_PPC_H */
> diff --git a/urcu/arch_s390.h b/urcu/arch_s390.h
> index 22a1853..0982112 100644
> --- a/urcu/arch_s390.h
> +++ b/urcu/arch_s390.h
> @@ -35,8 +35,6 @@
> extern "C" {
> #endif
>
> -#define CONFIG_HAVE_MEM_COHERENCY
> -
> #define CACHE_LINE_SIZE 128
>
> #ifndef __SIZEOF_LONG__
> @@ -52,40 +50,6 @@ extern "C" {
> #endif
>
> #define mb() __asm__ __volatile__("bcr 15,0" : : : "memory")
> -#define rmb() __asm__ __volatile__("bcr 15,0" : : : "memory")
> -#define wmb() __asm__ __volatile__("bcr 15,0" : : : "memory")
> -#define mc() barrier()
> -#define rmc() barrier()
> -#define wmc() barrier()
> -
> -#ifdef CONFIG_RCU_SMP
> -#define smp_mb() mb()
> -#define smp_rmb() rmb()
> -#define smp_wmb() wmb()
> -#define smp_mc() mc()
> -#define smp_rmc() rmc()
> -#define smp_wmc() wmc()
> -#else
> -#define smp_mb() barrier()
> -#define smp_rmb() barrier()
> -#define smp_wmb() barrier()
> -#define smp_mc() barrier()
> -#define smp_rmc() barrier()
> -#define smp_wmc() barrier()
> -#endif
> -
> -/* Nop everywhere except on alpha. */
> -#define smp_read_barrier_depends()
> -
> -static inline void cpu_relax(void)
> -{
> - barrier();
> -}
> -
> -static inline void sync_core()
> -{
> - __asm__ __volatile__("bcr 15,0" : : : "memory");
> -}
>
> typedef unsigned long long cycles_t;
>
> @@ -102,4 +66,6 @@ static inline cycles_t get_cycles (void)
> }
> #endif
>
> +#include <urcu/arch_defaults.h>
> +
> #endif /* _URCU_ARCH_S390_H */
> diff --git a/urcu/arch_sparc64.h b/urcu/arch_sparc64.h
> index 54c4c3c..c906168 100644
> --- a/urcu/arch_sparc64.h
> +++ b/urcu/arch_sparc64.h
> @@ -29,8 +29,6 @@
> extern "C" {
> #endif
>
> -#define CONFIG_HAVE_MEM_COHERENCY
> -
> #define CACHE_LINE_SIZE 256
>
> #ifndef BITS_PER_LONG
> @@ -50,53 +48,6 @@ __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
> #define rmb() membar_safe("#LoadLoad")
> #define wmb() membar_safe("#StoreStore")
>
> -/*
> - * Architectures without cache coherency need something like the following:
> - *
> - * #define mb() mc()
> - * #define rmb() rmc()
> - * #define wmb() wmc()
> - * #define mc() arch_cache_flush()
> - * #define rmc() arch_cache_flush_read()
> - * #define wmc() arch_cache_flush_write()
> - */
> -
> -#define mc() barrier()
> -#define rmc() barrier()
> -#define wmc() barrier()
> -
> -#ifdef CONFIG_RCU_SMP
> -#define smp_mb() mb()
> -#define smp_rmb() rmb()
> -#define smp_wmb() wmb()
> -#define smp_mc() mc()
> -#define smp_rmc() rmc()
> -#define smp_wmc() wmc()
> -#else
> -#define smp_mb() barrier()
> -#define smp_rmb() barrier()
> -#define smp_wmb() barrier()
> -#define smp_mc() barrier()
> -#define smp_rmc() barrier()
> -#define smp_wmc() barrier()
> -#endif
> -
> -/* Nop everywhere except on alpha. */
> -#define smp_read_barrier_depends()
> -
> -static inline void cpu_relax(void)
> -{
> - barrier();
> -}
> -
> -/*
> - * Serialize core instruction execution. Also acts as a compiler barrier.
> - */
> -static inline void sync_core()
> -{
> - mb();
> -}
> -
> typedef unsigned long long cycles_t;
>
> static inline cycles_t get_cycles (void)
> @@ -108,4 +59,6 @@ static inline cycles_t get_cycles (void)
> }
> #endif
>
> +#include <urcu/arch_defaults.h>
> +
> #endif /* _URCU_ARCH_SPARC64_H */
> diff --git a/urcu/arch_x86.h b/urcu/arch_x86.h
> index 4abac2b..bc03379 100644
> --- a/urcu/arch_x86.h
> +++ b/urcu/arch_x86.h
> @@ -29,8 +29,6 @@
> extern "C" {
> #endif
>
> -#define CONFIG_HAVE_MEM_COHERENCY
> -
> #define CACHE_LINE_SIZE 128
>
> #ifdef CONFIG_RCU_HAVE_FENCE
> @@ -47,68 +45,16 @@ extern "C" {
> #define wmb() asm volatile("lock; addl $0,0(%%esp)"::: "memory")
> #endif
>
> -/*
> - * Architectures without cache coherency need something like the following:
> - *
> - * #define mb() mc()
> - * #define rmb() rmc()
> - * #define wmb() wmc()
> - * #define mc() arch_cache_flush()
> - * #define rmc() arch_cache_flush_read()
> - * #define wmc() arch_cache_flush_write()
> - */
> -
> -#define mc() barrier()
> -#define rmc() barrier()
> -#define wmc() barrier()
> -
> -#ifdef CONFIG_RCU_SMP
> -#define smp_mb() mb()
> -#define smp_rmb() rmb()
> -#define smp_wmb() wmb()
> -#define smp_mc() mc()
> -#define smp_rmc() rmc()
> -#define smp_wmc() wmc()
> -#else
> -#define smp_mb() barrier()
> -#define smp_rmb() barrier()
> -#define smp_wmb() barrier()
> -#define smp_mc() barrier()
> -#define smp_rmc() barrier()
> -#define smp_wmc() barrier()
> -#endif
> -
> -/* Nop everywhere except on alpha. */
> -#define smp_read_barrier_depends()
> -
> -static inline void rep_nop(void)
> -{
> - asm volatile("rep; nop" : : : "memory");
> -}
> -
> -static inline void cpu_relax(void)
> -{
> - rep_nop();
> -}
> +#define cpu_relax() asm volatile("rep; nop" : : : "memory");
>
> /*
> * Serialize core instruction execution. Also acts as a compiler barrier.
> - */
> -#ifdef __PIC__
> -/*
> - * Cannot use cpuid because it clobbers the ebx register and clashes
> - * with -fPIC :
> + * Cannot use cpuid on PIC because it clobbers the ebx register;
> * error: PIC register 'ebx' clobbered in 'asm'
> */
> -static inline void sync_core(void)
> -{
> - mb();
> -}
> -#else
> -static inline void sync_core(void)
> -{
> +#ifndef __PIC__
> +#define sync_core() \
> asm volatile("cpuid" : : : "memory", "eax", "ebx", "ecx", "edx");
> -}
> #endif
>
> #define rdtscll(val) \
> @@ -133,4 +79,6 @@ static inline cycles_t get_cycles(void)
> }
> #endif
>
> +#include <urcu/arch_defaults.h>
> +
> #endif /* _URCU_ARCH_X86_H */
> --
> 1.6.6
>
>
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 06/12] add uatomic_defaults.h, use it for default definitions
2010-02-15 19:04 ` [ltt-dev] [PATCH 06/12] add uatomic_defaults.h, use it for default definitions Paolo Bonzini
@ 2010-02-18 3:10 ` Mathieu Desnoyers
0 siblings, 0 replies; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 3:10 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> uatomic_defaults.h can be included by uatomic_arch_*.h to provide useful
Maybe rebrand defaults -> generic here too ?
More comments inline.
> default definitions. uatomic_arch_*.h can define whatever builtins
> it wants to override, then uatomic_defaults.h will provide what is not
> already defined, as follows:
>
> - uatomic_cmpxchg will use __sync_val_compare_and_swap builtins;
>
> - uatomic_add_return will use __sync_fetch_and_add if uatomic_arch_*.h
> did not provide a definition of uatomic_cmpxchg. If it did, we assume
> __sync builtins are buggy or otherwise undesirable on this platform,
> so uatomic_defaults.h will implement uatomic_add_return in terms of
> uatomic_cmpxchg too.
>
> - uatomic_xchg is like uatomic_add_return. However, since GCC does
> not provide an adequate builtin, it needs to use a compare-and-swap
> loop using __sync_bool_compare_and_swap if uatomic_cmpxchg is not
> provided.
>
> - uatomic_sub_return/uatomic_add/uatomic_sub will be implemented
> in terms of uatomic_add_return;
>
> - uatomic_inc/uatomic_dec will be implemented in terms of uatomic_add.
>
> After this patch, uatomic_defaults.h is already used for the latter two
> categories.
>
> The hunk in tests/test_uatomic.c is only needed for bisectability
> and will be removed later.
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> ---
> Makefile.am | 2 +-
> tests/test_uatomic.c | 2 +
> urcu/uatomic_arch_ppc.h | 15 +--
> urcu/uatomic_arch_s390.h | 15 +--
> urcu/uatomic_arch_sparc64.h | 15 +--
> urcu/uatomic_arch_x86.h | 26 ++---
> urcu/uatomic_defaults.h | 262 +++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 280 insertions(+), 57 deletions(-)
> create mode 100644 urcu/uatomic_defaults.h
>
> diff --git a/Makefile.am b/Makefile.am
> index 2ede9e0..c91dfe9 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -6,7 +6,7 @@ SUBDIRS = . tests
>
> 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 urcu/urcu-futex.h
> + urcu/rculist.h urcu/system.h urcu/urcu-futex.h urcu/uatomic_defaults.h
> nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic_arch.h urcu/config.h
>
> EXTRA_DIST = $(top_srcdir)/urcu/arch_*.h $(top_srcdir)/urcu/uatomic_arch_*.h \
> diff --git a/tests/test_uatomic.c b/tests/test_uatomic.c
> index 68cb6df..c0f36fe 100644
> --- a/tests/test_uatomic.c
> +++ b/tests/test_uatomic.c
> @@ -1,5 +1,7 @@
> #include <stdio.h>
> #include <assert.h>
> +
> +#define UATOMIC_NO_LINK_ERROR
> #include <urcu/uatomic_arch.h>
>
> #if (defined(__i386__) || defined(__x86_64__))
> diff --git a/urcu/uatomic_arch_ppc.h b/urcu/uatomic_arch_ppc.h
> index 8da192e..b42bfdb 100644
> --- a/urcu/uatomic_arch_ppc.h
> +++ b/urcu/uatomic_arch_ppc.h
> @@ -47,9 +47,6 @@ extern "C" {
>
> #define ILLEGAL_INSTR ".long 0xd00d00"
>
> -#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
> -#define uatomic_read(addr) LOAD_SHARED(*(addr))
> -
> /*
> * Using a isync as second barrier for exchange to provide acquire semantic.
> * According to uatomic_ops/sysdeps/gcc/powerpc.h, the documentation is "fairly
> @@ -225,18 +222,10 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val,
> (unsigned long)(v), \
> sizeof(*(addr))))
>
> -/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
> -
> -#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
> -
> -#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
> -#define uatomic_sub(addr, v) (void)uatomic_sub_return((addr), (v))
> -
> -#define uatomic_inc(addr) uatomic_add((addr), 1)
> -#define uatomic_dec(addr) uatomic_add((addr), -1)
> -
> #ifdef __cplusplus
> }
> #endif
>
> +#include <urcu/uatomic_defaults.h>
> +
> #endif /* _URCU_ARCH_UATOMIC_PPC_H */
> diff --git a/urcu/uatomic_arch_s390.h b/urcu/uatomic_arch_s390.h
> index 614867f..8f1523c 100644
> --- a/urcu/uatomic_arch_s390.h
> +++ b/urcu/uatomic_arch_s390.h
> @@ -78,9 +78,6 @@ struct __uatomic_dummy {
> };
> #define __hp(x) ((struct __uatomic_dummy *)(x))
>
> -#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
> -#define uatomic_read(addr) LOAD_SHARED(*(addr))
> -
> /* xchg */
>
> static inline __attribute__((always_inline))
> @@ -208,18 +205,10 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
> (unsigned long)(v), \
> sizeof(*(addr))))
>
> -/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
> -
> -#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
> -
> -#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
> -#define uatomic_sub(addr, v) (void)uatomic_sub_return((addr), (v))
> -
> -#define uatomic_inc(addr) uatomic_add((addr), 1)
> -#define uatomic_dec(addr) uatomic_add((addr), -1)
> -
> #ifdef __cplusplus
> }
> #endif
>
> +#include <urcu/uatomic_defaults.h>
> +
> #endif /* _URCU_UATOMIC_ARCH_S390_H */
> diff --git a/urcu/uatomic_arch_sparc64.h b/urcu/uatomic_arch_sparc64.h
> index d443d4f..0c16eaf 100644
> --- a/urcu/uatomic_arch_sparc64.h
> +++ b/urcu/uatomic_arch_sparc64.h
> @@ -39,9 +39,6 @@ extern "C" {
> #define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> #endif
>
> -#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
> -#define uatomic_read(addr) LOAD_SHARED(*(addr))
> -
> /* cmpxchg */
>
> static inline __attribute__((always_inline))
> @@ -169,18 +166,10 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
> (unsigned long)(v), \
> sizeof(*(addr))))
>
> -/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
> -
> -#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
> -
> -#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
> -#define uatomic_sub(addr, v) (void)uatomic_sub_return((addr), (v))
> -
> -#define uatomic_inc(addr) uatomic_add((addr), 1)
> -#define uatomic_dec(addr) uatomic_add((addr), -1)
> -
> #ifdef __cplusplus
> }
> #endif
>
> +#include <urcu/uatomic_defaults.h>
> +
> #endif /* _URCU_ARCH_UATOMIC_PPC_H */
> diff --git a/urcu/uatomic_arch_x86.h b/urcu/uatomic_arch_x86.h
> index 3bfe86d..8a81995 100644
> --- a/urcu/uatomic_arch_x86.h
> +++ b/urcu/uatomic_arch_x86.h
> @@ -49,7 +49,11 @@ struct __uatomic_dummy {
> #define __hp(x) ((struct __uatomic_dummy *)(x))
>
> #define _uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
> +
> +#if 0
> +/* Read is atomic even in compat mode */
> #define _uatomic_read(addr) LOAD_SHARED(*(addr))
> +#endif
Maybe we should fix this by removing it entirely, just leaving the
comment below in the "compat_" block ?
>
> /* cmpxchg */
>
> @@ -176,7 +180,7 @@ unsigned long __uatomic_exchange(void *addr, unsigned long val, int len)
> ((__typeof__(*(addr))) __uatomic_exchange((addr), (unsigned long)(v), \
> sizeof(*(addr))))
>
> -/* uatomic_add_return, uatomic_sub_return */
> +/* uatomic_add_return */
>
> static inline __attribute__((always_inline))
> unsigned long __uatomic_add_return(void *addr, unsigned long val,
> @@ -241,9 +245,7 @@ unsigned long __uatomic_add_return(void *addr, unsigned long val,
> (unsigned long)(v), \
> sizeof(*(addr))))
>
> -#define _uatomic_sub_return(addr, v) _uatomic_add_return((addr), -(v))
> -
> -/* uatomic_add, uatomic_sub */
> +/* uatomic_add */
>
> static inline __attribute__((always_inline))
> void __uatomic_add(void *addr, unsigned long val, int len)
> @@ -297,8 +299,6 @@ void __uatomic_add(void *addr, unsigned long val, int len)
> #define _uatomic_add(addr, v) \
> (__uatomic_add((addr), (unsigned long)(v), sizeof(*(addr))))
>
> -#define _uatomic_sub(addr, v) _uatomic_add((addr), -(v))
> -
>
> /* uatomic_inc */
>
> @@ -449,24 +449,17 @@ extern unsigned long _compat_uatomic_xchg(void *addr,
> (unsigned long)(v), \
> sizeof(*(addr))))
>
> -#define compat_uatomic_sub_return(addr, v) \
> - compat_uatomic_add_return((addr), -(v))
> #define compat_uatomic_add(addr, v) \
> ((void)compat_uatomic_add_return((addr), (v)))
> -#define compat_uatomic_sub(addr, v) \
> - ((void)compat_uatomic_sub_return((addr), (v)))
> #define compat_uatomic_inc(addr) \
> (compat_uatomic_add((addr), 1))
> #define compat_uatomic_dec(addr) \
> - (compat_uatomic_sub((addr), 1))
> + (compat_uatomic_add((addr), -1))
>
> #else
> #define UATOMIC_COMPAT(insn) (_uatomic_##insn)
> #endif
>
> -/* Read is atomic even in compat mode */
We could say:
/* Read is atomic even in compat mode. Use generic version. */
> -#define uatomic_read(addr) _uatomic_read(addr)
> -
> #define uatomic_set(addr, v) \
> UATOMIC_COMPAT(set(addr, v))
> #define uatomic_cmpxchg(addr, old, _new) \
> @@ -475,10 +468,7 @@ extern unsigned long _compat_uatomic_xchg(void *addr,
> UATOMIC_COMPAT(xchg(addr, v))
> #define uatomic_add_return(addr, v) \
> UATOMIC_COMPAT(add_return(addr, v))
> -#define uatomic_sub_return(addr, v) \
> - UATOMIC_COMPAT(sub_return(addr, v))
> #define uatomic_add(addr, v) UATOMIC_COMPAT(add(addr, v))
> -#define uatomic_sub(addr, v) UATOMIC_COMPAT(sub(addr, v))
> #define uatomic_inc(addr) UATOMIC_COMPAT(inc(addr))
> #define uatomic_dec(addr) UATOMIC_COMPAT(dec(addr))
>
> @@ -486,4 +476,6 @@ extern unsigned long _compat_uatomic_xchg(void *addr,
> }
> #endif
>
> +#include <urcu/uatomic_defaults.h>
> +
> #endif /* _URCU_ARCH_UATOMIC_X86_H */
> diff --git a/urcu/uatomic_defaults.h b/urcu/uatomic_defaults.h
> new file mode 100644
> index 0000000..93467dd
> --- /dev/null
> +++ b/urcu/uatomic_defaults.h
> @@ -0,0 +1,262 @@
> +#ifndef _URCU_UATOMIC_GCC_H
> +#define _URCU_UATOMIC_GCC_H
> +
> +/*
> + * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
> + * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
> + * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P.
> + * Copyright (c) 2009 Mathieu Desnoyers
> + * Copyright (c) 2010 Paolo Bonzini
> + *
> + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
> + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
> + *
> + * Permission is hereby granted to use or copy this program
> + * for any purpose, provided the above notices are retained on all copies.
> + * Permission to modify the code and to distribute modified code is granted,
> + * provided the above notices are retained, and a notice that the code was
> + * modified is included with the above copyright notice.
> + *
> + * Code inspired from libuatomic_ops-1.2, inherited in part from the
> + * Boehm-Demers-Weiser conservative garbage collector.
> + */
> +
> +#include <urcu/compiler.h>
> +#include <urcu/system.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef BITS_PER_LONG
> +#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> +#endif
> +
> +#ifndef uatomic_set
> +#define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
> +#endif
> +
> +#ifndef uatomic_read
> +#define uatomic_read(addr) LOAD_SHARED(*(addr))
> +#endif
> +
> +#if !defined __OPTIMIZE__ || defined UATOMIC_NO_LINK_ERROR
> +static inline __attribute__((always_inline))
> +void _uatomic_link_error()
> +{
> +#ifdef ILLEGAL_INSTR
> + /* generate an illegal instruction. Cannot catch this with linker tricks
> + * when optimizations are disabled. */
> + __asm__ __volatile__(ILLEGAL_INSTR);
> +#else
> + __builtin_trap ();
coding style:
__builtin_trap();
> +#endif
> +}
> +#else
> +extern void _uatomic_link_error ();
> +#endif
Please add comments after these nested #else and #endif to make it
easier to match the nesting.
e.g.
#ifdef A
#ifdef B
#else /* #ifdef B */
#endif /* #else #ifdef B */
#endif /* #ifdef A */
> +
> +/* cmpxchg */
> +
> +#ifndef uatomic_cmpxchg
> +static inline __attribute__((always_inline))
> +unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
> + unsigned long _new, int len)
> +{
> + switch (len) {
> + case 4:
> + return __sync_val_compare_and_swap_4(addr, old, _new);
> +#if (BITS_PER_LONG == 64)
> + case 8:
> + return __sync_val_compare_and_swap_8(addr, old, _new);
> +#endif
> + }
> + _uatomic_link_error();
> + return 0;
> +}
> +
> +
> +#define uatomic_cmpxchg(addr, old, _new) \
> + ((__typeof__(*(addr))) _uatomic_cmpxchg((addr), (unsigned long)(old),\
> + (unsigned long)(_new), \
> + sizeof(*(addr))))
> +
> +
> +/* uatomic_add_return */
> +
> +#ifndef uatomic_add_return
> +static inline __attribute__((always_inline))
> +unsigned long _uatomic_add_return(void *addr, unsigned long val,
> + int len)
> +{
> + switch (len) {
> + case 4:
> + return __sync_add_and_fetch_4(addr, val);
> +#if (BITS_PER_LONG == 64)
> + case 8:
> + return __sync_add_and_fetch_8(addr, val);
> +#endif
> + }
> + _uatomic_link_error();
> + return 0;
> +}
> +
> +
> +#define uatomic_add_return(addr, v) \
> + ((__typeof__(*(addr))) _uatomic_add_return((addr), \
> + (unsigned long)(v), \
> + sizeof(*(addr))))
> +#endif
> +
> +#ifndef uatomic_xchg
> +/* xchg */
> +
> +static inline __attribute__((always_inline))
> +unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
> +{
> + switch (len) {
> + case 4:
> + {
> + unsigned int old;
> +
> + do
> + old = uatomic_read((unsigned int *)addr);
> + while (!__sync_bool_compare_and_swap_4(addr, old, val));
I really prefer
do {
one liner;
} while (cond);
for some reason. (less error prone)
> +
> + return old;
> + }
> +#if (BITS_PER_LONG == 64)
> + case 8:
> + {
> + unsigned long old;
> +
> + do
> + old = uatomic_read((unsigned long *)addr);
> + while (!__sync_bool_compare_and_swap_8(addr, old, val));
> +
Same here.
> + return old;
> + }
> +#endif
> + }
> + _uatomic_link_error();
> + return 0;
> +}
> +
> +#define uatomic_xchg(addr, v) \
> + ((__typeof__(*(addr))) _uatomic_exchange((addr), (unsigned long)(v), \
> + sizeof(*(addr))))
> +#endif
> +
> +#else
#else ...
Thanks,
Mathieu
> +
> +#ifndef uatomic_add_return
> +/* uatomic_add_return */
> +
> +static inline __attribute__((always_inline))
> +unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
> +{
> + switch (len) {
> + case 4:
> + {
> + unsigned int old, oldt;
> +
> + oldt = uatomic_read((unsigned int *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, old + val, 4);
> + } while (oldt != old);
> +
> + return old + val;
> + }
> +#if (BITS_PER_LONG == 64)
> + case 8:
> + {
> + unsigned long old, oldt;
> +
> + oldt = uatomic_read((unsigned long *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, old + val, 8);
> + } while (oldt != old);
> +
> + return old + val;
> + }
> +#endif
> + }
> + _uatomic_link_error();
> + return 0;
> +}
> +
> +#define uatomic_add_return(addr, v) \
> + ((__typeof__(*(addr))) _uatomic_add_return((addr), \
> + (unsigned long)(v), \
> + sizeof(*(addr))))
> +#endif
> +
> +#ifndef uatomic_xchg
> +/* xchg */
> +
> +static inline __attribute__((always_inline))
> +unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
> +{
> + switch (len) {
> + case 4:
> + {
> + unsigned int old, oldt;
> +
> + oldt = uatomic_read((unsigned int *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, val, 4);
> + } while (oldt != old);
> +
> + return old;
> + }
> +#if (BITS_PER_LONG == 64)
> + case 8:
> + {
> + unsigned long old, oldt;
> +
> + oldt = uatomic_read((unsigned long *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, val, 8);
> + } while (oldt != old);
> +
> + return old;
> + }
> +#endif
> + }
> + _uatomic_link_error();
> + return 0;
> +}
> +
> +#define uatomic_xchg(addr, v) \
> + ((__typeof__(*(addr))) _uatomic_exchange((addr), (unsigned long)(v), \
> + sizeof(*(addr))))
> +#endif
> +
> +#endif
> +
> +/* uatomic_sub_return, uatomic_add, uatomic_sub, uatomic_inc, uatomic_dec */
> +
> +#ifndef uatomic_add
> +#define uatomic_add(addr, v) (void)uatomic_add_return((addr), (v))
> +#endif
> +
> +#define uatomic_sub_return(addr, v) uatomic_add_return((addr), -(v))
> +#define uatomic_sub(addr, v) uatomic_add((addr), -(v))
> +
> +#ifndef uatomic_inc
> +#define uatomic_inc(addr) uatomic_add((addr), 1)
> +#endif
> +
> +#ifndef uatomic_dec
> +#define uatomic_dec(addr) uatomic_add((addr), -1)
> +#endif
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _URCU_UATOMIC_GCC_H */
> --
> 1.6.6
>
>
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 08/12] move whether atomic byte/short exists to uatomic_arch_*.h
2010-02-15 19:04 ` [ltt-dev] [PATCH 08/12] move whether atomic byte/short exists to uatomic_arch_*.h Paolo Bonzini
@ 2010-02-18 3:12 ` Mathieu Desnoyers
0 siblings, 0 replies; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 3:12 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> And add more generic implementations to uatomic_defaults.h.
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> ---
> tests/test_uatomic.c | 15 +------
> urcu/uatomic_arch_x86.h | 3 +
> urcu/uatomic_defaults.h | 96 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 101 insertions(+), 13 deletions(-)
>
> diff --git a/tests/test_uatomic.c b/tests/test_uatomic.c
> index c0f36fe..5682655 100644
> --- a/tests/test_uatomic.c
> +++ b/tests/test_uatomic.c
> @@ -1,21 +1,10 @@
> #include <stdio.h>
> #include <assert.h>
> -
> -#define UATOMIC_NO_LINK_ERROR
> #include <urcu/uatomic_arch.h>
>
> -#if (defined(__i386__) || defined(__x86_64__))
> -#define HAS_ATOMIC_BYTE
> -#define HAS_ATOMIC_SHORT
> -#endif
> -
> struct testvals {
> -#ifdef HAS_ATOMIC_BYTE
> unsigned char c;
> -#endif
> -#ifdef HAS_ATOMIC_SHORT
> unsigned short s;
> -#endif
> unsigned int i;
> unsigned long l;
> };
> @@ -54,10 +43,10 @@ do { \
>
> int main(int argc, char **argv)
> {
> -#ifdef HAS_ATOMIC_BYTE
> +#ifdef UATOMIC_HAS_ATOMIC_BYTE
> do_test(&vals.c);
> #endif
> -#ifdef HAS_ATOMIC_SHORT
> +#ifdef UATOMIC_HAS_ATOMIC_SHORT
> do_test(&vals.s);
> #endif
> do_test(&vals.i);
> diff --git a/urcu/uatomic_arch_x86.h b/urcu/uatomic_arch_x86.h
> index 8a81995..f2d0c19 100644
> --- a/urcu/uatomic_arch_x86.h
> +++ b/urcu/uatomic_arch_x86.h
> @@ -23,6 +23,9 @@
> #include <urcu/compiler.h>
> #include <urcu/system.h>
>
> +#define UATOMIC_HAS_ATOMIC_BYTE
> +#define UATOMIC_HAS_ATOMIC_SHORT
> +
> #ifdef __cplusplus
> extern "C" {
> #endif
> diff --git a/urcu/uatomic_defaults.h b/urcu/uatomic_defaults.h
> index 93467dd..2d0af6e 100644
> --- a/urcu/uatomic_defaults.h
> +++ b/urcu/uatomic_defaults.h
> @@ -64,6 +64,14 @@ unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
> unsigned long _new, int len)
> {
> switch (len) {
> +#ifdef UATOMIC_HAS_ATOMIC_BYTE
> + case 1:
> + return __sync_val_compare_and_swap_1(addr, old, _new);
> +#endif
> +#ifdef UATOMIC_HAS_ATOMIC_SHORT
> + case 2:
> + return __sync_val_compare_and_swap_2(addr, old, _new);
> +#endif
> case 4:
> return __sync_val_compare_and_swap_4(addr, old, _new);
> #if (BITS_PER_LONG == 64)
> @@ -90,6 +98,14 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val,
> int len)
> {
> switch (len) {
> +#ifdef UATOMIC_HAS_ATOMIC_BYTE
> + case 1:
> + return __sync_add_and_fetch_1(addr, val);
> +#endif
> +#ifdef UATOMIC_HAS_ATOMIC_SHORT
> + case 2:
> + return __sync_add_and_fetch_2(addr, val);
> +#endif
> case 4:
> return __sync_add_and_fetch_4(addr, val);
> #if (BITS_PER_LONG == 64)
> @@ -115,6 +131,30 @@ static inline __attribute__((always_inline))
> unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
> {
> switch (len) {
> +#ifdef UATOMIC_HAS_ATOMIC_BYTE
> + case 1:
> + {
> + unsigned char old;
> +
> + do
> + old = uatomic_read((unsigned char *)addr);
> + while (!__sync_bool_compare_and_swap_1(addr, old, val));
Same here for brackets.
> +
> + return old;
> + }
> +#endif
> +#ifdef UATOMIC_HAS_ATOMIC_SHORT
> + case 2:
> + {
> + unsigned short old;
> +
> + do
> + old = uatomic_read((unsigned short *)addr);
> + while (!__sync_bool_compare_and_swap_2(addr, old, val));
And here.
Thanks,
Mathieu
> +
> + return old;
> + }
> +#endif
> case 4:
> {
> unsigned int old;
> @@ -156,6 +196,34 @@ static inline __attribute__((always_inline))
> unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
> {
> switch (len) {
> +#ifdef UATOMIC_HAS_ATOMIC_BYTE
> + case 1:
> + {
> + unsigned char old, oldt;
> +
> + oldt = uatomic_read((unsigned char *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, old + val, 1);
> + } while (oldt != old);
> +
> + return old + val;
> + }
> +#endif
> +#ifdef UATOMIC_HAS_ATOMIC_SHORT
> + case 2:
> + {
> + unsigned short old, oldt;
> +
> + oldt = uatomic_read((unsigned short *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, old + val, 2);
> + } while (oldt != old);
> +
> + return old + val;
> + }
> +#endif
> case 4:
> {
> unsigned int old, oldt;
> @@ -200,6 +268,34 @@ static inline __attribute__((always_inline))
> unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
> {
> switch (len) {
> +#ifdef UATOMIC_HAS_ATOMIC_BYTE
> + case 1:
> + {
> + unsigned char old, oldt;
> +
> + oldt = uatomic_read((unsigned char *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, val, 1);
> + } while (oldt != old);
> +
> + return old;
> + }
> +#endif
> +#ifdef UATOMIC_HAS_ATOMIC_SHORT
> + case 2:
> + {
> + unsigned short old, oldt;
> +
> + oldt = uatomic_read((unsigned short *)addr);
> + do {
> + old = oldt;
> + oldt = _uatomic_cmpxchg(addr, old, val, 2);
> + } while (oldt != old);
> +
> + return old;
> + }
> +#endif
> case 4:
> {
> unsigned int old, oldt;
> --
> 1.6.6
>
>
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 09/12] add Alpha support
2010-02-15 19:04 ` [ltt-dev] [PATCH 09/12] add Alpha support Paolo Bonzini
@ 2010-02-18 3:21 ` Mathieu Desnoyers
0 siblings, 0 replies; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 3:21 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> And you already know what needs to be special-cased for Alpha...
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> ---
> configure.ac | 1 +
> urcu/arch_alpha.h | 48 +++++++++++++++++++++++++++++++++++++++++++++
> urcu/uatomic_arch_alpha.h | 32 ++++++++++++++++++++++++++++++
> 3 files changed, 81 insertions(+), 0 deletions(-)
> create mode 100644 urcu/arch_alpha.h
> create mode 100644 urcu/uatomic_arch_alpha.h
>
> diff --git a/configure.ac b/configure.ac
> index ab6f3a2..1ce19d0 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -50,6 +50,7 @@ case $host_cpu in
> s390) ARCHTYPE="s390" ;;
> s390x) ARCHTYPE="s390" ;;
> sparc64) ARCHTYPE="sparc64" ;;
> + alpha*) ARCHTYPE="alpha" ;;
> *) ARCHTYPE="unknown";;
> esac
>
> diff --git a/urcu/arch_alpha.h b/urcu/arch_alpha.h
> new file mode 100644
> index 0000000..4d521de
> --- /dev/null
> +++ b/urcu/arch_alpha.h
> @@ -0,0 +1,48 @@
> +#ifndef _URCU_ARCH_ALPHA_H
> +#define _URCU_ARCH_ALPHA_H
> +
> +/*
> + * arch_ppc.h: trivial definitions for the Alpha architecture.
arch_alpha.h
> + *
> + * Copyright (c) 2010 Paolo Bonzini <pbonzini at redhat.com>
> + *
> + * 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; either
> + * version 2.1 of the License, or (at your option) any later version.
> +*
Missing space. (hrm, missing space on ppc too)
Thanks,
Mathieu
> + * 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 <urcu/compiler.h>
> +#include <urcu/config.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#define mb() asm volatile("mb":::"memory")
> +#define wmb() asm volatile("wmb":::"memory")
> +#define read_barrier_depends() asm volatile("mb":::"memory")
> +
> +typedef unsigned long long cycles_t;
> +
> +static inline cycles_t get_cycles (void)
> +{
> + return 0; /* not supported */
> +}
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#include <urcu/arch_defaults.h>
> +
> +#endif /* _URCU_ARCH_ALPHA_H */
> diff --git a/urcu/uatomic_arch_alpha.h b/urcu/uatomic_arch_alpha.h
> new file mode 100644
> index 0000000..6d002cb
> --- /dev/null
> +++ b/urcu/uatomic_arch_alpha.h
> @@ -0,0 +1,32 @@
> +#ifndef _URCU_UATOMIC_ARCH_ALPHA_H
> +#define _URCU_UATOMIC_ARCH_ALPHA_H
> +
> +/*
> + * Atomic exchange operations for the Alpha architecture. Let GCC do it.
> + *
> + * Copyright (c) 2010 Paolo Bonzini <pbonzini at redhat.com>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +#include <urcu/compiler.h>
> +#include <urcu/system.h>
> +#include <urcu/uatomic_defaults.h>
> +
> +#endif /* _URCU_UATOMIC_ARCH_ALPHA_H */
> --
> 1.6.6
>
>
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 10/12] support compiling on unknown architectures
2010-02-15 19:04 ` [ltt-dev] [PATCH 10/12] support compiling on unknown architectures Paolo Bonzini
@ 2010-02-18 3:22 ` Mathieu Desnoyers
0 siblings, 0 replies; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 3:22 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> The new defaults mean that, for example, ia64 support comes for free.
Hurray! :)
Mathieu
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> ---
> configure.ac | 10 ++++++----
> 1 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 1ce19d0..871e600 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -54,11 +54,13 @@ case $host_cpu in
> *) ARCHTYPE="unknown";;
> esac
>
> -if test "$ARCHTYPE" = "unknown"; then
> - AC_MSG_ERROR([Unable to detect the architecture.])
> +if test "$ARCHTYPE" != "unknown"; then
> + UATOMICSRC=urcu/uatomic_arch_$ARCHTYPE.h
> + ARCHSRC=urcu/arch_$ARCHTYPE.h
> +else
> + UATOMICSRC=urcu/uatomic_defaults.h
> + ARCHSRC=urcu/arch_defaults.h
> fi
> -UATOMICSRC=urcu/uatomic_arch_$ARCHTYPE.h
> -ARCHSRC=urcu/arch_$ARCHTYPE.h
> if test "x$ARCHTYPE" != xx86 -a "x$ARCHTYPE" != xppc; then
> APISRC=tests/api_gcc.h
> else
> --
> 1.6.6
>
>
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG
2010-02-15 19:04 ` [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG Paolo Bonzini
@ 2010-02-18 3:25 ` Mathieu Desnoyers
2010-02-18 8:45 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 3:25 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> Use __SIZEOF_LONG__, defined by GCC 4.3 or later, or _LP64, defined
> by GCC 3.4 or later. The GCC 3.4 requirement is only for 64-bit
> systems.
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> ---
> urcu/arch_ppc.h | 4 ----
> urcu/arch_s390.h | 12 ------------
> urcu/arch_sparc64.h | 4 ----
> urcu/compiler.h | 8 ++++++++
> urcu/uatomic_arch_ppc.h | 12 ------------
> urcu/uatomic_arch_s390.h | 12 ------------
> urcu/uatomic_arch_sparc64.h | 12 ------------
> urcu/uatomic_arch_x86.h | 12 ------------
> urcu/uatomic_defaults.h | 4 ----
> 9 files changed, 8 insertions(+), 72 deletions(-)
>
> diff --git a/urcu/arch_ppc.h b/urcu/arch_ppc.h
> index f925d07..41e6a7c 100644
> --- a/urcu/arch_ppc.h
> +++ b/urcu/arch_ppc.h
> @@ -32,10 +32,6 @@ extern "C" {
> /* Include size of POWER5+ L3 cache lines: 256 bytes */
> #define CACHE_LINE_SIZE 256
>
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> #define mb() asm volatile("sync":::"memory")
>
> /*
> diff --git a/urcu/arch_s390.h b/urcu/arch_s390.h
> index 0982112..889fc0d 100644
> --- a/urcu/arch_s390.h
> +++ b/urcu/arch_s390.h
> @@ -37,18 +37,6 @@ extern "C" {
>
> #define CACHE_LINE_SIZE 128
>
> -#ifndef __SIZEOF_LONG__
> -#ifdef __s390x__
> -#define __SIZEOF_LONG__ 8
> -#else
> -#define __SIZEOF_LONG__ 4
> -#endif
> -#endif
> -
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> #define mb() __asm__ __volatile__("bcr 15,0" : : : "memory")
>
> typedef unsigned long long cycles_t;
> diff --git a/urcu/arch_sparc64.h b/urcu/arch_sparc64.h
> index c906168..c10afeb 100644
> --- a/urcu/arch_sparc64.h
> +++ b/urcu/arch_sparc64.h
> @@ -31,10 +31,6 @@ extern "C" {
>
> #define CACHE_LINE_SIZE 256
>
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> /*
> * Inspired from the Linux kernel. Workaround Spitfire bug #51.
> */
> diff --git a/urcu/compiler.h b/urcu/compiler.h
> index aab2c5c..5b7bb30 100644
> --- a/urcu/compiler.h
> +++ b/urcu/compiler.h
> @@ -47,4 +47,12 @@
> #define min(a,b) ((a)<(b)?(a):(b))
> #endif
>
> +#if defined(__SIZEOF_LONG__)
> +#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> +#elif defined(_LP64)
How about _LLP64 and _ILP64 ? (not sure exactly which architectures
would fit in this category nowadays though).
Thanks,
Mathieu
> +#define BITS_PER_LONG 64
> +#else
> +#define BITS_PER_LONG 32
> +#endif
> +
> #endif /* _URCU_COMPILER_H */
> diff --git a/urcu/uatomic_arch_ppc.h b/urcu/uatomic_arch_ppc.h
> index b42bfdb..801c41c 100644
> --- a/urcu/uatomic_arch_ppc.h
> +++ b/urcu/uatomic_arch_ppc.h
> @@ -27,24 +27,12 @@
> extern "C" {
> #endif
>
> -#ifndef __SIZEOF_LONG__
> -#ifdef __powerpc64__
> -#define __SIZEOF_LONG__ 8
> -#else
> -#define __SIZEOF_LONG__ 4
> -#endif
> -#endif
> -
> #ifdef __NO_LWSYNC__
> #define LWSYNC_OPCODE "sync\n"
> #else
> #define LWSYNC_OPCODE "lwsync\n"
> #endif
>
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> #define ILLEGAL_INSTR ".long 0xd00d00"
>
> /*
> diff --git a/urcu/uatomic_arch_s390.h b/urcu/uatomic_arch_s390.h
> index 2f9b532..44bcb97 100644
> --- a/urcu/uatomic_arch_s390.h
> +++ b/urcu/uatomic_arch_s390.h
> @@ -36,18 +36,6 @@
> extern "C" {
> #endif
>
> -#ifndef __SIZEOF_LONG__
> -#ifdef __s390x__
> -#define __SIZEOF_LONG__ 8
> -#else
> -#define __SIZEOF_LONG__ 4
> -#endif
> -#endif
> -
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
> #define COMPILER_HAVE_SHORT_MEM_OPERAND
> #endif
> diff --git a/urcu/uatomic_arch_sparc64.h b/urcu/uatomic_arch_sparc64.h
> index ef6572e..df66cd1 100644
> --- a/urcu/uatomic_arch_sparc64.h
> +++ b/urcu/uatomic_arch_sparc64.h
> @@ -27,18 +27,6 @@
> extern "C" {
> #endif
>
> -#ifndef __SIZEOF_LONG__
> -#ifdef __LP64__
> -#define __SIZEOF_LONG__ 8
> -#else
> -#define __SIZEOF_LONG__ 4
> -#endif
> -#endif
> -
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> /* cmpxchg */
>
> static inline __attribute__((always_inline))
> diff --git a/urcu/uatomic_arch_x86.h b/urcu/uatomic_arch_x86.h
> index f2d0c19..269618c 100644
> --- a/urcu/uatomic_arch_x86.h
> +++ b/urcu/uatomic_arch_x86.h
> @@ -30,18 +30,6 @@
> extern "C" {
> #endif
>
> -#ifndef __SIZEOF_LONG__
> -#if defined(__x86_64__) || defined(__amd64__)
> -#define __SIZEOF_LONG__ 8
> -#else
> -#define __SIZEOF_LONG__ 4
> -#endif
> -#endif
> -
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> /*
> * Derived from AO_compare_and_swap() and AO_test_and_set_full().
> */
> diff --git a/urcu/uatomic_defaults.h b/urcu/uatomic_defaults.h
> index 2d0af6e..5c93261 100644
> --- a/urcu/uatomic_defaults.h
> +++ b/urcu/uatomic_defaults.h
> @@ -28,10 +28,6 @@
> extern "C" {
> #endif
>
> -#ifndef BITS_PER_LONG
> -#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
> -#endif
> -
> #ifndef uatomic_set
> #define uatomic_set(addr, v) STORE_SHARED(*(addr), (v))
> #endif
> --
> 1.6.6
>
>
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 11/12] avoid multiple evaluation of STORE_SHARED argument
2010-02-15 19:04 ` [ltt-dev] [PATCH 11/12] avoid multiple evaluation of STORE_SHARED argument Paolo Bonzini
@ 2010-02-18 3:28 ` Mathieu Desnoyers
2010-02-18 8:45 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 3:28 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
Acked-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
Can you please resend the whole patchset after taking my comments into
account ? There is less risk of mistakes like that. Please append the
Acked-by to the patches already acked so I can skip them in the next
rounds of review.
Thanks,
Mathieu
> ---
> urcu/system.h | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/urcu/system.h b/urcu/system.h
> index e36a13b..0c3152f 100644
> --- a/urcu/system.h
> +++ b/urcu/system.h
> @@ -46,9 +46,9 @@
> */
> #define STORE_SHARED(x, v) \
> ({ \
> - _STORE_SHARED(x, v); \
> + typeof(x) _v = _STORE_SHARED(x, v); \
> smp_wmc(); \
> - (v); \
> + _v; \
> })
>
> #endif /* _URCU_SYSTEM_H */
> --
> 1.6.6
>
>
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG
2010-02-18 3:25 ` Mathieu Desnoyers
@ 2010-02-18 8:45 ` Paolo Bonzini
2010-02-18 13:46 ` Mathieu Desnoyers
0 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-18 8:45 UTC (permalink / raw)
On 02/18/2010 04:25 AM, Mathieu Desnoyers wrote:
>> > +#if defined(__SIZEOF_LONG__)
>> > +#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
>> > +#elif defined(_LP64)
> How about _LLP64 and _ILP64 ? (not sure exactly which architectures
> would fit in this category nowadays though).
They are not defined by GCC.
I32LLP64 is basically only Mingw64 and ia64-hpux. They'd probably break
horribly because with 99% likelihood somewhere there is an assumption
that sizeof (long) == sizeof (void*).
What used ILP64, maybe some Cray?
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 11/12] avoid multiple evaluation of STORE_SHARED argument
2010-02-18 3:28 ` Mathieu Desnoyers
@ 2010-02-18 8:45 ` Paolo Bonzini
0 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-18 8:45 UTC (permalink / raw)
On 02/18/2010 04:28 AM, Mathieu Desnoyers wrote:
> * Paolo Bonzini (pbonzini at redhat.com) wrote:
>> Signed-off-by: Paolo Bonzini<pbonzini at redhat.com>
>
> Acked-by: Mathieu Desnoyers<mathieu.desnoyers at efficios.com>
>
> Can you please resend the whole patchset after taking my comments into
> account ? There is less risk of mistakes like that. Please append the
> Acked-by to the patches already acked so I can skip them in the next
> rounds of review.
Of course, thanks.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG
2010-02-18 8:45 ` Paolo Bonzini
@ 2010-02-18 13:46 ` Mathieu Desnoyers
2010-02-18 15:27 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 13:46 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> On 02/18/2010 04:25 AM, Mathieu Desnoyers wrote:
>>> > +#if defined(__SIZEOF_LONG__)
>>> > +#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
>>> > +#elif defined(_LP64)
>> How about _LLP64 and _ILP64 ? (not sure exactly which architectures
>> would fit in this category nowadays though).
>
> They are not defined by GCC.
Good to know.
>
> I32LLP64 is basically only Mingw64 and ia64-hpux.
And anyway I32LLP64 have 4-byte longs, so they should work anyway with
these tests.
> They'd probably break
> horribly because with 99% likelihood somewhere there is an assumption
> that sizeof (long) == sizeof (void*).
In the atomic ops headers possibly, yes.
>
> What used ILP64, maybe some Cray?
Let's ask Paul to see what he knows about this.
As I pointed out, it's not a show stopper not to support everything, but
at least we should know what our limitations are.
Thanks,
Mathieu
>
> Paolo
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG
2010-02-18 13:46 ` Mathieu Desnoyers
@ 2010-02-18 15:27 ` Paolo Bonzini
2010-02-18 16:09 ` Mathieu Desnoyers
0 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-18 15:27 UTC (permalink / raw)
On 02/18/2010 02:46 PM, Mathieu Desnoyers wrote:
>> >
>> > I32LLP64 is basically only Mingw64 and ia64-hpux.
> And anyway I32LLP64 have 4-byte longs, so they should work anyway with
> these tests.
>
>> > They'd probably break
>> > horribly because with 99% likelihood somewhere there is an assumption
>> > that sizeof (long) == sizeof (void*).
>
> In the atomic ops headers possibly, yes.
You couldn't use atomic op headers to exchange pointers too. Maybe not
used by liburcu, but still a strong limitation.
Some time we should also add double-long compare-and-swap, that's very
useful for lock-free lists.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG
2010-02-18 15:27 ` Paolo Bonzini
@ 2010-02-18 16:09 ` Mathieu Desnoyers
2010-02-19 19:25 ` [ltt-dev] lock-free data structures (was Re: [PATCH 12/12] centralize definition of BITS_PER_LONG) Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Mathieu Desnoyers @ 2010-02-18 16:09 UTC (permalink / raw)
* Paolo Bonzini (pbonzini at redhat.com) wrote:
> On 02/18/2010 02:46 PM, Mathieu Desnoyers wrote:
>>> >
>>> > I32LLP64 is basically only Mingw64 and ia64-hpux.
>> And anyway I32LLP64 have 4-byte longs, so they should work anyway with
>> these tests.
>>
>>> > They'd probably break
>>> > horribly because with 99% likelihood somewhere there is an assumption
>>> > that sizeof (long) == sizeof (void*).
>>
>> In the atomic ops headers possibly, yes.
>
> You couldn't use atomic op headers to exchange pointers too. Maybe not
> used by liburcu, but still a strong limitation.
Well the current atomic op headers are per-architecture. This should be
taken into account for the generic version you are proposing I guess.
>
> Some time we should also add double-long compare-and-swap, that's very
> useful for lock-free lists.
Yes, good idea! Although this won't be available on all architectures.
We might have to think of a mutex-based compatibility layer for these.
Do you have pointers to papers describing this double-wide CAS
linked-list structure ? I wonder if we could use a clever RCU structure
to mimick the double-wide CAS.
Thanks,
Mathieu
>
> Paolo
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
>
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] lock-free data structures (was Re: [PATCH 12/12] centralize definition of BITS_PER_LONG)
2010-02-18 16:09 ` Mathieu Desnoyers
@ 2010-02-19 19:25 ` Paolo Bonzini
2010-02-19 23:51 ` Paul E. McKenney
0 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-19 19:25 UTC (permalink / raw)
>> Some time we should also add double-long compare-and-swap, that's very
>> useful for lock-free lists.
>
> Do you have pointers to papers describing this double-wide CAS
> linked-list structure ?
I found
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.86.8494&rep=rep1&type=pdf
(page 4) which is a lock-free queue.
The two words are used like this:
struct gen_ptr {
long gen;
void *ptr;
}
where gen is always incremented whenever ptr is changed.
> Yes, good idea! Although this won't be available on all architectures.
> We might have to think of a mutex-based compatibility layer for these.
You don't need a mutex if you use it for a lock-free queue. You're just
better off providing two version of the queue, one for double-word CAS
and a not-really-lock-free one for simple CAS.
The elementary operation in that algorithm are reading a struct gen_ptr
in a way that can be compared-and-swapped later, and doing a
compare-and-swap that checks consistency of generation and pointer and
increments the generation. If you have double-word CAS, everything is
very simple because consistency is taken care of by the double-word CAS.
So with double-word CAS the above are
void *atomicRead (struct gen_ptr *val)
{
return val->ptr;
}
and
long atomicCmpXchgIncrGeneration (struct gen_ptr *val, void *old_ptr,
void *new_ptr)
{
int old_gen = val->gen;
struct gen_ptr read =
atomicCmpXchgDouble (val, old_gen, old_ptr,
old_gen + 1, new_ptr)
return read.gen;
}
but even without double-word CAS you can do it because if the
generations match, so will the pointers. So the CAS will be on the
generation in this case, and you use the low-order bit as a tag bit for
"operation in progress". It would go something like this (untested):
struct gen_ptr atomicRead (struct gen_ptr *val)
{
struct gen_ptr read;
for (;;) {
read.gen = val->gen;
if (read.gen & 1) {
/* Unlucky. */
continue;
} else {
read.ptr = val->ptr;
rmb ();
if (read.gen == val->gen)
return read;
}
}
}
long
atomicCmpXchgWithGeneration (struct gen_ptr *val, long old_gen,
void *new_ptr)
{
assert (!(old_gen & 1));
int read_gen = CAS (&val->gen, old_gen, old_gen + 3);
if (read_gen == old_gen) {
/* We are the only ones that have access to val->ptr here.
Since the low bit is 1, other threads will lock on
atomicRead and fail the CAS in their
atomicCmpXchgWithGeneration. Update val->ptr and untag
the generation number. */
val->ptr = new_ptr;
wmb ();
val->gen--;
}
return read_gen;
}
Now, while the above is certainly fun, I don't think it belongs in
liburcu. However...
> I wonder if we could use a clever RCU structure
> to mimick the double-wide CAS.
I don't know, I think lock-free queues and RCU are used for very
different access patterns (and if you need lock-free, chances are that
lock-free will kill your cache and not give you _that much_ performance,
so maybe you'd better rethink everything...). However I'm not expert at
all.
Still, related to this, the paper above gives only half of the story.
The lock-free queue needs a free list traditionally, and the paper
mentions using a lock-free stack as a free list (BTW the lock-free stack
doesn't need double-word CAS). But then, the nodes on the freelist can
never be returned to the OS because you can always race with the
operations on the lock-free queue.
So, maybe RCU could be used to detect quiescent periods when there is no
operation being performed on the lock-free queue. *Both enqueue and
dequeue* would be wrapped in rcu_read_{,un}lock(), unlike normal RCU
algorithms because this one is lock free. Then, in dequeue you'd
replace the paper's line D19 with
defer_rcu(free, head);
Hmm...
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] lock-free data structures (was Re: [PATCH 12/12] centralize definition of BITS_PER_LONG)
2010-02-19 19:25 ` [ltt-dev] lock-free data structures (was Re: [PATCH 12/12] centralize definition of BITS_PER_LONG) Paolo Bonzini
@ 2010-02-19 23:51 ` Paul E. McKenney
2010-02-20 0:10 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Paul E. McKenney @ 2010-02-19 23:51 UTC (permalink / raw)
On Fri, Feb 19, 2010 at 08:25:04PM +0100, Paolo Bonzini wrote:
>
>>> Some time we should also add double-long compare-and-swap, that's very
>>> useful for lock-free lists.
>>
>> Do you have pointers to papers describing this double-wide CAS
>> linked-list structure ?
>
> I found
> http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.86.8494&rep=rep1&type=pdf
> (page 4) which is a lock-free queue.
>
> The two words are used like this:
>
> struct gen_ptr {
> long gen;
> void *ptr;
> }
>
> where gen is always incremented whenever ptr is changed.
Doesn't the use of RCU prevent the ABA scenario, and doesn't that make
DCAS unnecessary?
Thanx, Paul
>> Yes, good idea! Although this won't be available on all architectures.
>> We might have to think of a mutex-based compatibility layer for these.
>
> You don't need a mutex if you use it for a lock-free queue. You're just
> better off providing two version of the queue, one for double-word CAS and
> a not-really-lock-free one for simple CAS.
>
> The elementary operation in that algorithm are reading a struct gen_ptr in
> a way that can be compared-and-swapped later, and doing a compare-and-swap
> that checks consistency of generation and pointer and increments the
> generation. If you have double-word CAS, everything is very simple because
> consistency is taken care of by the double-word CAS. So with double-word
> CAS the above are
>
> void *atomicRead (struct gen_ptr *val)
> {
> return val->ptr;
> }
>
> and
>
> long atomicCmpXchgIncrGeneration (struct gen_ptr *val, void *old_ptr,
> void *new_ptr)
> {
> int old_gen = val->gen;
> struct gen_ptr read =
> atomicCmpXchgDouble (val, old_gen, old_ptr,
> old_gen + 1, new_ptr)
> return read.gen;
> }
>
> but even without double-word CAS you can do it because if the generations
> match, so will the pointers. So the CAS will be on the generation in this
> case, and you use the low-order bit as a tag bit for "operation in
> progress". It would go something like this (untested):
>
> struct gen_ptr atomicRead (struct gen_ptr *val)
> {
> struct gen_ptr read;
> for (;;) {
> read.gen = val->gen;
> if (read.gen & 1) {
> /* Unlucky. */
> continue;
> } else {
> read.ptr = val->ptr;
> rmb ();
> if (read.gen == val->gen)
> return read;
> }
> }
> }
>
> long
> atomicCmpXchgWithGeneration (struct gen_ptr *val, long old_gen,
> void *new_ptr)
> {
> assert (!(old_gen & 1));
> int read_gen = CAS (&val->gen, old_gen, old_gen + 3);
> if (read_gen == old_gen) {
> /* We are the only ones that have access to val->ptr here.
> Since the low bit is 1, other threads will lock on
> atomicRead and fail the CAS in their
> atomicCmpXchgWithGeneration. Update val->ptr and untag
> the generation number. */
> val->ptr = new_ptr;
> wmb ();
> val->gen--;
> }
> return read_gen;
> }
>
> Now, while the above is certainly fun, I don't think it belongs in liburcu.
> However...
>
>> I wonder if we could use a clever RCU structure
>> to mimick the double-wide CAS.
>
> I don't know, I think lock-free queues and RCU are used for very different
> access patterns (and if you need lock-free, chances are that lock-free will
> kill your cache and not give you _that much_ performance, so maybe you'd
> better rethink everything...). However I'm not expert at all.
>
> Still, related to this, the paper above gives only half of the story. The
> lock-free queue needs a free list traditionally, and the paper mentions
> using a lock-free stack as a free list (BTW the lock-free stack doesn't
> need double-word CAS). But then, the nodes on the freelist can never be
> returned to the OS because you can always race with the operations on the
> lock-free queue.
>
> So, maybe RCU could be used to detect quiescent periods when there is no
> operation being performed on the lock-free queue. *Both enqueue and
> dequeue* would be wrapped in rcu_read_{,un}lock(), unlike normal RCU
> algorithms because this one is lock free. Then, in dequeue you'd replace
> the paper's line D19 with
>
> defer_rcu(free, head);
>
> Hmm...
>
> Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] lock-free data structures (was Re: [PATCH 12/12] centralize definition of BITS_PER_LONG)
2010-02-19 23:51 ` Paul E. McKenney
@ 2010-02-20 0:10 ` Paolo Bonzini
2010-02-20 0:44 ` Paul E. McKenney
0 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-20 0:10 UTC (permalink / raw)
On 02/20/2010 12:51 AM, Paul E. McKenney wrote:
> Doesn't the use of RCU prevent the ABA scenario, and doesn't that make
> DCAS unnecessary?
Yeah, looks like it's so! So by wrapping enqueue/dequeue with RCU you
could strip the generation counts (giving the algorithm that is usually
taught for garbage-collected environments only)... nice, I guess DCAS is
not so much needed in the context of liburcu.
I'll try to write an example.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] lock-free data structures (was Re: [PATCH 12/12] centralize definition of BITS_PER_LONG)
2010-02-20 0:10 ` Paolo Bonzini
@ 2010-02-20 0:44 ` Paul E. McKenney
0 siblings, 0 replies; 31+ messages in thread
From: Paul E. McKenney @ 2010-02-20 0:44 UTC (permalink / raw)
On Sat, Feb 20, 2010 at 01:10:45AM +0100, Paolo Bonzini wrote:
> On 02/20/2010 12:51 AM, Paul E. McKenney wrote:
>> Doesn't the use of RCU prevent the ABA scenario, and doesn't that make
>> DCAS unnecessary?
>
> Yeah, looks like it's so! So by wrapping enqueue/dequeue with RCU you
> could strip the generation counts (giving the algorithm that is usually
> taught for garbage-collected environments only)... nice, I guess DCAS is
> not so much needed in the context of liburcu.
>
> I'll try to write an example.
I look forward to seeing it!
Thanx, Paul
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ltt-dev] [PATCH 04/12] define sync_core for x86 PIC
2010-02-19 19:22 [ltt-dev] [PATCH 00/12] provide generic version of uatomic and other per-arch defs Paolo Bonzini
@ 2010-02-19 19:22 ` Paolo Bonzini
0 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2010-02-19 19:22 UTC (permalink / raw)
Pushing/popping the reserved ebx register is surely less expensive
than a memory barrier.
Note that since ebx is a callee-save register, this is even safe for
signals (i.e. it would be safe even if we needed the value that cpuid
puts in %%ebx).
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
Acked-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
urcu/arch_x86.h | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/urcu/arch_x86.h b/urcu/arch_x86.h
index c4674de..64cc026 100644
--- a/urcu/arch_x86.h
+++ b/urcu/arch_x86.h
@@ -49,9 +49,13 @@ extern "C" {
/*
* Serialize core instruction execution. Also acts as a compiler barrier.
- * Cannot use cpuid on PIC because it clobbers the ebx register;
- * error: PIC register 'ebx' clobbered in 'asm'
+ * On PIC ebx cannot be clobbered
*/
+#ifdef __PIC__
+#define sync_core() \
+ asm volatile("push %%ebx; cpuid; pop %%ebx" \
+ : : : "memory", "eax", "ecx", "edx");
+#endif
#ifndef __PIC__
#define sync_core() \
asm volatile("cpuid" : : : "memory", "eax", "ebx", "ecx", "edx");
--
1.6.6
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2010-02-20 0:44 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-15 19:04 [ltt-dev] [PATCH 00/12] provide default definition of uatomic builtins Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 01/12] use kernel style makefile output Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 02/12] use autoconf symbolic linking Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 03/12] add urcu/arch_defaults.h Paolo Bonzini
2010-02-18 2:57 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 04/12] define sync_core for x86 PIC Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 05/12] remove compat_uatomic_cmpxchg #define from non-x86 Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 06/12] add uatomic_defaults.h, use it for default definitions Paolo Bonzini
2010-02-18 3:10 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 07/12] use uatomic_defaults.h for common fallback implementations Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 08/12] move whether atomic byte/short exists to uatomic_arch_*.h Paolo Bonzini
2010-02-18 3:12 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 09/12] add Alpha support Paolo Bonzini
2010-02-18 3:21 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 10/12] support compiling on unknown architectures Paolo Bonzini
2010-02-18 3:22 ` Mathieu Desnoyers
2010-02-15 19:04 ` [ltt-dev] [PATCH 11/12] avoid multiple evaluation of STORE_SHARED argument Paolo Bonzini
2010-02-18 3:28 ` Mathieu Desnoyers
2010-02-18 8:45 ` Paolo Bonzini
2010-02-15 19:04 ` [ltt-dev] [PATCH 12/12] centralize definition of BITS_PER_LONG Paolo Bonzini
2010-02-18 3:25 ` Mathieu Desnoyers
2010-02-18 8:45 ` Paolo Bonzini
2010-02-18 13:46 ` Mathieu Desnoyers
2010-02-18 15:27 ` Paolo Bonzini
2010-02-18 16:09 ` Mathieu Desnoyers
2010-02-19 19:25 ` [ltt-dev] lock-free data structures (was Re: [PATCH 12/12] centralize definition of BITS_PER_LONG) Paolo Bonzini
2010-02-19 23:51 ` Paul E. McKenney
2010-02-20 0:10 ` Paolo Bonzini
2010-02-20 0:44 ` Paul E. McKenney
2010-02-15 19:04 ` [ltt-dev] [PATCH 13/12] test uatomic_defaults.h Paolo Bonzini
2010-02-19 19:22 [ltt-dev] [PATCH 00/12] provide generic version of uatomic and other per-arch defs Paolo Bonzini
2010-02-19 19:22 ` [ltt-dev] [PATCH 04/12] define sync_core for x86 PIC Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox