Add arm atomic operations
authorMatthias Clasen <matthiasc@src.gnome.org>
Tue, 11 Sep 2007 04:16:59 +0000 (04:16 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 11 Sep 2007 04:16:59 +0000 (04:16 +0000)
svn path=/trunk/; revision=5748

ChangeLog
configure.in
glib/gatomic.c

index 786865d..8e138cd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-09-11  Matthias Clasen  <mclasen@redhat.com>
+
+       * configure.in: Define G_ATOMIC_ARM.
+
+       * glib/gatomic.c: Add Arm implementation of atomic
+       operations.  (#457601, Jussi Laako)
+
 2007-09-10  Marco Barisione <marco@barisione.org>
 
        * glib/gregex.c: define PCRE_ERROR_NULLWSLIMIT if it's not defined by
index bc81128..eea8af4 100644 (file)
@@ -228,9 +228,6 @@ if test "x$enable_threads" != "xyes"; then
   enable_threads=no
 fi
 
-AC_DEFINE_UNQUOTED(G_COMPILED_WITH_DEBUGGING, ["${enable_debug}"],
-       [Whether glib was compiled with debugging enabled])
-
 AC_MSG_CHECKING([whether to enable garbage collector friendliness])
 if test "x$enable_gc_friendly" = "xyes"; then
   AC_DEFINE(ENABLE_GC_FRIENDLY_DEFAULT, 1, [Whether to enable GC friendliness by default])
@@ -2100,6 +2097,12 @@ if test x"$GCC" = xyes; then
                         [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
+      ;;
     *)
       AC_MSG_RESULT([none])
       glib_memory_barrier_needed=yes
index dec4138..5cbcc46 100644 (file)
@@ -3,6 +3,7 @@
  *
  * g_atomic_*: atomic operations.
  * Copyright (C) 2003 Sebastian Wilhelmi
+ * Copyright (C) 2007 Nokia Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+#if defined (G_ATOMIC_ARM)
+#include <sched.h>
+#endif
+
 #include "config.h"
 
 #include "glib.h"
@@ -482,7 +487,98 @@ g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
 #  else /* What's that */
 #    error "Your system has an unsupported pointer size"
 #  endif /* GLIB_SIZEOF_VOID_P */
-# else /* !G_ATOMIC_IA64 */
+# elif defined (G_ATOMIC_ARM)
+static volatile int atomic_spin = 0;
+
+static int atomic_spin_trylock (void)
+{
+  int result;
+
+  asm volatile (
+    "swp %0, %1, [%2]\n"
+    : "=&r,&r" (result)
+    : "r,0" (1), "r,r" (&atomic_spin)
+    : "memory");
+  if (result == 0)
+    return 0;
+  else
+    return -1;
+}
+
+static void atomic_spin_lock (void)
+{
+  while (atomic_spin_trylock())
+    sched_yield();
+}
+
+static void atomic_spin_unlock (void)
+{
+  atomic_spin = 0;
+}
+
+gint
+g_atomic_int_exchange_and_add (volatile gint *atomic, 
+                              gint           val)
+{
+  gint result;
+  atomic_spin_lock();  
+  result = *atomic;
+  *atomic += val;
+  atomic_spin_unlock();
+
+  return result;
+}
+
+void
+g_atomic_int_add (volatile gint *atomic,
+                 gint           val)
+{
+  atomic_spin_lock();
+  *atomic += val;
+  atomic_spin_unlock();
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint *atomic, 
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  gboolean result;
+
+  atomic_spin_lock();
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  atomic_spin_unlock();
+
+  return result;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gboolean result;
+  atomic_spin_lock();
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  atomic_spin_unlock();
+
+  return result;
+}
+# else /* !G_ATOMIC_ARM */
 #  define DEFINE_WITH_MUTEXES
 # endif /* G_ATOMIC_IA64 */
 #else /* !__GNUC__ */