[maemo-commits] [maemo-commits] r14937 - in projects/haf/trunk/glib: . glib
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Mon Dec 10 14:55:42 EET 2007
- Previous message: [maemo-commits] r14936 - in projects/haf/trunk/glib: glib gthread
- Next message: [maemo-commits] r14938 - projects/haf/tags/glib2.0
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: xan
Date: 2007-12-10 14:55:36 +0200 (Mon, 10 Dec 2007)
New Revision: 14937
Modified:
projects/haf/trunk/glib/configure.in
projects/haf/trunk/glib/glib/gatomic.c
Log:
Atomic operations for ARM.
Part of bug NB#76856
Modified: projects/haf/trunk/glib/configure.in
===================================================================
--- projects/haf/trunk/glib/configure.in 2007-12-10 12:53:55 UTC (rev 14936)
+++ projects/haf/trunk/glib/configure.in 2007-12-10 12:55:36 UTC (rev 14937)
@@ -2089,6 +2089,35 @@
[s390 atomic implementation])
glib_memory_barrier_needed=no
;;
+ arm*)
+ AC_MSG_RESULT([arm])
+ AC_MSG_CHECKING(arm atomic operations type)
+ if test x$glib_os_linux != xyes; then
+ AC_MSG_RESULT(inline asm)
+ glib_save_CFLAGS=$CFLAGS
+ AC_MSG_CHECKING(architecture supports ARMv6 instructions)
+ cp $srcdir/armv6-test.c conftest.$ac_ext
+ CFLAGS="$CFLAGS -march=armv6"
+ AC_TRY_RUN(ac_compile,
+ [AC_DEFINE_UNQUOTED(G_ATOMIC_ARM, 6,
+ [armv6 atomic implementation])
+ glib_memory_barrier_needed=yes
+ add_flags="-march=armv6"
+ AC_MSG_RESULT(armv6)],
+ [AC_DEFINE_UNQUOTED(G_ATOMIC_ARM, 1,
+ [arm atomic implementation])
+ glib_memory_barrier_needed=no
+ add_flags=""
+ AC_MSG_RESULT(pre-armv6)])
+ CFLAGS=$glib_save_CFLAGS
+ CFLAGS="$CFLAGS $add_flags"
+ else
+ AC_MSG_RESULT(kernel helper)
+ AC_DEFINE_UNQUOTED(G_ATOMIC_ARM_LINUX, 1,
+ [special arm linux implementation])
+ glib_memory_barrier_needed=yes
+ fi
+ ;;
*)
AC_MSG_RESULT([none])
glib_memory_barrier_needed=yes
Modified: projects/haf/trunk/glib/glib/gatomic.c
===================================================================
--- projects/haf/trunk/glib/glib/gatomic.c 2007-12-10 12:53:55 UTC (rev 14936)
+++ projects/haf/trunk/glib/glib/gatomic.c 2007-12-10 12:55:36 UTC (rev 14937)
@@ -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
@@ -19,9 +20,13 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
-
+
#include "config.h"
+#if defined (G_ATOMIC_ARM)
+#include <sched.h>
+#endif
+
#include "glib.h"
#include "gthreadprivate.h"
#include "galias.h"
@@ -482,7 +487,282 @@
# 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)
+# if (G_ATOMIC_ARM < 6)
+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 < 6 */
+gint
+g_atomic_int_exchange_and_add (volatile gint *atomic,
+ gint val)
+{
+ unsigned long result;
+ int old, tmp;
+
+ do {
+ asm volatile (
+ "ldrex %0, [%3]\n"
+ "add %1, %0, %4\n"
+ "strex %2, %1, [%3]\n"
+ : "=&r" (old), "=&r" (tmp), "=&r" (result)
+ : "r" (atomic), "Ir" (val)
+ : "cc", "memory");
+ } while (result);
+ return old;
+}
+
+void
+g_atomic_int_add (volatile gint *atomic,
+ gint val)
+{
+ unsigned long result;
+ int tmp;
+
+ do {
+ asm volatile (
+ "ldrex %0, [%2]\n"
+ "add %0, %0, %3\n"
+ "strex %1, %0, [%2]\n"
+ : "=&r" (tmp), "=&r" (result)
+ : "r" (atomic), "Ir" (val)
+ : "cc", "memory");
+ } while (result);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint *atomic,
+ gint oldval,
+ gint newval)
+{
+ unsigned long result;
+ int old;
+
+ asm volatile (
+ "ldrex %1, [%2]\n"
+ "mov %0, #0\n"
+ "teq %1, %3\n"
+ "strexeq %0, %4, [%2]\n"
+ : "=&r" (result), "=&r" (old)
+ : "r" (atomic), "Ir" (oldval), "r" (newval)
+ : "cc", "memory");
+ return (result) ? FALSE : TRUE;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ unsigned long result;
+ void *old;
+
+ asm volatile (
+ "ldrex %1, [%2]\n"
+ "mov %0, #0\n"
+ "teq %1, %3\n"
+ "strexeq %0, %4, [%2]\n"
+ : "=&r" (result), "=&r" (old)
+ : "r" (atomic), "Ir" (oldval), "r" (newval)
+ : "cc", "memory");
+ return (result) ? FALSE : TRUE;
+}
+
+gint
+g_atomic_int_get (volatile gint *atomic)
+{
+ return *atomic;
+}
+
+void
+g_atomic_int_set (volatile gint *atomic,
+ gint newval)
+{
+ unsigned long result;
+
+ do {
+ asm volatile (
+ "ldrex %0, [%1]\n"
+ "strex %0, %2, [%1]\n"
+ : "=&r" (result)
+ : "r" (atomic), "r" (newval)
+ : "cc", "memory");
+ } while (result);
+}
+
+gpointer
+g_atomic_pointer_get (volatile gpointer *atomic)
+{
+ return *atomic;
+}
+
+void
+g_atomic_pointer_set (volatile gpointer *atomic,
+ gpointer newval)
+{
+ unsigned long result;
+
+ do {
+ asm volatile (
+ "ldrex %0, [%1]\n"
+ "strex %0, %2, [%1]\n"
+ : "=&r" (result)
+ : "r" (atomic), "r" (newval)
+ : "cc", "memory");
+ } while (result);
+}
+# endif /* G_ATOMIC_ARM < 6 */
+# elif defined(G_ATOMIC_ARM_LINUX)
+/* use special helper functions provided by the linux kernel */
+
+typedef void (_khelper_barrier_t)(void);
+#define _khelper_barrier (*(_khelper_barrier_t *)0xffff0fa0)
+/*#define G_ATOMIC_MEMORY_BARRIER _khelper_barrier()*/
+/* scratchbox/qemu explodes on barrier */
+#define G_ATOMIC_MEMORY_BARRIER while(0)
+typedef int (_khelper_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define _khelper_cmpxchg (*(_khelper_cmpxchg_t *)0xffff0fc0)
+
+gint
+g_atomic_int_exchange_and_add (volatile gint *atomic,
+ gint val)
+{
+ int result;
+ int old, new;
+
+ do {
+ old = *atomic;
+ new = old + val;
+ result = _khelper_cmpxchg(old, new, atomic);
+ } while (result);
+ return old;
+}
+
+void
+g_atomic_int_add (volatile gint *atomic,
+ gint val)
+{
+ int result;
+ int old, new;
+
+ do {
+ old = *atomic;
+ new = old + val;
+ result = _khelper_cmpxchg(old, new, atomic);
+ } while (result);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint *atomic,
+ gint oldval,
+ gint newval)
+{
+ int result;
+
+ result = _khelper_cmpxchg(oldval, newval, atomic);
+ return (result) ? FALSE : TRUE;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ int result;
+
+ result = _khelper_cmpxchg(*((int *) &oldval),
+ *((int *) &newval),
+ (int *) atomic);
+ return (result) ? FALSE : TRUE;
+}
+# else /* !G_ATOMIC_ARM_LINUX */
# define DEFINE_WITH_MUTEXES
# endif /* G_ATOMIC_IA64 */
#else /* !__GNUC__ */
@@ -663,7 +943,7 @@
g_mutex_unlock (g_atomic_mutex);
}
#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
-#elif defined (G_ATOMIC_OP_MEMORY_BARRIER_NEEDED)
+#elif (defined(G_ATOMIC_OP_MEMORY_BARRIER_NEEDED) && !defined(G_ATOMIC_ARM))
gint
g_atomic_int_get (volatile gint *atomic)
{
- Previous message: [maemo-commits] r14936 - in projects/haf/trunk/glib: glib gthread
- Next message: [maemo-commits] r14938 - projects/haf/tags/glib2.0
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
