[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: arm eabi port, patches



On Wed, Jan 10, 2007 at 08:12:48PM +0100, Lennert Buytenhek wrote:
> Is that something you can share?  I have some dual-core Intel h/w I'd
> like to try this on.  The xsc3 core doesn't implement all of the v6 ISA
> (v5te only), but does have the standard set of ARMv6 memory barriers.
> 
> [ In theory the two xsc3 cores in this CPU aren't cache coherent but
>   I'd like to try it anyway. ]

You'll have plenty of other trouble... but sure, here you go.  This
version is rather suboptimal; it goes to a lot of trouble using swp
based locking, but in turn implements the swp primitive with the
kernel cmpxchg helper, and the result has about twice the memory
cycles that it ought to.

Enjoy, no warranty.

-- 
Daniel Jacobowitz
CodeSourcery

Index: B_csl_arm/ChangeLog.csl
===================================================================
--- B_csl_arm/ChangeLog.csl	(revision 131127)
+++ B_csl_arm/ChangeLog.csl	(revision 131128)
@@ -1,3 +1,11 @@
+2006-05-02  Paul Brook  <paul@codesourcery.com>
+
+	* nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h (lll_mutex_trylock,
+	lll_mutex_cond_trylock): Use atomic_compare_and_exchange_val_acq.
+	* nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h (atomic_exchange_acq):
+	Disable on SMP.
+	(atomic_full_barrier): Define.
+
 2006-03-24  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* sysdeps/unix/sysv/linux/arm/eabi/socket.S: Delete.
Index: B_csl_arm/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h
===================================================================
--- B_csl_arm/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h	(revision 131127)
+++ B_csl_arm/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h	(revision 131128)
@@ -37,6 +37,10 @@ typedef uintmax_t uatomic_max_t;
 
 void __arm_link_error (void);
 
+#ifdef UP
+
+/* We require kernel assisted barriers for SMP safety, so it is only worth
+   defining this on UP.  */
 #define atomic_exchange_acq(mem, newvalue)				      \
   ({ __typeof (*mem) result;						      \
      if (sizeof (*mem) == 1)						      \
@@ -54,6 +58,17 @@ void __arm_link_error (void);
        }								      \
      result; })
 
+#else
+
+#define atomic_full_barrier() \
+     __asm__ __volatile__						      \
+	     ("mov\tip, #0xffff0fff\n\t"				      \
+	      "mov\tlr, pc\n\t"						      \
+	      "add\tpc, ip, #(0xffff0fa0 - 0xffff0fff)"			      \
+	      : : : "ip", "lr", "cc", "memory");
+
+#endif
+
 /* Atomic compare and exchange.  This sequence relies on the kernel to
    provide a compare and exchange operation which is atomic on the
    current architecture, either via cleverness on pre-ARMv6 or via
Index: B_csl_arm/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h
===================================================================
--- B_csl_arm/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h	(revision 131127)
+++ B_csl_arm/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h	(revision 131128)
@@ -72,43 +72,11 @@
   })
 
 
-static inline int __attribute__((always_inline))
-__lll_mutex_trylock (int *futex)
-{
-  int flag = 1, old;
-  asm volatile (
-    "\tswp	%[old], %[flag], [%[futex]]	@ try to take the lock\n"
-    "\tcmp	%[old], #1			@ check old lock value\n"
-    "\tmovlo	%[flag], #0			@ if we got it, return 0\n"
-    "\tswphi	%[flag], %[old], [%[futex]]	@ if it was contested,\n"
-    "						@ restore the contested flag,\n"
-    "						@ and check whether that won."
-    : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old)
-    : : "memory" );
-
-  return flag;
-}
-#define lll_mutex_trylock(lock)	__lll_mutex_trylock (&(lock))
-
-
-static inline int __attribute__((always_inline))
-__lll_mutex_cond_trylock (int *futex)
-{
-  int flag = 2, old;
-  asm volatile (
-    "\tswp	%[old], %[flag], [%[futex]]	@ try to take the lock\n"
-    "\tcmp	%[old], #1			@ check old lock value\n"
-    "\tmovlo	%[flag], #0			@ if we got it, return 0\n"
-    "\tswphi	%[flag], %[old], [%[futex]]	@ if it was contested,\n"
-    "						@ restore the contested flag,\n"
-    "						@ and check whether that won."
-    : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old)
-    : : "memory" );
-
-  return flag;
-}
-#define lll_mutex_cond_trylock(lock)	__lll_mutex_cond_trylock (&(lock))
+#define lll_mutex_trylock(lock)	\
+  atomic_compare_and_exchange_val_acq(&(lock), 1, 0)
 
+#define lll_mutex_cond_trylock(lock)	\
+  atomic_compare_and_exchange_val_acq(&(lock), 2, 0)
 
 extern void __lll_mutex_lock_outlined (int *futex) attribute_hidden;
 



Reply to: