This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ARM: avoid use of swp instruction in pthread locking


The 'swp' instruction should be avoided - it is deprecated in ARMv6 and
very slow on modern CPUs.  The Linux kernel provides helper routines
that execute the ideal code sequence for locking on the current
processor, and glibc already has code, in the Linux/NPTL version of
<atomic.h>, to use those helpers.  This patch makes atomic.h use them
unconditionally (it preferred 'swp' in uniprocessor configuration) and
updates two places that were using hand-rolled assembly instead of
<atomic.h>.

zw

* sysdeps/arm/nptl/pthread_spin_lock.S
* sysdeps/arm/nptl/pthread_spin_trylock.S: Delete.
* sysdeps/arm/nptl/pthread_spin_lock.c
* sysdeps/arm/nptl/pthread_spin_trylock.c: New files using <atomic.h>
primitives to take spinlocks.
* sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h: Use kernel helpers
unconditionally.


Index: sysdeps/arm/nptl/pthread_spin_trylock.S
===================================================================
--- sysdeps/arm/nptl/pthread_spin_trylock.S	(revision 176329)
+++ sysdeps/arm/nptl/pthread_spin_trylock.S	(working copy)
@@ -1,34 +0,0 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C 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.
-
-   The GNU C 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 the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#define _ERRNO_H 1
-#include <bits/errno.h>
-
-#include <sysdep.h>
-
-	.text
-	.align	4
-
-ENTRY (pthread_spin_trylock)
-	mov	r1, #1
-	swp	r2, r1, [r0]
-	teq	r2, #0
-	moveq	r0, #0
-	movne	r0, #EBUSY
-	PSEUDO_RET_NOERRNO
-END (pthread_spin_trylock)
Index: sysdeps/arm/nptl/pthread_spin_trylock.c
===================================================================
--- sysdeps/arm/nptl/pthread_spin_trylock.c	(revision 0)
+++ sysdeps/arm/nptl/pthread_spin_trylock.c	(revision 0)
@@ -0,0 +1,27 @@
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <atomic.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  return atomic_compare_and_exchange_val_acq(lock, 1, 0) ? EBUSY : 0;
+}
Index: sysdeps/arm/nptl/pthread_spin_lock.S
===================================================================
--- sysdeps/arm/nptl/pthread_spin_lock.S	(revision 176329)
+++ sysdeps/arm/nptl/pthread_spin_lock.S	(working copy)
@@ -1,31 +0,0 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C 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.
-
-   The GNU C 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 the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <sysdep.h>
-
-	.text
-	.align	4
-
-ENTRY (pthread_spin_lock)
-	mov	r1, #1
-1:	swp	r2, r1, [r0]
-	teq	r2, #0
-	bne	1b
-	mov	r0, #0
-	PSEUDO_RET_NOERRNO
-END (pthread_spin_lock)
Index: sysdeps/arm/nptl/pthread_spin_lock.c
===================================================================
--- sysdeps/arm/nptl/pthread_spin_lock.c	(revision 0)
+++ sysdeps/arm/nptl/pthread_spin_lock.c	(revision 0)
@@ -0,0 +1,30 @@
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <atomic.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  while (atomic_compare_and_exchange_val_acq(lock, 1, 0) != 0)
+   while (*lock != 0)
+    ;
+
+  return 0;
+}
Index: sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
===================================================================
--- sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h	(revision 176329)
+++ sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h	(working copy)
@@ -37,29 +37,6 @@
 
 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)						      \
-       __asm__ __volatile__ ("swpb %0, %1, [%2]"			      \
-			     : "=&r,&r" (result)			      \
-			     : "r,0" (newvalue), "r,r" (mem) : "memory");     \
-     else if (sizeof (*mem) == 4)					      \
-       __asm__ __volatile__ ("swp %0, %1, [%2]"				      \
-			     : "=&r,&r" (result)			      \
-			     : "r,0" (newvalue), "r,r" (mem) : "memory");     \
-     else								      \
-       {								      \
-	 result = 0;							      \
-	 abort ();							      \
-       }								      \
-     result; })
-
-#else
-
 #ifdef __thumb2__
 #define atomic_full_barrier() \
      __asm__ __volatile__						      \
@@ -76,8 +53,6 @@
 	      : : : "ip", "lr", "cc", "memory");
 #endif
 
-#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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]