diff options
Diffstat (limited to 'libpthread/linuxthreads/sysdeps/ia64')
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/ia64/CVS/Entries | 7 | ||||
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/ia64/CVS/Repository | 1 | ||||
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/ia64/CVS/Root | 1 | ||||
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/ia64/pspinlock.c | 79 | ||||
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/ia64/pt-machine.h | 133 | ||||
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/ia64/tcb-offsets.sym | 9 | ||||
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/ia64/tls.h | 145 | 
7 files changed, 375 insertions, 0 deletions
diff --git a/libpthread/linuxthreads/sysdeps/ia64/CVS/Entries b/libpthread/linuxthreads/sysdeps/ia64/CVS/Entries new file mode 100644 index 000000000..a259a3611 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/ia64/CVS/Entries @@ -0,0 +1,7 @@ +/Makefile/1.1/Tue Nov 15 14:20:47 2005// +/Versions/1.2/Tue Nov 15 14:20:47 2005// +/pspinlock.c/1.5/Tue Nov 15 14:20:47 2005// +/pt-machine.h/1.15/Tue Nov 15 14:20:47 2005// +/tcb-offsets.sym/1.6/Tue Nov 15 14:20:47 2005// +/tls.h/1.10/Wed Nov 16 19:58:55 2005// +D diff --git a/libpthread/linuxthreads/sysdeps/ia64/CVS/Repository b/libpthread/linuxthreads/sysdeps/ia64/CVS/Repository new file mode 100644 index 000000000..24c4c03c9 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/ia64/CVS/Repository @@ -0,0 +1 @@ +ports/linuxthreads/sysdeps/ia64 diff --git a/libpthread/linuxthreads/sysdeps/ia64/CVS/Root b/libpthread/linuxthreads/sysdeps/ia64/CVS/Root new file mode 100644 index 000000000..ca45c5d4d --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/ia64/CVS/Root @@ -0,0 +1 @@ +:pserver:anoncvs@sources.redhat.com:/cvs/glibc diff --git a/libpthread/linuxthreads/sysdeps/ia64/pspinlock.c b/libpthread/linuxthreads/sysdeps/ia64/pspinlock.c new file mode 100644 index 000000000..d61aa3f43 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/ia64/pspinlock.c @@ -0,0 +1,79 @@ +/* POSIX spinlock implementation.  ia64 version. +   Copyright (C) 2000, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jes Sorensen <jes@linuxcare.com> + +   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" +#include <ia64intrin.h> + +/* This implementation is inspired by the implementation used in the +   Linux kernel. */ + +int +__pthread_spin_lock (pthread_spinlock_t *lock) +{ +  int *p = (int *) lock; +   +  while (__builtin_expect (__sync_val_compare_and_swap (p, 0, 1), 0)) +    { +      /* Spin without using the atomic instruction.  */ +      do +        __asm __volatile ("" : : : "memory"); +      while (*p); +    } +  return 0; +} +weak_alias (__pthread_spin_lock, pthread_spin_lock) + + +int +__pthread_spin_trylock (pthread_spinlock_t *lock) +{ +  return __sync_val_compare_and_swap ((int *) lock, 0, 1) == 0 ? 0 : EBUSY; +} +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/ia64/pt-machine.h b/libpthread/linuxthreads/sysdeps/ia64/pt-machine.h new file mode 100644 index 000000000..6c5dfe93b --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/ia64/pt-machine.h @@ -0,0 +1,133 @@ +/* Machine-dependent pthreads configuration and inline functions. +   IA-64 version. +   Copyright (C) 1999, 2000, 2002, 2003, 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; see the file COPYING.LIB.  If not, +   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +   Boston, MA 02111-1307, USA.  */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H   1 + +#include <ia64intrin.h> + +#ifndef PT_EI +# define PT_EI extern inline __attribute__ ((always_inline)) +#endif + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long int *p, long int oldval, long int newval); + +/* Make sure gcc doesn't try to be clever and move things around on +   us. We need to use _exactly_ the address the user gave us, not some +   alias that contains the same information.  */ +#define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x) + +#ifndef ELF_MACHINE_NAME + +#define NEED_SEPARATE_REGISTER_STACK + +/* We want the OS to assign stack addresses.  */ +#define FLOATING_STACKS 1 + +/* Maximum size of the stack if the rlimit is unlimited.  */ +#define ARCH_STACK_MAX_SIZE     32*1024*1024 + +/* Get some notion of the current stack.  Need not be exactly the top +   of the stack, just something somewhere in the current frame. +   r12 (sp) is the stack pointer. */ +#define CURRENT_STACK_FRAME  stack_pointer +register char *stack_pointer __asm__ ("sp"); + + +/* Register r13 (tp) is reserved by the ABI as "thread pointer". */ +struct _pthread_descr_struct; +register struct _pthread_descr_struct *__thread_self __asm__("r13"); + +/* Return the thread descriptor for the current thread.  */ +#define THREAD_SELF  __thread_self + +/* Initialize the thread-unique value.  */ +#define INIT_THREAD_SELF(descr, nr)  (__thread_self = (descr)) + + +/* Access to data in the thread descriptor is easy.  */ +#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)) + + +/* Memory barrier */ +#define MEMORY_BARRIER() __sync_synchronize () + + +#define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS + +PT_EI int +__compare_and_swap (long int *p, long int oldval, long int newval) +{ +  long int readval; + +  __asm__ __volatile__ +       ("mov ar.ccv=%4;;\n\t" +	"cmpxchg8.acq %0=%1,%2,ar.ccv" +	: "=r" (readval), "=m" (__atomic_fool_gcc (p)) +	: "r"(newval), "m" (__atomic_fool_gcc (p)), "r" (oldval) +	: "memory"); +  return readval == oldval; +} + +PT_EI int +__compare_and_swap_with_release_semantics (long int *p, +					   long int oldval, +					   long int newval) +{ +  long int readval; + +  __asm__ __volatile__ +       ("mov ar.ccv=%4;;\n\t" +	"cmpxchg8.rel %0=%1,%2,ar.ccv" +	: "=r" (readval), "=m" (__atomic_fool_gcc (p)) +	: "r"(newval), "m" (__atomic_fool_gcc (p)), "r" (oldval) +	: "memory"); +  return readval == oldval; +} + +#endif /* ELF_MACHINE_NAME */ + +/* Spinlock implementation; required.  */ +PT_EI long int +testandset (int *spinlock) +{ +  long int ret; + +  __asm__ __volatile__( +       "xchg4 %0=%1,%2" +       : "=r"(ret), "=m"(__atomic_fool_gcc (spinlock)) +       : "r"(1), "m"(__atomic_fool_gcc (spinlock)) +       : "memory"); + +  return ret; +} + +/* Indicate that we are looping.  */ +#define BUSY_WAIT_NOP	__asm__ ("hint @pause") + +#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads/sysdeps/ia64/tcb-offsets.sym b/libpthread/linuxthreads/sysdeps/ia64/tcb-offsets.sym new file mode 100644 index 000000000..f7793f766 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/ia64/tcb-offsets.sym @@ -0,0 +1,9 @@ +#include <sysdep.h> +#include <tls.h> + +-- +#ifdef USE_TLS +MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads) - sizeof (struct _pthread_descr_struct) +#else +MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) +#endif diff --git a/libpthread/linuxthreads/sysdeps/ia64/tls.h b/libpthread/linuxthreads/sysdeps/ia64/tls.h new file mode 100644 index 000000000..0311a9ccb --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/ia64/tls.h @@ -0,0 +1,145 @@ +/* Definitions for thread-local data handling.  linuxthreads/IA-64 version. +   Copyright (C) 2002, 2003, 2004, 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.  */ + +#ifndef _TLS_H +#define _TLS_H + +#ifndef __ASSEMBLER__ + +# include <pt-machine.h> +# include <stdbool.h> +# include <stddef.h> + +/* Type for the dtv.  */ +typedef union dtv +{ +  size_t counter; +  struct +  { +    void *val; +    bool is_static; +  } pointer; +} dtv_t; + +#else /* __ASSEMBLER__ */ +# include <tcb-offsets.h> +#endif /* __ASSEMBLER__ */ + +#ifdef HAVE_TLS_SUPPORT + +/* Signal that TLS support is available.  */ +# define USE_TLS        1 + +# ifndef __ASSEMBLER__ + +typedef struct +{ +  dtv_t *dtv; +  void *private; +} tcbhead_t; + +/* 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) + +/* This is the size we need before TCB.  */ +#  define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct) + +/* Alignment requirements for the TCB.  */ +#  define TLS_TCB_ALIGN __alignof__ (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 *)__thread_self)->dtv = (DTV)) + +/* Return dtv of given thread descriptor.  */ +#  define GET_DTV(tcbp) \ +  (((tcbhead_t *) (tcbp))->dtv) + +#if defined NEED_DL_SYSINFO +# define INIT_SYSINFO \ +  (((tcbhead_t *) __thread_self)->private = (void *) GLRO(dl_sysinfo)) +#else +# define INIT_SYSINFO 0 +#endif + +/* 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) \ +  (__thread_self = (__typeof (__thread_self)) (tcbp), INIT_SYSINFO, NULL) + +/* Return the address of the dtv for the current thread.  */ +#  define THREAD_DTV() \ +  (((tcbhead_t *)__thread_self)->dtv) + +/* Return the thread descriptor for the current thread.  */ +#  undef THREAD_SELF +#  define THREAD_SELF (__thread_self - 1) + +#  undef INIT_THREAD_SELF +#  define INIT_THREAD_SELF(descr, nr) \ +  (__thread_self = (struct _pthread_descr_struct *)(descr) + 1) + +# define TLS_MULTIPLE_THREADS_IN_TCB 1 + +/* Get the thread descriptor definition.  */ +#  include <linuxthreads/descr.h> + +# endif + +#else + +# ifndef __ASSEMBLER__ + +typedef struct +{ +  void *tcb; +  dtv_t *dtv; +  void *self; +  int multiple_threads; +} tcbhead_t; + +/* Get the thread descriptor definition.  */ +#  include <linuxthreads/descr.h> + +#  define NONTLS_INIT_TP \ +  do { 									\ +    static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 };	\ +    __thread_self = (__typeof (__thread_self)) &nontls_init_tp;		\ +  } while (0) + +#endif + +#endif /* USE_TLS */ + +#endif	/* tls.h */  | 
