[glib] Use GCC atomic builtin operations.
- From: Hiroyuki Ikezoe <hiikezoe src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib] Use GCC atomic builtin operations.
- Date: Thu, 7 Jan 2010 10:36:01 +0000 (UTC)
commit 37716bd00a7911de545ebca3dc7a248503eaf46e
Author: Hiroyuki Ikezoe <poincare ikezoe net>
Date: Thu Jan 7 19:33:39 2010 +0900
Use GCC atomic builtin operations.
Fix for bug #531902.
configure.in | 211 ++++++++++++++++++++++++++++------------------------
glib/Makefile.am | 8 ++-
glib/gatomic-gcc.c | 92 +++++++++++++++++++++++
3 files changed, 214 insertions(+), 97 deletions(-)
---
diff --git a/configure.in b/configure.in
index edc4142..8221911 100644
--- a/configure.in
+++ b/configure.in
@@ -2412,103 +2412,119 @@ dnl ********************************
AC_MSG_CHECKING([whether to use assembler code for atomic operations])
+glib_cv_gcc_has_builtin_atomic_operations=no
if test x"$GCC" = xyes; then
- case $host_cpu in
- i386)
- AC_MSG_RESULT([none])
- glib_memory_barrier_needed=no
- ;;
- i?86)
- AC_MSG_RESULT([i486])
- AC_DEFINE_UNQUOTED(G_ATOMIC_I486, 1,
- [i486 atomic implementation])
- glib_memory_barrier_needed=no
- ;;
- sparc*)
- SPARCV9_WARNING="Try to rerun configure with CFLAGS='-mcpu=v9',
- when you are using a sparc with v9 instruction set (most
- sparcs nowadays). This will make the code for atomic
- operations much faster. The resulting code will not run
- on very old sparcs though."
-
- AC_LINK_IFELSE([[
- main ()
- {
- int tmp1, tmp2, tmp3;
- __asm__ __volatile__("casx [%2], %0, %1"
- : "=&r" (tmp1), "=&r" (tmp2) : "r" (&tmp3));
- }]],
- AC_MSG_RESULT([sparcv9])
- AC_DEFINE_UNQUOTED(G_ATOMIC_SPARCV9, 1,
- [sparcv9 atomic implementation]),
- AC_MSG_RESULT([no])
- AC_MSG_WARN([[$SPARCV9_WARNING]]))
- glib_memory_barrier_needed=yes
- ;;
- alpha*)
- AC_MSG_RESULT([alpha])
- AC_DEFINE_UNQUOTED(G_ATOMIC_ALPHA, 1,
- [alpha atomic implementation])
- glib_memory_barrier_needed=yes
- ;;
- x86_64)
- AC_MSG_RESULT([x86_64])
- AC_DEFINE_UNQUOTED(G_ATOMIC_X86_64, 1,
- [x86_64 atomic implementation])
- glib_memory_barrier_needed=no
- ;;
- powerpc*)
- AC_MSG_RESULT([powerpc])
- AC_DEFINE_UNQUOTED(G_ATOMIC_POWERPC, 1,
- [powerpc atomic implementation])
- glib_memory_barrier_needed=yes
- AC_MSG_CHECKING([whether asm supports numbered local labels])
- AC_TRY_COMPILE(
- ,[
- __asm__ __volatile__ ("1: nop\n"
- " bne- 1b")
- ],[
- AC_DEFINE_UNQUOTED(ASM_NUMERIC_LABELS, 1, [define if asm blocks can use numeric local labels])
- AC_MSG_RESULT([yes])
- ],[
- AC_MSG_RESULT([no])
- ])
- ;;
- ia64)
- AC_MSG_RESULT([ia64])
- AC_DEFINE_UNQUOTED(G_ATOMIC_IA64, 1,
- [ia64 atomic implementation])
- glib_memory_barrier_needed=yes
- ;;
- s390|s390x)
- AC_MSG_RESULT([s390])
- AC_DEFINE_UNQUOTED(G_ATOMIC_S390, 1,
- [s390 atomic implementation])
- glib_memory_barrier_needed=no
- ;;
- arm*)
- AC_MSG_RESULT([arm])
- AC_DEFINE_UNQUOTED(G_ATOMIC_ARM, 1,
- [arm atomic implementation])
- glib_memory_barrier_needed=no
- ;;
- crisv32*|etraxfs*)
- AC_MSG_RESULT([crisv32])
- AC_DEFINE_UNQUOTED(G_ATOMIC_CRISV32, 1,
- [crisv32 atomic implementation])
- glib_memory_barrier_needed=no
- ;;
- cris*|etrax*)
- AC_MSG_RESULT([cris])
- AC_DEFINE_UNQUOTED(G_ATOMIC_CRIS, 1,
- [cris atomic implementation])
- glib_memory_barrier_needed=no
- ;;
- *)
- AC_MSG_RESULT([none])
- glib_memory_barrier_needed=yes
- ;;
- esac
+ AC_MSG_CHECKING([whether GCC supports build-in atomic intrinsics])
+ AC_TRY_LINK([],
+ [int i;
+ __sync_synchronize ();
+ __sync_bool_compare_and_swap (&i, 0, 1);
+ __sync_fetch_and_add (&i, 1);
+ ],
+ [glib_cv_gcc_has_builtin_atomic_operations=yes],
+ [glib_cv_gcc_has_builtin_atomic_operations=no])
+
+ AC_MSG_RESULT($glib_cv_gcc_has_builtin_atomic_operations)
+ if test $glib_cv_gcc_has_builtin_atomic_operations = yes; then
+ glib_memory_barrier_needed=yes
+ else
+ case $host_cpu in
+ i386)
+ AC_MSG_RESULT([none])
+ glib_memory_barrier_needed=no
+ ;;
+ i?86)
+ AC_MSG_RESULT([i486])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_I486, 1,
+ [i486 atomic implementation])
+ glib_memory_barrier_needed=no
+ ;;
+ sparc*)
+ SPARCV9_WARNING="Try to rerun configure with CFLAGS='-mcpu=v9',
+ when you are using a sparc with v9 instruction set (most
+ sparcs nowadays). This will make the code for atomic
+ operations much faster. The resulting code will not run
+ on very old sparcs though."
+
+ AC_LINK_IFELSE([[
+ main ()
+ {
+ int tmp1, tmp2, tmp3;
+ __asm__ __volatile__("casx [%2], %0, %1"
+ : "=&r" (tmp1), "=&r" (tmp2) : "r" (&tmp3));
+ }]],
+ AC_MSG_RESULT([sparcv9])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_SPARCV9, 1,
+ [sparcv9 atomic implementation]),
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([[$SPARCV9_WARNING]]))
+ glib_memory_barrier_needed=yes
+ ;;
+ alpha*)
+ AC_MSG_RESULT([alpha])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_ALPHA, 1,
+ [alpha atomic implementation])
+ glib_memory_barrier_needed=yes
+ ;;
+ x86_64)
+ AC_MSG_RESULT([x86_64])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_X86_64, 1,
+ [x86_64 atomic implementation])
+ glib_memory_barrier_needed=no
+ ;;
+ powerpc*)
+ AC_MSG_RESULT([powerpc])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_POWERPC, 1,
+ [powerpc atomic implementation])
+ glib_memory_barrier_needed=yes
+ AC_MSG_CHECKING([whether asm supports numbered local labels])
+ AC_TRY_COMPILE(
+ ,[
+ __asm__ __volatile__ ("1: nop\n"
+ " bne- 1b")
+ ],[
+ AC_DEFINE_UNQUOTED(ASM_NUMERIC_LABELS, 1, [define if asm blocks can use numeric local labels])
+ AC_MSG_RESULT([yes])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+ ;;
+ ia64)
+ AC_MSG_RESULT([ia64])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_IA64, 1,
+ [ia64 atomic implementation])
+ glib_memory_barrier_needed=yes
+ ;;
+ s390|s390x)
+ AC_MSG_RESULT([s390])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_S390, 1,
+ [s390 atomic implementation])
+ glib_memory_barrier_needed=no
+ ;;
+ arm*)
+ AC_MSG_RESULT([arm])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_ARM, 1,
+ [arm atomic implementation])
+ glib_memory_barrier_needed=no
+ ;;
+ crisv32*|etraxfs*)
+ AC_MSG_RESULT([crisv32])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_CRISV32, 1,
+ [crisv32 atomic implementation])
+ glib_memory_barrier_needed=no
+ ;;
+ cris*|etrax*)
+ AC_MSG_RESULT([cris])
+ AC_DEFINE_UNQUOTED(G_ATOMIC_CRIS, 1,
+ [cris atomic implementation])
+ glib_memory_barrier_needed=no
+ ;;
+ *)
+ AC_MSG_RESULT([none])
+ glib_memory_barrier_needed=yes
+ ;;
+ esac
+ fi
else
if test $glib_native_win32 = yes; then
# For Windows but not using gcc. No barriers needed then either.
@@ -2516,6 +2532,9 @@ else
fi
fi
+AM_CONDITIONAL(HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS,
+ [test $glib_cv_gcc_has_builtin_atomic_operations = yes])
+
dnl ****************************************
dnl *** GLib POLL* compatibility defines ***
dnl ****************************************
diff --git a/glib/Makefile.am b/glib/Makefile.am
index e2080fb..5701922 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -19,6 +19,12 @@ gregex_c =
gregex_h =
endif
+if HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS
+gatomic_c = gatomic-gcc.c
+else
+gatomic_c = gatomic.c
+endif
+
SUBDIRS = libcharset $(PRINTF_SUBDIR) $(MAYBE_PCRE) update-pcre . tests
DIST_SUBDIRS = libcharset gnulib pcre update-pcre tests
@@ -100,7 +106,7 @@ uninstall-ms-lib:
libglib_2_0_la_SOURCES = \
garray.c \
gasyncqueue.c \
- gatomic.c \
+ $(gatomic_c) \
gbacktrace.c \
gbase64.c \
gbookmarkfile.c \
diff --git a/glib/gatomic-gcc.c b/glib/gatomic-gcc.c
new file mode 100644
index 0000000..7b33b19
--- /dev/null
+++ b/glib/gatomic-gcc.c
@@ -0,0 +1,92 @@
+/* GLIB - Library of useful routines for C programming
+ * gatomic-gcc.c: atomic operations using GCC builtins.
+ * Copyright (C) 2009 Hiroyuki Ikezoe
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "glib.h"
+#include "galias.h"
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ return __sync_fetch_and_add (atomic, val);
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ __sync_fetch_and_add (atomic, val);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ return __sync_bool_compare_and_swap (atomic, oldval, newval);
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ return __sync_bool_compare_and_swap (atomic, oldval, newval);
+}
+
+void
+_g_atomic_thread_init (void)
+{
+}
+
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+ __sync_synchronize ();
+ return *atomic;
+}
+
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint newval)
+{
+ *atomic = newval;
+ __sync_synchronize ();
+}
+
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+ __sync_synchronize ();
+ return *atomic;
+}
+
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer newval)
+{
+ *atomic = newval;
+ __sync_synchronize ();
+}
+
+#define __G_ATOMIC_C__
+#include "galiasdef.c"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]