diff options
Diffstat (limited to 'libpthread/linuxthreads/sysdeps/arm/pt-machine.h')
-rw-r--r-- | libpthread/linuxthreads/sysdeps/arm/pt-machine.h | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/libpthread/linuxthreads/sysdeps/arm/pt-machine.h b/libpthread/linuxthreads/sysdeps/arm/pt-machine.h index 9ffc8bdc4..3250961cf 100644 --- a/libpthread/linuxthreads/sysdeps/arm/pt-machine.h +++ b/libpthread/linuxthreads/sysdeps/arm/pt-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent pthreads configuration and inline functions. ARM version. - Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Philip Blundell <philb@gnu.org>. @@ -15,36 +15,75 @@ 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; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 -#include <features.h> +#include <sys/syscall.h> +#include <unistd.h> #ifndef PT_EI # define PT_EI __extern_always_inline #endif +#if __ARM_ARCH >= 7 || defined(__thumb2__) +/* Spinlock implementation; required. */ +PT_EI long int +testandset (int *spinlock) +{ + unsigned int ret, tmp, val = 1; + + __asm__ __volatile__ ( +"0: ldrex %0, [%2] \n" +" strex %1, %3, [%2] \n" +" cmp %1, #0 \n" +" bne 0b" + : "=&r" (ret), "=&r" (tmp) + : "r" (spinlock), "r" (val) : "memory", "cc"); + + return ret; +} + +#elif defined(__thumb__) + /* This will not work on ARM1 or ARM2 because SWP is lacking on those machines. Unfortunately we have no way to detect this at compile time; let's hope nobody tries to use one. */ /* Spinlock implementation; required. */ -PT_EI long int -testandset (int *spinlock) +PT_EI long int testandset (int *spinlock); +PT_EI long int testandset (int *spinlock) { register unsigned int ret; + void *pc; + __asm__ __volatile__( + ".align 0\n" + "\tbx pc\n" + "\tnop\n" + "\t.arm\n" + "\tswp %0, %2, [%3]\n" + "\torr %1, pc, #1\n" + "\tbx %1\n" + "\t.force_thumb" + : "=r"(ret), "=r"(pc) + : "0"(1), "r"(spinlock)); + return ret; +} + +#else /* __thumb__ */ +PT_EI long int testandset (int *spinlock); +PT_EI long int testandset (int *spinlock) +{ + register unsigned int ret; __asm__ __volatile__("swp %0, %1, [%2]" : "=r"(ret) : "0"(1), "r"(spinlock)); - return ret; } - +#endif /* Get some notion of the current stack. Need not be exactly the top of the stack, just something somewhere in the current frame. */ |