summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/unix/sysv/linux/sparc
diff options
context:
space:
mode:
authorAustin Foxley <austinf@cetoncorp.com>2009-10-17 12:26:24 -0700
committerAustin Foxley <austinf@cetoncorp.com>2009-10-17 12:26:24 -0700
commitc68d0fa2d88fc2134a38d99e7e944828384a7671 (patch)
tree6596943bd1c77f18d6e49d4153ddd3f3d67b49f5 /libpthread/nptl/sysdeps/unix/sysv/linux/sparc
parent9a03e98a3b418f33c347a6023e9320f3a42cb9e4 (diff)
libpthread/nptl: core of the "Native Posix Threading Library" for uClibc
targetting arm,sh,i386,mips,sparc for now Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sparc')
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch66
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions6
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h89
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h218
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h44
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c29
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c131
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h258
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c94
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S45
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h105
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S45
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h110
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep.h65
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S5
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