diff options
Diffstat (limited to 'libpthread/linuxthreads/sysdeps/arm')
-rw-r--r-- | libpthread/linuxthreads/sysdeps/arm/pspinlock.c | 82 | ||||
-rw-r--r-- | libpthread/linuxthreads/sysdeps/arm/pt-machine.h | 57 | ||||
-rw-r--r-- | libpthread/linuxthreads/sysdeps/arm/sysdep-cancel.h | 8 | ||||
-rw-r--r-- | libpthread/linuxthreads/sysdeps/arm/sysdep.h | 137 | ||||
-rw-r--r-- | libpthread/linuxthreads/sysdeps/arm/tls.h | 172 |
5 files changed, 48 insertions, 408 deletions
diff --git a/libpthread/linuxthreads/sysdeps/arm/pspinlock.c b/libpthread/linuxthreads/sysdeps/arm/pspinlock.c deleted file mode 100644 index 9deb0b1b1..000000000 --- a/libpthread/linuxthreads/sysdeps/arm/pspinlock.c +++ /dev/null @@ -1,82 +0,0 @@ -/* POSIX spinlock implementation. Arm version. - Copyright (C) 2000 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; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include <errno.h> -#include <pthread.h> -#include "internals.h" - - -int -__pthread_spin_lock (pthread_spinlock_t *lock) -{ - unsigned int val; - - do - __asm__ __volatile__ ("swp %0, %1, [%2]" - : "=r" (val) - : "0" (1), "r" (lock) - : "memory"); - while (val != 0); - - return 0; -} -weak_alias (__pthread_spin_lock, pthread_spin_lock) - - -int -__pthread_spin_trylock (pthread_spinlock_t *lock) -{ - unsigned int val; - - __asm__ __volatile__ ("swp %0, %1, [%2]" - : "=r" (val) - : "0" (1), "r" (lock) - : "memory"); - - return val ? EBUSY : 0; -} -weak_alias (__pthread_spin_trylock, pthread_spin_trylock) - - -int -__pthread_spin_unlock (pthread_spinlock_t *lock) -{ - return *lock = 0; -} -weak_alias (__pthread_spin_unlock, pthread_spin_unlock) - - -int -__pthread_spin_init (pthread_spinlock_t *lock, int pshared) -{ - /* We can ignore the `pshared' parameter. Since we are busy-waiting - all processes which can access the memory location `lock' points - to can use the spinlock. */ - return *lock = 0; -} -weak_alias (__pthread_spin_init, pthread_spin_init) - - -int -__pthread_spin_destroy (pthread_spinlock_t *lock) -{ - /* Nothing to do. */ - return 0; -} -weak_alias (__pthread_spin_destroy, pthread_spin_destroy) 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. */ diff --git a/libpthread/linuxthreads/sysdeps/arm/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/arm/sysdep-cancel.h deleted file mode 100644 index ba6a1e04b..000000000 --- a/libpthread/linuxthreads/sysdeps/arm/sysdep-cancel.h +++ /dev/null @@ -1,8 +0,0 @@ -#include <sysdep.h> - -/* No multi-thread handling enabled. */ -#define SINGLE_THREAD_P (1) -#define RTLD_SINGLE_THREAD_P (1) -#define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */ -#define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */ -#define LIBC_CANCEL_HANDLED() /* Nothing. */ diff --git a/libpthread/linuxthreads/sysdeps/arm/sysdep.h b/libpthread/linuxthreads/sysdeps/arm/sysdep.h deleted file mode 100644 index 15d951c77..000000000 --- a/libpthread/linuxthreads/sysdeps/arm/sysdep.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Generic asm macros used on many machines. - Copyright (C) 1991,92,93,96,98,2002,2003 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. */ - -#ifndef C_LABEL - -/* Define a macro we can use to construct the asm name for a C symbol. */ -#ifdef NO_UNDERSCORES -#ifdef __STDC__ -#define C_LABEL(name) name##: -#else -#define C_LABEL(name) name/**/: -#endif -#else -#ifdef __STDC__ -#define C_LABEL(name) _##name##: -#else -#define C_LABEL(name) _/**/name/**/: -#endif -#endif - -#endif - -#ifdef __ASSEMBLER__ -/* Mark the end of function named SYM. This is used on some platforms - to generate correct debugging information. */ -#ifndef END -#define END(sym) -#endif - -#ifndef JUMPTARGET -#define JUMPTARGET(sym) sym -#endif - -/* Makros to generate eh_frame unwind information. */ -# ifdef HAVE_ASM_CFI_DIRECTIVES -# define cfi_startproc .cfi_startproc -# define cfi_endproc .cfi_endproc -# define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off -# define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg -# define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off -# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off -# define cfi_offset(reg, off) .cfi_offset reg, off -# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off -# define cfi_register(r1, r2) .cfi_register r1, r2 -# define cfi_return_column(reg) .cfi_return_column reg -# define cfi_restore(reg) .cfi_restore reg -# define cfi_same_value(reg) .cfi_same_value reg -# define cfi_undefined(reg) .cfi_undefined reg -# define cfi_remember_state .cfi_remember_state -# define cfi_restore_state .cfi_restore_state -# define cfi_window_save .cfi_window_save -# else -# define cfi_startproc -# define cfi_endproc -# define cfi_def_cfa(reg, off) -# define cfi_def_cfa_register(reg) -# define cfi_def_cfa_offset(off) -# define cfi_adjust_cfa_offset(off) -# define cfi_offset(reg, off) -# define cfi_rel_offset(reg, off) -# define cfi_register(r1, r2) -# define cfi_return_column(reg) -# define cfi_restore(reg) -# define cfi_same_value(reg) -# define cfi_undefined(reg) -# define cfi_remember_state -# define cfi_restore_state -# define cfi_window_save -# endif - -#else /* ! ASSEMBLER */ -# ifdef HAVE_ASM_CFI_DIRECTIVES -# define CFI_STRINGIFY(Name) CFI_STRINGIFY2 (Name) -# define CFI_STRINGIFY2(Name) #Name -# define CFI_STARTPROC ".cfi_startproc" -# define CFI_ENDPROC ".cfi_endproc" -# define CFI_DEF_CFA(reg, off) \ - ".cfi_def_cfa " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) -# define CFI_DEF_CFA_REGISTER(reg) \ - ".cfi_def_cfa_register " CFI_STRINGIFY(reg) -# define CFI_DEF_CFA_OFFSET(off) \ - ".cfi_def_cfa_offset " CFI_STRINGIFY(off) -# define CFI_ADJUST_CFA_OFFSET(off) \ - ".cfi_adjust_cfa_offset " CFI_STRINGIFY(off) -# define CFI_OFFSET(reg, off) \ - ".cfi_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) -# define CFI_REL_OFFSET(reg, off) \ - ".cfi_rel_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) -# define CFI_REGISTER(r1, r2) \ - ".cfi_register " CFI_STRINGIFY(r1) "," CFI_STRINGIFY(r2) -# define CFI_RETURN_COLUMN(reg) \ - ".cfi_return_column " CFI_STRINGIFY(reg) -# define CFI_RESTORE(reg) \ - ".cfi_restore " CFI_STRINGIFY(reg) -# define CFI_UNDEFINED(reg) \ - ".cfi_undefined " CFI_STRINGIFY(reg) -# define CFI_REMEMBER_STATE \ - ".cfi_remember_state" -# define CFI_RESTORE_STATE \ - ".cfi_restore_state" -# define CFI_WINDOW_SAVE \ - ".cfi_window_save" -# else -# define CFI_STARTPROC -# define CFI_ENDPROC -# define CFI_DEF_CFA(reg, off) -# define CFI_DEF_CFA_REGISTER(reg) -# define CFI_DEF_CFA_OFFSET(off) -# define CFI_ADJUST_CFA_OFFSET(off) -# define CFI_OFFSET(reg, off) -# define CFI_REL_OFFSET(reg, off) -# define CFI_REGISTER(r1, r2) -# define CFI_RETURN_COLUMN(reg) -# define CFI_RESTORE(reg) -# define CFI_UNDEFINED(reg) -# define CFI_REMEMBER_STATE -# define CFI_RESTORE_STATE -# define CFI_WINDOW_SAVE -# endif - -#endif /* __ASSEMBLER__ */ diff --git a/libpthread/linuxthreads/sysdeps/arm/tls.h b/libpthread/linuxthreads/sysdeps/arm/tls.h deleted file mode 100644 index 8057a5413..000000000 --- a/libpthread/linuxthreads/sysdeps/arm/tls.h +++ /dev/null @@ -1,172 +0,0 @@ -/* Definitions for thread-local data handling. linuxthreads/ARM version. - Copyright (C) 2004 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. */ - -#ifndef _TLS_H -#define _TLS_H - -#ifndef __ASSEMBLER__ - -# include <stdbool.h> -# include <pt-machine.h> -# include <stddef.h> - -/* Type for the dtv. */ -typedef union dtv -{ - size_t counter; - struct - { - void *val; - bool is_static; - } pointer; -} dtv_t; - -typedef struct -{ - dtv_t *dtv; - - /* Reserved for the thread implementation. Unused in LinuxThreads. */ - void *private; -} tcbhead_t; -#endif - - -/* We can support TLS only if the floating-stack support is available. - However, we want to compile in the support and test at runtime whether - the running kernel can support it or not. To avoid bothering with the - TLS support code at all, use configure --without-tls. - - We need USE_TLS to be consistently defined, for ldsodefs.h conditionals. - But some of the code below can cause problems in building libpthread - (e.g. useldt.h will defined FLOATING_STACKS when it shouldn't). */ - -/* LinuxThreads can only support TLS if both floating stacks and support - from the tools are available. - - We have to define USE_TLS consistently, or ldsodefs.h will lay out types - differently between an NPTL build and a LinuxThreads build. It can be set - for libc.so and not libpthread.so, but only if we provide appropriate padding - in the _pthread_descr_struct. - - Currently nothing defines FLOATING_STACKS. We could assume this based on - kernel version once the TLS patches are available in kernel.org. - - To avoid bothering with the TLS support code at all, use configure - --without-tls. */ - -#if defined HAVE_TLS_SUPPORT \ - && (defined FLOATING_STACKS || !defined IS_IN_libpthread) - -/* Signal that TLS support is available. */ -# define USE_TLS 1 - -/* Include padding in _pthread_descr_struct so that libc can find p_errno, - if libpthread will only include the padding because of the !IS_IN_libpthread - check. */ -#ifndef FLOATING_STACKS -# define INCLUDE_TLS_PADDING 1 -#endif - -# ifndef __ASSEMBLER__ -/* Get system call information. */ -# include <sysdep.h> - -/* This is the size of the initial TCB. */ -# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) - -/* Alignment requirements for the initial TCB. */ -# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) - -/* This is the size of the TCB. */ -# define TLS_TCB_SIZE sizeof (tcbhead_t) - -/* Alignment requirements for the TCB. */ -# define TLS_TCB_ALIGN __alignof__ (tcbhead_t) - -/* This is the size we need before TCB. */ -# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct) - -/* The DTV is allocated at the TP; the TCB is placed elsewhere. */ -# define TLS_DTV_AT_TP 1 - -/* Install the dtv pointer. The pointer passed is to the element with - index -1 which contain the length. */ -# define INSTALL_DTV(TCBP, DTVP) \ - (((tcbhead_t *) (TCBP))->dtv = (DTVP) + 1) - -/* Install new dtv for current thread. */ -# define INSTALL_NEW_DTV(DTV) \ - (((tcbhead_t *)__builtin_thread_pointer ())->dtv = (DTV)) - -/* Return dtv of given thread descriptor. */ -# define GET_DTV(TCBP) \ - (((tcbhead_t *) (TCBP))->dtv) - -/* Code to initially initialize the thread pointer. This might need - special attention since 'errno' is not yet available and if the - operation can cause a failure 'errno' must not be touched. */ -# define TLS_INIT_TP(TCBP, SECONDCALL) \ - ({ INTERNAL_SYSCALL_DECL (err); \ - long result_var; \ - result_var = INTERNAL_SYSCALL_ARM (set_tls, err, 1, (TCBP)); \ - INTERNAL_SYSCALL_ERROR_P (result_var, err) \ - ? "unknown error" : NULL; }) - -/* Return the address of the dtv for the current thread. */ -# define THREAD_DTV() \ - (((tcbhead_t *)__builtin_thread_pointer ())->dtv) - -/* Return the thread descriptor for the current thread. */ -# undef THREAD_SELF -# define THREAD_SELF \ - ((pthread_descr)__builtin_thread_pointer () - 1) - -# undef INIT_THREAD_SELF -# define INIT_THREAD_SELF(DESCR, NR) \ - TLS_INIT_TP ((struct _pthread_descr_struct *)(DESCR) + 1, 0) - -/* Get the thread descriptor definition. */ -# include <linuxthreads/descr.h> - -/* ??? Generic bits of LinuxThreads may call these macros with - DESCR set to NULL. We are expected to be able to reference - the "current" value. - - In our case, we'd really prefer to use DESCR, since lots of - PAL_code calls would be expensive. We can only trust that - the compiler does its job and unifies the multiple - __builtin_thread_pointer instances. */ - -#define THREAD_GETMEM(descr, member) \ - ((void) sizeof (descr), THREAD_SELF->member) -#define THREAD_GETMEM_NC(descr, member) \ - ((void) sizeof (descr), THREAD_SELF->member) -#define THREAD_SETMEM(descr, member, value) \ - ((void) sizeof (descr), THREAD_SELF->member = (value)) -#define THREAD_SETMEM_NC(descr, member, value) \ - ((void) sizeof (descr), THREAD_SELF->member = (value)) - -/* Initializing the thread pointer will generate a SIGILL if the syscall - is not available. */ -#define TLS_INIT_TP_EXPENSIVE 1 - -# endif /* HAVE_TLS_SUPPORT */ -#endif /* __ASSEMBLER__ */ - -#endif /* tls.h */ |