diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sparc')
30 files changed, 1473 insertions, 0 deletions
| diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile new file mode 100644 index 000000000..43a6fad84 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile @@ -0,0 +1,13 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +top_srcdir=../../../../../../../ +top_builddir=../../../../../../../ +all: objs +include $(top_builddir)Rules.mak +include Makefile.arch +include $(top_srcdir)Makerules diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch new file mode 100644 index 000000000..b54731075 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch @@ -0,0 +1,66 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +libpthread_SSRC = pt-vfork.S clone.S +libpthread_CSRC = pthread_once.c lowlevellock.c + +libc_a_CSRC = fork.c libc-lowlevellock.c +libc_a_SSRC = clone.S vfork.S + +CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 +CFLAGS-OMIT-libc-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 + +ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y) +CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__ +endif + +ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD + +CFLAGS-pthread_once.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 +CFLAGS-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 + + +ASFLAGS-clone.S = -D_LIBC_REENTRANT +ASFLAGS-vfork.S = -D_LIBC_REENTRANT + +ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) +#Needed to use the correct SYSCALL_ERROR_HANDLER +ASFLAGS-clone.S += -DUSE___THREAD +ASFLAGS-vfork.S += -DUSE___THREAD +ASFLAGS-pt-vfork.S += -DUSE___THREAD +endif + +CFLAGS += $(SSP_ALL_CFLAGS) +#CFLAGS:=$(CFLAGS:-O1=-O2) + +LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/sparc +LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/sparc + +LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC)) +LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC)) + +ifeq ($(DOPIC),y) +libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os) +else +libpthread-a-y += $(LINUX_ARCH_OBJ) +endif +libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS) + +libpthread-nomulti-y+=$(LINUX_ARCH_OBJS) + +LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC)) +LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC)) + +libc-static-y+=$(LIBC_LINUX_ARCH_OBJ) +libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS) + +libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ) + +objclean-y+=nptl_linux_arch_clean + +nptl_linux_arch_clean: +	$(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions new file mode 100644 index 000000000..d10277248 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions @@ -0,0 +1,6 @@ +libpthread { +  GLIBC_2.3.3 { +    # Changed PTHREAD_STACK_MIN. +    pthread_attr_setstack; pthread_attr_setstacksize; +  } +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h new file mode 100644 index 000000000..e082ea8f0 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h @@ -0,0 +1,89 @@ +/* Minimum guaranteed maximum values for system limits.  Linux/SPARC version. +   Copyright (C) 1993-1998,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 Library General Public License as +   published by the Free Software Foundation; either version 2 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 +   Library General Public License for more details. + +   You should have received a copy of the GNU Library 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.  */ + +/* The kernel header pollutes the namespace with the NR_OPEN symbol +   and defines LINK_MAX although filesystems have different maxima.  A +   similar thing is true for OPEN_MAX: the limit can be changed at +   runtime and therefore the macro must not be defined.  Remove this +   after including the header if necessary.  */ +#ifndef NR_OPEN +# define __undef_NR_OPEN +#endif +#ifndef LINK_MAX +# define __undef_LINK_MAX +#endif +#ifndef OPEN_MAX +# define __undef_OPEN_MAX +#endif + +/* The kernel sources contain a file with all the needed information.  */ +#include <linux/limits.h> + +/* Have to remove NR_OPEN?  */ +#ifdef __undef_NR_OPEN +# undef NR_OPEN +# undef __undef_NR_OPEN +#endif +/* Have to remove LINK_MAX?  */ +#ifdef __undef_LINK_MAX +# undef LINK_MAX +# undef __undef_LINK_MAX +#endif +/* Have to remove OPEN_MAX?  */ +#ifdef __undef_OPEN_MAX +# undef OPEN_MAX +# undef __undef_OPEN_MAX +#endif + +/* The number of data keys per process.  */ +#define _POSIX_THREAD_KEYS_MAX	128 +/* This is the value this implementation supports.  */ +#define PTHREAD_KEYS_MAX	1024 + +/* Controlling the iterations of destructors for thread-specific data.  */ +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4 +/* Number of iterations this implementation does.  */ +#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS + +/* The number of threads per process.  */ +#define _POSIX_THREAD_THREADS_MAX	64 +/* We have no predefined limit on the number of threads.  */ +#undef PTHREAD_THREADS_MAX + +/* Maximum amount by which a process can descrease its asynchronous I/O +   priority level.  */ +#define AIO_PRIO_DELTA_MAX	20 + +/* Minimum size for a thread.  We are free to choose a reasonable value.  */ +#define PTHREAD_STACK_MIN	24576 + +/* Maximum number of timer expiration overruns.  */ +#define DELAYTIMER_MAX	2147483647 + +/* Maximum tty name length.  */ +#define TTY_NAME_MAX		32 + +/* Maximum login name length.  This is arbitrary.  */ +#define LOGIN_NAME_MAX		256 + +/* Maximum host name length.  */ +#define HOST_NAME_MAX		64 + +/* Maximum message queue priority level.  */ +#define MQ_PRIO_MAX		32768 diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h new file mode 100644 index 000000000..459d1ca79 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h @@ -0,0 +1,218 @@ +/* Machine-specific pthread type layouts.  SPARC version. +   Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + +   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 _BITS_PTHREADTYPES_H +#define _BITS_PTHREADTYPES_H	1 + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 +# define __SIZEOF_PTHREAD_ATTR_T 56 +# define __SIZEOF_PTHREAD_MUTEX_T 40 +# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +# define __SIZEOF_PTHREAD_COND_T 48 +# define __SIZEOF_PTHREAD_CONDATTR_T 4 +# define __SIZEOF_PTHREAD_RWLOCK_T 56 +# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +# define __SIZEOF_PTHREAD_BARRIER_T 32 +# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +#else +# define __SIZEOF_PTHREAD_ATTR_T 36 +# define __SIZEOF_PTHREAD_MUTEX_T 24 +# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +# define __SIZEOF_PTHREAD_COND_T 48 +# define __SIZEOF_PTHREAD_CONDATTR_T 4 +# define __SIZEOF_PTHREAD_RWLOCK_T 32 +# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +# define __SIZEOF_PTHREAD_BARRIER_T 20 +# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +#endif + + +/* Thread identifiers.  The structure of the attribute type is +   deliberately not exposed.  */ +typedef unsigned long int pthread_t; + + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_ATTR_T]; +  long int __align; +} pthread_attr_t; + + +#if __WORDSIZE == 64 +typedef struct __pthread_internal_list +{ +  struct __pthread_internal_list *__prev; +  struct __pthread_internal_list *__next; +} __pthread_list_t; +#else +typedef struct __pthread_internal_slist +{ +  struct __pthread_internal_slist *__next; +} __pthread_slist_t; +#endif + + +/* Data structures for mutex handling.  The structure of the attribute +   type is deliberately not exposed.  */ +typedef union +{ +  struct __pthread_mutex_s +  { +    int __lock; +    unsigned int __count; +    int __owner; +#if __WORDSIZE == 64 +    unsigned int __nusers; +#endif +    /* KIND must stay at this position in the structure to maintain +       binary compatibility.  */ +    int __kind; +#if __WORDSIZE == 64 +    int __spins; +    __pthread_list_t __list; +# define __PTHREAD_MUTEX_HAVE_PREV      1 +#else +    unsigned int __nusers; +    __extension__ union +    { +      int __spins; +      __pthread_slist_t __list; +    }; +#endif +  } __data; +  char __size[__SIZEOF_PTHREAD_MUTEX_T]; +  long int __align; +} pthread_mutex_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_MUTEXATTR_T]; +  int __align; +} pthread_mutexattr_t; + + +/* Data structure for conditional variable handling.  The structure of +   the attribute type is deliberately not exposed.  */ +typedef union +{ +  struct +  { +    int __lock; +    unsigned int __futex; +    __extension__ unsigned long long int __total_seq; +    __extension__ unsigned long long int __wakeup_seq; +    __extension__ unsigned long long int __woken_seq; +    void *__mutex; +    unsigned int __nwaiters; +    unsigned int __broadcast_seq; +  } __data; +  char __size[__SIZEOF_PTHREAD_COND_T]; +  __extension__ long long int __align; +} pthread_cond_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_CONDATTR_T]; +  int __align; +} pthread_condattr_t; + + +/* Keys for thread-specific data */ +typedef unsigned int pthread_key_t; + + +/* Once-only execution */ +typedef int pthread_once_t; + + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K +/* Data structure for read-write lock variable handling.  The +   structure of the attribute type is deliberately not exposed.  */ +typedef union +{ +# if __WORDSIZE == 64 +  struct +  { +    int __lock; +    unsigned int __nr_readers; +    unsigned int __readers_wakeup; +    unsigned int __writer_wakeup; +    unsigned int __nr_readers_queued; +    unsigned int __nr_writers_queued; +    int __writer; +    int __pad1; +    unsigned long int __pad2; +    unsigned long int __pad3; +    /* FLAGS must stay at this position in the structure to maintain +       binary compatibility.  */ +    unsigned int __flags; +  } __data; +# else +  struct +  { +    int __lock; +    unsigned int __nr_readers; +    unsigned int __readers_wakeup; +    unsigned int __writer_wakeup; +    unsigned int __nr_readers_queued; +    unsigned int __nr_writers_queued; +    /* FLAGS must stay at this position in the structure to maintain +       binary compatibility.  */ +    unsigned int __flags; +    int __writer; +  } __data; +# endif +  char __size[__SIZEOF_PTHREAD_RWLOCK_T]; +  long int __align; +} pthread_rwlock_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T]; +  long int __align; +} pthread_rwlockattr_t; +#endif + + +#ifdef __USE_XOPEN2K +/* POSIX spinlock data type.  */ +typedef volatile int pthread_spinlock_t; + + +/* POSIX barriers data type.  The structure of the type is +   deliberately not exposed.  */ +typedef union +{ +  char __size[__SIZEOF_PTHREAD_BARRIER_T]; +  long int __align; +} pthread_barrier_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T]; +  int __align; +} pthread_barrierattr_t; +#endif + + +#endif	/* bits/pthreadtypes.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h new file mode 100644 index 000000000..7f3a32832 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h @@ -0,0 +1,44 @@ +/* Machine-specific POSIX semaphore type layouts.  SPARC version. +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + +   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 _SEMAPHORE_H +# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead." +#endif + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 +# define __SIZEOF_SEM_T	32 +#else +# define __SIZEOF_SEM_T	16 +#endif + +/* Value returned if `sem_open' failed.  */ +#define SEM_FAILED      ((sem_t *) 0) + +/* Maximum value the semaphore can have.  */ +#define SEM_VALUE_MAX   (2147483647) + + +typedef union +{ +  char __size[__SIZEOF_SEM_T]; +  long int __align; +} sem_t; diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S new file mode 100644 index 000000000..dfc5e8261 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "./sparc64/clone.S" +#else +#include "./sparc32/clone.S" +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c new file mode 100644 index 000000000..1cd79110a --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + +   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 <sched.h> +#include <signal.h> +#include <sysdep.h> +#include <tls.h> + +#define ARCH_FORK() \ +  INLINE_CLONE_SYSCALL (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ +			0, NULL, NULL, &THREAD_SELF->tid) + +#include "../fork.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c new file mode 100644 index 000000000..b19282281 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c @@ -0,0 +1,21 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. + +   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.  */ + +/* No difference to lowlevellock.c, except we lose a couple of functions.  */ +#include "lowlevellock.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c new file mode 100644 index 000000000..e9ec4df1e --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c @@ -0,0 +1,131 @@ +/* low level locking for pthread library.  SPARC version. +   Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. + +   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 <sysdep.h> +#include <lowlevellock.h> +#include <sys/time.h> + + +/* These functions don't get included in libc.so  */ +void +__lll_lock_wait (int *futex) +{ +  do +    { +      int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); +      if (oldval != 0) +	lll_futex_wait (futex, 2); +    } +  while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); +} + + +#ifdef IS_IN_libpthread +int +__lll_timedlock_wait (int *futex, const struct timespec *abstime) +{ +  /* Reject invalid timeouts.  */ +  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) +    return EINVAL; + +  do +    { +      struct timeval tv; +      struct timespec rt; + +      /* Get the current time.  */ +      (void) gettimeofday (&tv, NULL); + +      /* Compute relative timeout.  */ +      rt.tv_sec = abstime->tv_sec - tv.tv_sec; +      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; +      if (rt.tv_nsec < 0) +	{ +	  rt.tv_nsec += 1000000000; +	  --rt.tv_sec; +	} + +      /* Already timed out?  */ +      if (rt.tv_sec < 0) +	return ETIMEDOUT; + +      /* Wait.  */ +      int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); +      if (oldval != 0) +	lll_futex_timed_wait (futex, 2, &rt); +    } +  while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); + +  return 0; +} + +int +lll_unlock_wake_cb(int* futex) +{ +    int val = atomic_exchange_24_rel(futex, 0); + +    if( __builtin_expect( val > 1, 0 ) ) { +        lll_futex_wake( futex, 1 ); +    } + +    return 0; +} + + +int +__lll_timedwait_tid (int *tidp, const struct timespec *abstime) +{ +  int tid; + +  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) +    return EINVAL; + +  /* Repeat until thread terminated.  */ +  while ((tid = *tidp) != 0) +    { +      struct timeval tv; +      struct timespec rt; + +      /* Get the current time.  */ +      (void) gettimeofday (&tv, NULL); + +      /* Compute relative timeout.  */ +      rt.tv_sec = abstime->tv_sec - tv.tv_sec; +      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; +      if (rt.tv_nsec < 0) +	{ +	  rt.tv_nsec += 1000000000; +	  --rt.tv_sec; +	} + +      /* Already timed out?  */ +      if (rt.tv_sec < 0) +	return ETIMEDOUT; + +      /* Wait until thread terminates.  The kernel so far does not use +	 the private futex operations for this.  */ +      if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT) +	return ETIMEDOUT; +    } + +  return 0; +} +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h new file mode 100644 index 000000000..4db6fb0b4 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h @@ -0,0 +1,258 @@ +/* Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + +   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 Libr	\ary; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#ifndef _LOWLEVELLOCK_H +#define _LOWLEVELLOCK_H	1 + +#include <time.h> +#include <sys/param.h> +#include <bits/pthreadtypes.h> +#include <atomic.h> +#include <sysdep.h> + + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 +#define FUTEX_REQUEUE		3 +#define FUTEX_CMP_REQUEUE	4 +#define FUTEX_WAKE_OP		5 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1) + +/* Initializer for compatibility lock.	*/ +#define LLL_MUTEX_LOCK_INITIALIZER (0) + +#define lll_futex_wait(futexp, val) \ +  lll_futex_timed_wait (futexp, val, NULL) + +#define lll_futex_timed_wait(futexp, val, timespec) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		  \ +			      FUTEX_WAIT, (val), (timespec));			      \ +    __ret;								      \ +  }) + +#define lll_futex_wake(futexp, nr) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \ +			      FUTEX_WAKE, (nr), 0);					      \ +    __ret;								      \ +  }) + +/* Returns non-zero if error happened, zero if success.  */ +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \ +			      FUTEX_CMP_REQUEUE, (nr_wake), (nr_move), (mutex), (val));	      \ +    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \ +  }) + +#define lll_robust_dead(futexv) \ +  do									      \ +    {									      \ +      int *__futexp = &(futexv);					      \ +      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \ +      lll_futex_wake (__futexp, 1);				      \ +    }									      \ +  while (0) + +/* Returns non-zero if error happened, zero if success.  */ +#ifdef __sparc32_atomic_do_lock +/* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs.  */ +# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) 1 +#else +# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +									      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \ +			      FUTEX_WAKE_OP,    \ +			      (nr_wake), (nr_wake2), (futexp2),		      \ +			      FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);		      \ +    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \ +  }) +#endif + +static inline int +__attribute__ ((always_inline)) +__lll_trylock (int *futex) +{ +  return atomic_compare_and_exchange_val_24_acq (futex, 1, 0) != 0; +} +#define lll_mutex_trylock(futex) __lll_trylock (&(futex)) + +static inline int +__attribute__ ((always_inline)) +__lll_cond_trylock (int *futex) +{ +  return atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0; +} +#define lll_mutex_cond_trylock(futex) __lll_cond_trylock (&(futex)) + +static inline int +__attribute__ ((always_inline)) +__lll_robust_trylock (int *futex, int id) +{ +  return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0; +} +#define lll_robust_trylock(futex, id) \ +  __lll_robust_trylock (&(futex), id) + + +extern void __lll_lock_wait (int *futex) attribute_hidden; +extern int __lll_robust_lock_wait (int *futex) attribute_hidden; + +static inline void +__attribute__ ((always_inline)) +__lll_lock (int *futex) +{ +  int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0); + +  if (__builtin_expect (val != 0, 0)) +    { +	__lll_lock_wait (futex); +    } +} +#define lll_mutex_lock(futex) __lll_lock (&(futex)) + +static inline int +__attribute__ ((always_inline)) +__lll_robust_lock (int *futex, int id) +{ +  int result = 0; +  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) +    result = __lll_robust_lock_wait (futex); +  return result; +} +#define lll_robust_lock(futex, id) \ +  __lll_robust_lock (&(futex), id) + +static inline void +__attribute__ ((always_inline)) +__lll_cond_lock (int *futex) +{ +  int val = atomic_compare_and_exchange_val_24_acq (futex, 2, 0); + +  if (__builtin_expect (val != 0, 0)) +    __lll_lock_wait (futex); +} +#define lll_mutex_cond_lock(futex) __lll_cond_lock (&(futex)) + +#define lll_robust_cond_lock(futex, id) \ +  __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS) + + +extern int __lll_timedlock_wait (int *futex, const struct timespec *) attribute_hidden; +extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *) attribute_hidden; + +static inline int +__attribute__ ((always_inline)) +__lll_timedlock (int *futex, const struct timespec *abstime) +{ +  int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0); +  int result = 0; + +  if (__builtin_expect (val != 0, 0)) +    result = __lll_timedlock_wait (futex, abstime); +  return result; +} +#define lll_mutex_timedlock(futex, abstime) \ +  __lll_timedlock (&(futex), abstime) + +static inline int +__attribute__ ((always_inline)) +__lll_robust_timedlock (int *futex, const struct timespec *abstime, +			int id) +{ +  int result = 0; +  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) +    result = __lll_robust_timedlock_wait (futex, abstime); +  return result; +} +#define lll_robust_timedlock(futex, abstime, id) \ +  __lll_robust_timedlock (&(futex), abstime, id) + +#define lll_mutex_unlock(lock) \ +  ((void) ({								      \ +    int *__futex = &(lock);						      \ +    int __val = atomic_exchange_24_rel (__futex, 0);			      \ +    if (__builtin_expect (__val > 1, 0))				      \ +      lll_futex_wake (__futex, 1);				      \ +  })) + +#define lll_robust_unlock(lock) \ +  ((void) ({								      \ +    int *__futex = &(lock);						      \ +    int __val = atomic_exchange_rel (__futex, 0);			      \ +    if (__builtin_expect (__val & FUTEX_WAITERS, 0))			      \ +      lll_futex_wake (__futex, 1);				      \ +  })) + +#define lll_mutex_islocked(futex) \ +  (futex != 0) + +/* We have a separate internal lock implementation which is not tied +   to binary compatibility.  */ + +/* Type for lock object.  */ +typedef int lll_lock_t; + +/* Initializers for lock.  */ +#define LLL_LOCK_INITIALIZER		(0) +#define LLL_LOCK_INITIALIZER_LOCKED	(1) + +extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; + +#define lll_trylock(lock)	lll_mutex_trylock (lock) +#define lll_lock(lock)		lll_mutex_lock (lock) +#define lll_unlock(lock)	lll_mutex_unlock (lock) +#define lll_islocked(lock)	lll_mutex_islocked (lock) + + +/* The kernel notifies a process with uses CLONE_CLEARTID via futex +   wakeup when the clone terminates.  The memory location contains the +   thread ID while the clone is running and is reset to zero +   afterwards.	*/ +#define lll_wait_tid(tid) \ +  do							\ +    {							\ +      __typeof (tid) __tid;				\ +      while ((__tid = (tid)) != 0)			\ +	lll_futex_wait (&(tid), __tid);	\ +    }							\ +  while (0) + +extern int __lll_timedwait_tid (int *, const struct timespec *) +     attribute_hidden; + +#define lll_timedwait_tid(tid, abstime) \ +  ({							\ +    int __res = 0;					\ +    if ((tid) != 0)					\ +      __res = __lll_timedwait_tid (&(tid), (abstime));	\ +    __res;						\ +  }) + +#endif	/* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S new file mode 100644 index 000000000..e8705c54b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "sparc64/pt-vfork.S" +#else +#include "sparc32/pt-vfork.S" +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c new file mode 100644 index 000000000..3b07cc127 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c @@ -0,0 +1,94 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + +   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 "pthreadP.h" +#include <lowlevellock.h> + + +unsigned long int __fork_generation attribute_hidden; + + +static void +clear_once_control (void *arg) +{ +  pthread_once_t *once_control = (pthread_once_t *) arg; + +  *once_control = 0; +  lll_futex_wake (once_control, INT_MAX); +} + + +int +__pthread_once (once_control, init_routine) +     pthread_once_t *once_control; +     void (*init_routine) (void); +{ +  while (1) +    { +      int oldval, val, newval; + +      val = *once_control; +      do +	{ +	  /* Check if the initialized has already been done.  */ +	  if ((val & 2) != 0) +	    return 0; + +	  oldval = val; +	  newval = (oldval & 3) | __fork_generation | 1; +	  val = atomic_compare_and_exchange_val_acq (once_control, newval, +						     oldval); +	} +      while (__builtin_expect (val != oldval, 0)); + +      /* Check if another thread already runs the initializer.	*/ +      if ((oldval & 1) != 0) +	{ +	  /* Check whether the initializer execution was interrupted +	     by a fork.	 */ +	  if (((oldval ^ newval) & -4) == 0) +	    { +	      /* Same generation, some other thread was faster. Wait.  */ +	      lll_futex_wait (once_control, newval); +	      continue; +	    } +	} + +      /* This thread is the first here.  Do the initialization. +	 Register a cleanup handler so that in case the thread gets +	 interrupted the initialization can be restarted.  */ +      pthread_cleanup_push (clear_once_control, once_control); + +      init_routine (); + +      pthread_cleanup_pop (0); + + +      /* Add one to *once_control.  */ +      atomic_increment (once_control); + +      /* Wake up all other threads.  */ +      lll_futex_wake (once_control, INT_MAX); +      break; +    } + +  return 0; +} +weak_alias (__pthread_once, pthread_once) +strong_alias (__pthread_once, __pthread_once_internal) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S new file mode 100644 index 000000000..a6142aafe --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S @@ -0,0 +1,2 @@ +#define RESET_PID +#include <libc/sysdeps/linux/sparc/clone.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S new file mode 100644 index 000000000..fb01242b5 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S @@ -0,0 +1,45 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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> +#include <tcb-offsets.h> + +	.text +	.globl		__syscall_error +ENTRY(__vfork) +	ld	[%g7 + PID], %o5 +	sub	%g0, %o5, %o4 +	st	%o4, [%g7 + PID] + +	LOADSYSCALL(vfork) +	ta	0x10 +	bcc	2f +	 mov	%o7, %g1 +	st	%o5, [%g7 + PID] +	call	__syscall_error +	 mov	%g1, %o7 +2:	sub	%o1, 1, %o1 +	andcc	%o0, %o1, %o0 +	bne,a	1f +	 st	%o5, [%g7 + PID] +1:	retl +	 nop +END(__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h new file mode 100644 index 000000000..ad650d040 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h @@ -0,0 +1,105 @@ +/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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 <tls.h> +#include <sysdep.h> +#ifndef __ASSEMBLER__ +# include <pthreadP.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)   \ +        .text;                  \ +    .globl      __syscall_error;    \ +ENTRY(name)                 \ +    ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\ +    cmp %g1, 0;             \ +    bne 1f;                 \ +.type   __##syscall_name##_nocancel,@function;  \ +.globl  __##syscall_name##_nocancel;        \ +__##syscall_name##_nocancel:            \ +     mov SYS_ify(syscall_name), %g1;    \ +    ta 0x10;                \ +    bcc 8f;                 \ +     mov %o7, %g1;              \ +    call __syscall_error;           \ +     mov %g1, %o7;              \ +8:  jmpl %o7 + 8, %g0;          \ +     nop;                   \ +.size   __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\ +1:  save %sp, -96, %sp;         \ +    cfi_def_cfa_register(%fp);      \ +    cfi_window_save;            \ +    cfi_register(%o7, %i7);         \ +    CENABLE;                \ +     nop;                   \ +    mov %o0, %l0;               \ +    COPY_ARGS_##args            \ +    mov SYS_ify(syscall_name), %g1;     \ +    ta 0x10;                \ +    bcc 1f;                 \ +     mov %o0, %l1;              \ +    CDISABLE;               \ +     mov %l0, %o0;              \ +    call __syscall_error;           \ +     mov %l1, %o0;              \ +    b 2f;                   \ +     mov -1, %l1;               \ +1:  CDISABLE;               \ +     mov %l0, %o0;              \ +2:  jmpl %i7 + 8, %g0;          \ +     restore %g0, %l1, %o0; + +# ifdef IS_IN_libpthread +#  define CENABLE	call __pthread_enable_asynccancel +#  define CDISABLE	call __pthread_disable_asynccancel +# elif !defined NOT_IN_libc +#  define CENABLE	call __libc_enable_asynccancel +#  define CDISABLE	call __libc_disable_asynccancel +# elif defined IS_IN_librt +#  define CENABLE	call __librt_enable_asynccancel +#  define CDISABLE	call __librt_disable_asynccancel +# else +#  error Unsupported library +# endif + +#define COPY_ARGS_0	/* Nothing */ +#define COPY_ARGS_1	COPY_ARGS_0 mov %i0, %o0; +#define COPY_ARGS_2	COPY_ARGS_1 mov %i1, %o1; +#define COPY_ARGS_3	COPY_ARGS_2 mov %i2, %o2; +#define COPY_ARGS_4	COPY_ARGS_3 mov %i3, %o3; +#define COPY_ARGS_5	COPY_ARGS_4 mov %i4, %o4; +#define COPY_ARGS_6	COPY_ARGS_5 mov %i5, %o5; + +# ifndef __ASSEMBLER__ +#  define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \ +				   header.multiple_threads) == 0, 1) +# else +#  define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1 +# endif + +#elif !defined __ASSEMBLER__ + +# define SINGLE_THREAD_P (1) +# define NO_CANCELLATION 1 + +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S new file mode 100644 index 000000000..1a3827789 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S @@ -0,0 +1,49 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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> +#include <tcb-offsets.h> + +	.text +	.globl		__syscall_error +ENTRY(__vfork) +	ld	[%g7 + PID], %o5 +	cmp	%o5, 0 +	bne	1f +	 sub	%g0, %o5, %o4 +	sethi	%hi(0x80000000), %o4 +1:	st	%o4, [%g7 + PID] + +	LOADSYSCALL(vfork) +	ta	0x10 +	bcc	2f +	 mov	%o7, %g1 +	st	%o5, [%g7 + PID] +	call	__syscall_error +	 mov	%g1, %o7 +2:	sub	%o1, 1, %o1 +	andcc	%o0, %o1, %o0 +	bne,a	1f +	 st	%o5, [%g7 + PID] +1:	retl +	 nop +END(__vfork) + +hidden_def (vfork) +weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions new file mode 100644 index 000000000..3b111ddb5 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions @@ -0,0 +1,7 @@ +librt { +  GLIBC_2.3.3 { +    # Changed timer_t. +    timer_create; timer_delete; timer_getoverrun; timer_gettime; +    timer_settime; +  } +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S new file mode 100644 index 000000000..64e3bfc12 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S @@ -0,0 +1,2 @@ +#define RESET_PID +#include <libc/sysdeps/linux/sparc/sparcv9/clone.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S new file mode 100644 index 000000000..8941043c3 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S @@ -0,0 +1,45 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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> +#include <tcb-offsets.h> + +	.text +	.globl	__syscall_error +ENTRY(__vfork) +	ld	[%g7 + PID], %o5 +	sub	%g0, %o5, %o4 +	st	%o4, [%g7 + PID] + +	LOADSYSCALL(vfork) +	ta	0x6d +	bcc,pt	%xcc, 2f +	 mov	%o7, %g1 +	st	%o5, [%g7 + PID] +	call	__syscall_error +	 mov	%g1, %o7 +2:	sub	%o1, 1, %o1 +	andcc	%o0, %o1, %o0 +	bne,a,pt %icc, 1f +	 st	%o5, [%g7 + PID] +1:	retl +	 nop +END(__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h new file mode 100644 index 000000000..aec2d4a86 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h @@ -0,0 +1,110 @@ +/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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> +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <pthreadP.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)	\ +	.text;					\ +	.globl		__syscall_error;	\ +ENTRY(name)					\ +	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\ +	brnz,pn %g1, 1f;			\ +.type	__##syscall_name##_nocancel,@function;	\ +.globl	__##syscall_name##_nocancel;		\ +__##syscall_name##_nocancel:			\ +	 mov SYS_ify(syscall_name), %g1;	\ +	ta 0x6d;				\ +	bcc,pt %xcc, 8f;			\ +	 mov %o7, %g1;				\ +	call __syscall_error;			\ +	 mov %g1, %o7;				\ +8:	jmpl %o7 + 8, %g0;			\ +	 nop;					\ +.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\ +1:	save %sp, -192, %sp;			\ +	cfi_def_cfa_register(%fp);		\ +	cfi_window_save;			\ +	cfi_register(%o7, %i7);			\ +	CENABLE;				\ +	 nop;					\ +	mov %o0, %l0;				\ +	COPY_ARGS_##args			\ +	mov SYS_ify(syscall_name), %g1;		\ +	ta 0x6d;				\ +	bcc,pt %xcc, 1f;			\ +	 mov %o0, %l1;				\ +	CDISABLE;				\ +	 mov %l0, %o0;				\ +	call __syscall_error;			\ +	 mov %l1, %o0;				\ +	ba,pt %xcc, 2f;				\ +	 mov -1, %l1;				\ +1:	CDISABLE;				\ +	 mov %l0, %o0;				\ +2:	jmpl %i7 + 8, %g0;			\ +	 restore %g0, %l1, %o0; + +# ifdef IS_IN_libpthread +#  define CENABLE	call __pthread_enable_asynccancel +#  define CDISABLE	call __pthread_disable_asynccancel +# elif !defined NOT_IN_libc +#  define CENABLE	call __libc_enable_asynccancel +#  define CDISABLE	call __libc_disable_asynccancel +# elif defined IS_IN_librt +#  define CENABLE	call __librt_enable_asynccancel +#  define CDISABLE	call __librt_disable_asynccancel +# else +#  error Unsupported library +# endif + +#define COPY_ARGS_0	/* Nothing */ +#define COPY_ARGS_1	COPY_ARGS_0 mov %i0, %o0; +#define COPY_ARGS_2	COPY_ARGS_1 mov %i1, %o1; +#define COPY_ARGS_3	COPY_ARGS_2 mov %i2, %o2; +#define COPY_ARGS_4	COPY_ARGS_3 mov %i3, %o3; +#define COPY_ARGS_5	COPY_ARGS_4 mov %i4, %o4; +#define COPY_ARGS_6	COPY_ARGS_5 mov %i5, %o5; + +# ifndef __ASSEMBLER__ +#  define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \ +				   header.multiple_threads) == 0, 1) +# else +#  define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1 +# endif + +#elif !defined __ASSEMBLER__ + +# define SINGLE_THREAD_P (1) +# define NO_CANCELLATION 1 + +#endif + +#ifndef __ASSEMBLER__ +# define RTLD_SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ +				   header.multiple_threads) == 0, 1) +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c new file mode 100644 index 000000000..0a9c3372b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c @@ -0,0 +1 @@ +#include "../../x86_64/timer_create.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c new file mode 100644 index 000000000..f0d4fd21d --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c @@ -0,0 +1 @@ +#include "../../x86_64/timer_delete.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c new file mode 100644 index 000000000..82121a7a2 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c @@ -0,0 +1 @@ +#include "../../x86_64/timer_getoverr.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c new file mode 100644 index 000000000..313c05fea --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c @@ -0,0 +1 @@ +#include "../../x86_64/timer_gettime.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c new file mode 100644 index 000000000..76f549cb4 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c @@ -0,0 +1 @@ +#include "../../x86_64/timer_settime.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S new file mode 100644 index 000000000..b4e89aceb --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S @@ -0,0 +1,49 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + +   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> +#include <tcb-offsets.h> + +	.text +	.globl	__syscall_error +ENTRY(__vfork) +	ld	[%g7 + PID], %o5 +	sethi	%hi(0x80000000), %o3 +	cmp	%o5, 0 +	sub	%g0, %o5, %o4 +	move	%icc, %o3, %o4 +	st	%o4, [%g7 + PID] + +	LOADSYSCALL(vfork) +	ta	0x6d +	bcc,pt	%xcc, 2f +	 mov	%o7, %g1 +	st	%o5, [%g7 + PID] +	call	__syscall_error +	 mov	%g1, %o7 +2:	sub	%o1, 1, %o1 +	andcc	%o0, %o1, %o0 +	bne,a,pt %icc, 1f +	 st	%o5, [%g7 + PID] +1:	retl +	 nop +END(__vfork) + +hidden_def (vfork) +weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h new file mode 100644 index 000000000..5be9beb92 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "sparc64/sysdep-cancel.h" +#else +#include "sparc32/sysdep-cancel.h" +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep.h new file mode 100644 index 000000000..744e587a3 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep.h @@ -0,0 +1,65 @@ +#ifndef _LINUX_SPARC_SYSDEP_H +#define _LINUX_SPARC_SYSDEP_H 1 + +#include <sysdeps/unix/sysdep.h> + +#undef ENTRY +#undef END + +#ifdef __ASSEMBLER__ + +#define LOADSYSCALL(x) mov __NR_##x, %g1 + +#define ENTRY(name)                 \ +    .align 4;                       \ +    .global C_SYMBOL_NAME(name);    \ +    .type   name, @function;        \ +C_LABEL(name)                       \ +    cfi_startproc; + +#define END(name)                   \ +    cfi_endproc;                    \ +    .size name, . - name + +#define LOC(name) .L##name + +	/* If the offset to __syscall_error fits into a signed 22-bit +	 * immediate branch offset, the linker will relax the call into +	 * a normal branch. +	 */ +#undef PSEUDO +#undef PSEUDO_END +#undef PSEUDO_NOERRNO +#undef PSEUDO_ERRVAL + +#define PSEUDO(name, syscall_name, args)	\ +	.text;					\ +	.globl		__syscall_error;	\ +ENTRY(name);					\ +	LOADSYSCALL(syscall_name);		\ +	ta		0x10;			\ +	bcc		1f;			\ +	 mov		%o7, %g1;		\ +	call		__syscall_error;	\ +	 mov		%g1, %o7;		\ +1: + +#define PSEUDO_NOERRNO(name, syscall_name, args)\ +	.text;					\ +ENTRY(name);					\ +	LOADSYSCALL(syscall_name);		\ +	ta		0x10; + +#define PSEUDO_ERRVAL(name, syscall_name, args)	\ +	.text;					\ +ENTRY(name);					\ +	LOADSYSCALL(syscall_name);		\ +	ta		0x10; + +#define PSEUDO_END(name)			\ +	END(name) + + +#endif + +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S new file mode 100644 index 000000000..160cd0b10 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "sparc64/vfork.S" +#else +#include "sparc32/vfork.S" +#endif | 
