aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-03-11 09:30:37 +0000
committerRoland McGrath <roland@gnu.org>2003-03-11 09:30:37 +0000
commitb33e61633a10a233510f6f49b97b7e2ad15c7311 (patch)
tree9b6025b692435f629bc771dca74dcfb48e41768a /nptl
parent5d5d5969b17422e3b1af6f88436e91f32a36fd58 (diff)
downloadglibc-b33e61633a10a233510f6f49b97b7e2ad15c7311.zip
glibc-b33e61633a10a233510f6f49b97b7e2ad15c7311.tar.gz
glibc-b33e61633a10a233510f6f49b97b7e2ad15c7311.tar.bz2
* sysdeps/generic/dl-sysdep.c (_dl_important_hwcaps): If CNT == 1,
allocate space even for the trailing '/'. Reported by John Reiser <jreiser@BitWagon.com>. * sysdeps/unix/sysv/linux/ia64/sysdep.h (LOAD_ARGS_6, ASM_ARGS_6, ASM_CLOBBERS_6): Define. (ASM_CLOBBERS_5): Use ASM_CLOBBERS_6. * sysdeps/unix/sysv/linux/ia64/clone2.S (__clone2): Reorder arguments to match IA-32 order. * sysdeps/unix/sysv/linux/i386/clone.S: Fix comment.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog52
-rw-r--r--nptl/sysdeps/ia64/Makefile25
-rw-r--r--nptl/sysdeps/ia64/bits/atomic.h93
-rw-r--r--nptl/sysdeps/ia64/pthread_spin_init.c20
-rw-r--r--nptl/sysdeps/ia64/pthread_spin_lock.c36
-rw-r--r--nptl/sysdeps/ia64/pthread_spin_trylock.c28
-rw-r--r--nptl/sysdeps/ia64/pthread_spin_unlock.c31
-rw-r--r--nptl/sysdeps/ia64/pthreaddef.h46
-rw-r--r--nptl/sysdeps/ia64/tcb-offsets.sym4
-rw-r--r--nptl/sysdeps/ia64/td_ta_map_lwp2thr.c44
-rw-r--r--nptl/sysdeps/ia64/tls.h128
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_timedwait.c9
-rw-r--r--nptl/sysdeps/s390/pthreaddef.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h153
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h39
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/createthread.c26
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/fork.c31
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c19
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c21
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.c85
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h251
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c100
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c108
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/pt-vfork.S44
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c97
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c51
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c91
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c50
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c63
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h115
30 files changed, 1859 insertions, 3 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 8d28e89..8146b80 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,55 @@
+2003-03-11 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/pthread/pthread_cond_timedwait.c
+ (__pthread_cond_timedwait): Unlock and fail if
+ __pthread_mutex_unlock_internal failed.
+
+ * sysdeps/pthread/createthread.c (ARCH_CLONE): Define if not defined.
+ (create_thread): Only assert PD->tcb != NULL under [TLS_TCB_AT_TP].
+ Use ARCH_CLONE.
+ * allocatestack.c (ALLOCATE_STACK_PARMS): New macro.
+ [NEED_SEPARATE_REGISTER_STACK] (STACK_VARIABLES,
+ STACK_VARIABLES_ARGS, STACK_VARIABLES_PARMS, ALLOCATE_STACK_PARMS,
+ ALLOCATE_STACK): New macros.
+ (TLS_TPADJ): New macro.
+ (get_cached_stack, queue_stack, __deallocate_stack): Use TLS_TPADJ.
+ (allocate_stack): Handle TLS_DTV_AT_TP and
+ NEED_SEPARATE_REGISTER_STACK. Use TLS_TPADJ.
+ * pthread_create.c (__pthread_create_2_1) [! TLS_TCB_AT_TP]:
+ Don't set PD->self.
+ * init.c [__ia64__] (__NR_set_tid_address): Define.
+
+ * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: New file.
+ * sysdeps/unix/sysv/linux/ia64/bits/semaphore.h: New file.
+ * sysdeps/unix/sysv/linux/ia64/fork.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/createthread.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/lowlevellock.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: New file.
+ * sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/pt-initfini.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/pt-vfork.S: New file.
+ * sysdeps/unix/sysv/linux/ia64/pthread_once.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/sem_post.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/sem_timedwait.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/sem_trywait.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/sem_wait.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: New file.
+ * sysdeps/ia64/bits/atomic.h: New file.
+ * sysdeps/ia64/Makefile: New file.
+ * sysdeps/ia64/pthread_spin_init.c: New file.
+ * sysdeps/ia64/pthread_spin_lock.c: New file.
+ * sysdeps/ia64/pthread_spin_trylock.c: New file.
+ * sysdeps/ia64/pthread_spin_unlock.c: New file.
+ * sysdeps/ia64/pthreaddef.h: New file.
+ * sysdeps/ia64/tcb-offsets.sym: New file.
+ * sysdeps/ia64/td_ta_map_lwp2thr.c: New file.
+ * sysdeps/ia64/tls.h: New file.
+
+ * sysdeps/s390/pthreaddef.h (__exit_thread_inline): Pass 1 argument
+ to syscall instead of no arguments.
+
2003-03-10 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/x86_64/sem_post.S: New file.
diff --git a/nptl/sysdeps/ia64/Makefile b/nptl/sysdeps/ia64/Makefile
new file mode 100644
index 0000000..3229d3f
--- /dev/null
+++ b/nptl/sysdeps/ia64/Makefile
@@ -0,0 +1,25 @@
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
+
+ifeq ($(subdir),nptl)
+libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask
+endif
diff --git a/nptl/sysdeps/ia64/bits/atomic.h b/nptl/sysdeps/ia64/bits/atomic.h
new file mode 100644
index 0000000..4b1d24f
--- /dev/null
+++ b/nptl/sysdeps/ia64/bits/atomic.h
@@ -0,0 +1,93 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+#include <ia64intrin.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \
+ (!__sync_bool_compare_and_swap_si ((int *) (mem), (int) (long) (oldval), \
+ (int) (long) (newval)))
+
+# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \
+ (!__sync_bool_compare_and_swap_di ((long *) (mem), (long) (oldval), \
+ (long) (newval)))
+
+#define __arch_compare_and_exchange_32_val_acq(mem, newval, oldval) \
+ __sync_val_compare_and_swap_si ((int *) (mem), (int) (long) (oldval), \
+ (int) (long) (newval))
+
+# define __arch_compare_and_exchange_64_val_acq(mem, newval, oldval) \
+ __sync_val_compare_and_swap_di ((long *) (mem), (long) (oldval), \
+ (long) (newval))
+
+# define atomic_exchange_and_add(mem, value) \
+ ({ \
+ __typeof (*mem) __oldval, __val; \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __value = (value); \
+ \
+ __val = *__memp; \
+ if (sizeof (*mem) == 4) \
+ do \
+ __oldval = __val; \
+ while ((__val \
+ = __arch_compare_and_exchange_32_val_acq (__memp, __oldval, \
+ __oldval + __value)) \
+ != __oldval); \
+ else if (sizeof (*mem) == 8) \
+ do \
+ __oldval = __val; \
+ while ((__val \
+ = __arch_compare_and_exchange_64_val_acq (__memp, __oldval, \
+ __oldval + __value)) \
+ != __oldval); \
+ else \
+ abort (); \
+ __oldval + __value; })
diff --git a/nptl/sysdeps/ia64/pthread_spin_init.c b/nptl/sysdeps/ia64/pthread_spin_init.c
new file mode 100644
index 0000000..c300cd4
--- /dev/null
+++ b/nptl/sysdeps/ia64/pthread_spin_init.c
@@ -0,0 +1,20 @@
+/* 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. */
+
+/* Not needed. pthread_spin_init is an alias for pthread_spin_unlock. */
diff --git a/nptl/sysdeps/ia64/pthread_spin_lock.c b/nptl/sysdeps/ia64/pthread_spin_lock.c
new file mode 100644
index 0000000..f6b706a
--- /dev/null
+++ b/nptl/sysdeps/ia64/pthread_spin_lock.c
@@ -0,0 +1,36 @@
+/* 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 "pthreadP.h"
+
+int
+pthread_spin_lock (lock)
+ pthread_spinlock_t *lock;
+{
+ int *p = (int *) lock;
+
+ while (__builtin_expect (__sync_val_compare_and_swap_si (p, 0, 1), 0))
+ {
+ /* Spin without using the atomic instruction. */
+ do
+ __asm __volatile ("" : : : "memory");
+ while (*p);
+ }
+ return 0;
+}
diff --git a/nptl/sysdeps/ia64/pthread_spin_trylock.c b/nptl/sysdeps/ia64/pthread_spin_trylock.c
new file mode 100644
index 0000000..b7cbf14
--- /dev/null
+++ b/nptl/sysdeps/ia64/pthread_spin_trylock.c
@@ -0,0 +1,28 @@
+/* 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 <errno.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_trylock (lock)
+ pthread_spinlock_t *lock;
+{
+ return __sync_val_compare_and_swap_si ((int *) lock, 0, 1) == 0 ? 0 : EBUSY;
+}
diff --git a/nptl/sysdeps/ia64/pthread_spin_unlock.c b/nptl/sysdeps/ia64/pthread_spin_unlock.c
new file mode 100644
index 0000000..b3f1ff1
--- /dev/null
+++ b/nptl/sysdeps/ia64/pthread_spin_unlock.c
@@ -0,0 +1,31 @@
+/* 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. */
+
+/* Ugly hack to avoid the declaration of pthread_spin_init. */
+#define pthread_spin_init pthread_spin_init_XXX
+#include "pthreadP.h"
+#undef pthread_spin_init
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+ *lock = 0;
+ return 0;
+}
+strong_alias (pthread_spin_unlock, pthread_spin_init)
diff --git a/nptl/sysdeps/ia64/pthreaddef.h b/nptl/sysdeps/ia64/pthreaddef.h
new file mode 100644
index 0000000..8fc58e0
--- /dev/null
+++ b/nptl/sysdeps/ia64/pthreaddef.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Default stack size. */
+#define ARCH_STACK_DEFAULT_SIZE (32 * 1024 * 1024)
+
+/* IA-64 uses a normal stack and a register stack. */
+#define NEED_SEPARATE_REGISTER_STACK
+
+/* Required stack pointer alignment at beginning. */
+#define STACK_ALIGN 16
+
+/* Minimal stack size after allocating thread descriptor and guard size. */
+#define MINIMAL_REST_STACK 16384
+
+/* Alignment requirement for TCB. */
+#define TCB_ALIGNMENT 16
+
+/* The signal used for asynchronous cancelation. */
+#define SIGCANCEL __SIGRTMIN
+
+
+/* Location of current stack frame. */
+#define CURRENT_STACK_FRAME __stack_pointer
+register char *__stack_pointer __asm__ ("sp");
+
+/* XXX Until we have a better place keep the definitions here. */
+
+/* While there is no such syscall. */
+#define __exit_thread_inline(val) \
+ INLINE_SYSCALL (exit, 1, (val))
diff --git a/nptl/sysdeps/ia64/tcb-offsets.sym b/nptl/sysdeps/ia64/tcb-offsets.sym
new file mode 100644
index 0000000..69b6b39
--- /dev/null
+++ b/nptl/sysdeps/ia64/tcb-offsets.sym
@@ -0,0 +1,4 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET offsetof (struct pthread, multiple_threads) - sizeof (struct pthread)
diff --git a/nptl/sysdeps/ia64/td_ta_map_lwp2thr.c b/nptl/sysdeps/ia64/td_ta_map_lwp2thr.c
new file mode 100644
index 0000000..0931ce9
--- /dev/null
+++ b/nptl/sysdeps/ia64/td_ta_map_lwp2thr.c
@@ -0,0 +1,44 @@
+/* Which thread is running on an LWP? IA-64 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "thread_dbP.h"
+#include <tls.h>
+
+
+td_err_e
+td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
+{
+ LOG ("td_ta_map_lwp2thr");
+
+ /* Test whether the TA parameter is ok. */
+ if (! ta_ok (ta))
+ return TD_BADTA;
+
+ prgregset_t regs;
+ if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+ return TD_ERR;
+
+ /* IA-64 thread register is r13. */
+ th->th_unique = regs[13];
+
+ /* Found it. Now complete the `td_thrhandle_t' object. */
+ th->th_ta_p = (td_thragent_t *) ta;
+
+ return TD_OK;
+}
diff --git a/nptl/sysdeps/ia64/tls.h b/nptl/sysdeps/ia64/tls.h
new file mode 100644
index 0000000..8a13a59
--- /dev/null
+++ b/nptl/sysdeps/ia64/tls.h
@@ -0,0 +1,128 @@
+/* Definition for thread-local data handling. nptl/IA-64 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _TLS_H
+#define _TLS_H 1
+
+#include <dl-sysdep.h>
+#ifndef __ASSEMBLER__
+# include <stddef.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <list.h>
+
+
+/* Type for the dtv. */
+typedef union dtv
+{
+ size_t counter;
+ void *pointer;
+} dtv_t;
+
+
+typedef struct
+{
+ dtv_t *dtv;
+ void *private;
+} tcbhead_t;
+
+# define TLS_MULTIPLE_THREADS_IN_TCB 1
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif
+
+
+/* We require TLS support in the tools. */
+#ifndef HAVE_TLS_SUPPORT
+# error "TLS support is required."
+#endif
+
+/* Signal that TLS support is available. */
+#define USE_TLS 1
+
+/* Alignment requirement for the stack. */
+#define STACK_ALIGN 16
+
+#ifndef __ASSEMBLER__
+/* Get system call information. */
+# include <sysdep.h>
+
+register struct pthread *__thread_self __asm__("r13");
+
+/* This is the size of the initial TCB. */
+# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB. */
+# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB. */
+# define TLS_TCB_SIZE sizeof (tcbhead_t)
+
+/* This is the size we need before TCB. */
+# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
+
+/* Alignment requirements for the TCB. */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* The DTV is allocated at the TP; the TCB is placed elsewhere. */
+# define TLS_DTV_AT_TP 1
+
+/* Get the thread descriptor definition. */
+# include <nptl/descr.h>
+
+/* Install the dtv pointer. The pointer passed is to the element with
+ index -1 which contain the length. */
+# define INSTALL_DTV(descr, dtvp) \
+ ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread. */
+# define INSTALL_NEW_DTV(DTV) \
+ (((tcbhead_t *)__thread_self)->dtv = (DTV))
+
+/* Return dtv of given thread descriptor. */
+# define GET_DTV(descr) \
+ (((tcbhead_t *) (descr))->dtv)
+
+/* Code to initially initialize the thread pointer. This might need
+ special attention since 'errno' is not yet available and if the
+ operation can cause a failure 'errno' must not be touched. */
+# define TLS_INIT_TP(thrdescr, secondcall) \
+ (__thread_self = (thrdescr), NULL)
+
+/* Return the address of the dtv for the current thread. */
+# define THREAD_DTV() \
+ (((tcbhead_t *)__thread_self)->dtv)
+
+/* Return the thread descriptor for the current thread. */
+# define THREAD_SELF (__thread_self - 1)
+
+/* Access to data in the thread descriptor is easy. */
+#define THREAD_GETMEM(descr, member) \
+ descr->member
+#define THREAD_GETMEM_NC(descr, member, idx) \
+ descr->member[idx]
+#define THREAD_SETMEM(descr, member, value) \
+ descr->member = (value)
+#define THREAD_SETMEM_NC(descr, member, idx, value) \
+ descr->member[idx] = (value)
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 3b29cb4..d6a4ae7 100644
--- a/nptl/sysdeps/pthread/pthread_cond_timedwait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -46,7 +46,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
{
struct _pthread_cleanup_buffer buffer;
struct _condvar_cleanup_buffer cbuffer;
- int result = 0;
+ int result = 0, err;
/* Catch invalid parameters. */
if (abstime->tv_nsec >= 1000000000)
@@ -56,7 +56,12 @@ __pthread_cond_timedwait (cond, mutex, abstime)
lll_mutex_lock (cond->__data.__lock);
/* Now we can release the mutex. */
- __pthread_mutex_unlock_internal (mutex);
+ err = __pthread_mutex_unlock_internal (mutex);
+ if (err)
+ {
+ lll_mutex_unlock (cond->__data.__lock);
+ return err;
+ }
/* We have one new user of the condvar. */
++cond->__data.__total_seq;
diff --git a/nptl/sysdeps/s390/pthreaddef.h b/nptl/sysdeps/s390/pthreaddef.h
index 17ef4dc..ff044a3 100644
--- a/nptl/sysdeps/s390/pthreaddef.h
+++ b/nptl/sysdeps/s390/pthreaddef.h
@@ -41,4 +41,4 @@
/* While there is no such syscall. */
#define __exit_thread_inline(val) \
- INLINE_SYSCALL (exit, 0)
+ INLINE_SYSCALL (exit, 1, (val))
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
new file mode 100644
index 0000000..ebe2818
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
@@ -0,0 +1,153 @@
+/* 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 _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#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
+
+
+/* Thread identifiers. The structure of the attribute type is not
+ exposed on purpose. */
+typedef struct __opaque_pthread *pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __count;
+ struct pthread *__owner;
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned long long int __total_seq;
+ unsigned long long int __wakeup_seq;
+ unsigned long long int __woken_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#ifdef __USE_UNIX98
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is not exposed on purpose. */
+typedef union
+{
+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;
+ pthread_t __writer;
+ unsigned long int __pad1;
+ unsigned long int __pad2;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned int __flags;
+ } __data;
+ 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/nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h
new file mode 100644
index 0000000..cfb9c31
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@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. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T 32
+
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+/* Maximum value the semaphore can have. */
+#define SEM_VALUE_MAX ((int) ((~0u) >> 1))
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c b/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c
new file mode 100644
index 0000000..8ac06e8
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE (pd + 1)
+
+#define ARCH_CLONE __clone2
+
+/* Get the real implementation. */
+#include <nptl/sysdeps/pthread/createthread.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/fork.c b/nptl/sysdeps/unix/sysv/linux/ia64/fork.c
new file mode 100644
index 0000000..b8d00bd
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/fork.c
@@ -0,0 +1,31 @@
+/* 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_SYSCALL (clone2, 6, \
+ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \
+ NULL, 0, &THREAD_SELF->tid, NULL, NULL)
+
+#include "../fork.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c b/nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c
new file mode 100644
index 0000000..58b4832
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c
@@ -0,0 +1,19 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Not needed. lll_mutex_* implementation is the same as lll_*. */
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c b/nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c
new file mode 100644
index 0000000..b2bf0cf
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c
@@ -0,0 +1,21 @@
+/* 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. */
+
+/* No difference to lowlevelmutex.c */
+#include "lowlevelmutex.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.c b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.c
new file mode 100644
index 0000000..651fb88
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.c
@@ -0,0 +1,85 @@
+/* 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 <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+
+
+int
+lll_unlock_wake_cb (futex)
+ int *futex;
+{
+ int oldval;
+ int val = *futex;
+
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap (futex, oldval, 0)) != oldval);
+ if (oldval > 1)
+ lll_futex_wake (futex, 1);
+ return 0;
+}
+hidden_proto (lll_unlock_wake_cb)
+
+
+int
+___lll_timedwait_tid (ptid, abstime)
+ int *ptid;
+ const struct timespec *abstime;
+{
+ int tid;
+
+ if (abstime == NULL || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Repeat until thread terminated. */
+ while ((tid = *ptid) != 0)
+ {
+ /* Get current time. */
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+
+ /* Determine relative timeout. */
+ struct timespec rt;
+ 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. */
+ int err = lll_futex_timed_wait (ptid, tid, &rt);
+
+ /* Woken due to timeout? */
+ if (err == -ETIMEDOUT)
+ /* Yes. */
+ return ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+hidden_proto (___lll_timedwait_tid)
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
new file mode 100644
index 0000000..8fcc7f1
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
@@ -0,0 +1,251 @@
+/* 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 _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <ia64intrin.h>
+
+#define SYS_futex 1230
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+
+/* Initializer for compatibility lock. */
+#define LLL_MUTEX_LOCK_INITIALIZER (0)
+
+#define lll_futex_clobbers \
+ "out4", "out5", "out6", "out7", \
+ /* Non-stacked integer registers, minus r8, r10, r15. */ \
+ "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \
+ "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
+ "r28", "r29", "r30", "r31", \
+ /* Predicate registers. */ \
+ "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
+ /* Non-rotating fp registers. */ \
+ "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ /* Branch registers. */ \
+ "b6", "b7", \
+ "memory"
+
+#define lll_futex_wait(futex, val) \
+ ({ \
+ register unsigned long int __o0 asm ("out0") \
+ = (unsigned long int) (futex); \
+ register unsigned long int __o1 asm ("out1") = FUTEX_WAIT; \
+ register unsigned long int __o2 asm ("out2") = (unsigned long int) (val);\
+ register unsigned long int __o3 asm ("out3") = 0ul; \
+ register unsigned long int __r8 asm ("r8"); \
+ register unsigned long int __r10 asm ("r10"); \
+ register unsigned long int __r15 asm ("r15") = SYS_futex; \
+ \
+ __asm __volatile ("break %3;;" \
+ : "=r" (__r8), "=r" (__r10), "=r" (__r15) \
+ : "i" (0x100000), "2" (__r15), "r" (__o0), "r" (__o1), \
+ "r" (__o2), "r" (__o3) \
+ : lll_futex_clobbers); \
+ __r10 == -1 ? -__r8 : __r8; \
+ })
+
+
+#define lll_futex_timed_wait(futex, val, timespec) \
+ ({ \
+ register unsigned long int __o0 asm ("out0") \
+ = (unsigned long int) (futex); \
+ register unsigned long int __o1 asm ("out1") = FUTEX_WAIT; \
+ register unsigned long int __o2 asm ("out2") = (unsigned long int) (val);\
+ register unsigned long int __o3 asm ("out3") \
+ = (unsigned long int) (timespec); \
+ register unsigned long int __r8 asm ("r8"); \
+ register unsigned long int __r10 asm ("r10"); \
+ register unsigned long int __r15 asm ("r15") = SYS_futex; \
+ \
+ __asm __volatile ("break %3;;" \
+ : "=r" (__r8), "=r" (__r10), "=r" (__r15) \
+ : "i" (0x100000), "2" (__r15), "r" (__o0), "r" (__o1), \
+ "r" (__o2), "r" (__o3) \
+ : lll_futex_clobbers); \
+ __r10 == -1 ? -__r8 : __r8; \
+ })
+
+
+#define lll_futex_wake(futex, nr) \
+ ({ \
+ register unsigned long int __o0 asm ("out0") \
+ = (unsigned long int) (futex); \
+ register unsigned long int __o1 asm ("out1") = FUTEX_WAKE; \
+ register unsigned long int __o2 asm ("out2") = (unsigned long int) (nr); \
+ register unsigned long int __r8 asm ("r8"); \
+ register unsigned long int __r10 asm ("r10"); \
+ register unsigned long int __r15 asm ("r15") = SYS_futex; \
+ \
+ __asm __volatile ("break %3;;" \
+ : "=r" (__r8), "=r" (__r10), "=r" (__r15) \
+ : "i" (0x100000), "2" (__r15), "r" (__o0), "r" (__o1), \
+ "r" (__o2) \
+ : "out3", lll_futex_clobbers); \
+ __r10 == -1 ? -__r8 : __r8; \
+ })
+
+#define lll_compare_and_swap(futex, oldval, newval) \
+ __sync_val_compare_and_swap_si ((futex), (oldval), (newval))
+
+static inline int
+__attribute__ ((always_inline))
+__lll_mutex_trylock (int *futex)
+{
+ return lll_compare_and_swap (futex, 0, 1) != 0;
+}
+#define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex))
+
+
+extern void ___lll_mutex_lock (int *, int) attribute_hidden;
+
+
+static inline void
+__attribute__ ((always_inline))
+__lll_mutex_lock (int *futex)
+{
+ int oldval;
+ int val = *futex;
+
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap (futex, oldval, oldval + 1)) != oldval);
+ if (oldval > 0)
+ ___lll_mutex_lock (futex, oldval + 1);
+}
+#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
+
+
+extern int ___lll_mutex_timedlock (int *, const struct timespec *, int)
+ attribute_hidden;
+
+
+static inline int
+__attribute__ ((always_inline))
+__lll_mutex_timedlock (int *futex, const struct timespec *abstime)
+{
+ int oldval;
+ int val = *futex;
+ int result = 0;
+
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap (futex, oldval, oldval + 1)) != oldval);
+ if (oldval > 0)
+ result = ___lll_mutex_timedlock (futex, abstime, oldval + 1);
+
+ return result;
+}
+#define lll_mutex_timedlock(futex, abstime) \
+ __lll_mutex_timedlock (&(futex), abstime)
+
+
+static inline void
+__attribute__ ((always_inline))
+__lll_mutex_unlock (int *futex)
+{
+ int oldval;
+ int val = *futex;
+
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap (futex, oldval, 0)) != oldval);
+ if (oldval > 1)
+ lll_futex_wake (futex, 1);
+}
+#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
+
+#define lll_mutex_islocked(futex) \
+ (futex != 0)
+
+
+/* We have a separate internal lock implementation which is not tied
+ to binary compatibility. We can use the lll_mutex_*. */
+
+/* Type for lock object. */
+typedef int lll_lock_t;
+
+extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
+
+/* Initializers for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+#define lll_trylock(futex) lll_mutex_trylock (futex)
+#define lll_lock(futex) lll_mutex_lock (futex)
+#define lll_unlock(futex) lll_mutex_unlock (futex)
+#define lll_islocked(futex) lll_mutex_islocked (futex)
+
+
+/* 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. */
+static inline void
+__attribute__ ((always_inline))
+__lll_wait_tid (int *ptid)
+{
+ int tid;
+
+ while ((tid = *ptid) != 0)
+ lll_futex_wait (ptid, tid);
+}
+#define lll_wait_tid(tid) __lll_wait_tid(&(tid))
+
+
+extern int ___lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+static inline int
+__attribute__ ((always_inline))
+__lll_timedwait_tid (int *ptid, const struct timespec *abstime)
+{
+ if (*ptid == 0)
+ return 0;
+
+ return ___lll_timedwait_tid (ptid, abstime);
+}
+#define lll_timedwait_tid(tid, abstime) __lll_timedwait_tid (&(tid), abstime)
+
+
+/* Conditional variable handling. */
+
+extern void __lll_cond_wait (pthread_cond_t *cond)
+ attribute_hidden;
+extern int __lll_cond_timedwait (pthread_cond_t *cond,
+ const struct timespec *abstime)
+ attribute_hidden;
+extern void __lll_cond_wake (pthread_cond_t *cond)
+ attribute_hidden;
+extern void __lll_cond_broadcast (pthread_cond_t *cond)
+ attribute_hidden;
+
+#define lll_cond_wait(cond) \
+ __lll_cond_wait (cond)
+#define lll_cond_timedwait(cond, abstime) \
+ __lll_cond_timedwait (cond, abstime)
+#define lll_cond_wake(cond) \
+ __lll_cond_wake (cond)
+#define lll_cond_broadcast(cond) \
+ __lll_cond_broadcast (cond)
+
+#endif /* lowlevellock.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c
new file mode 100644
index 0000000..7ab67ca
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c
@@ -0,0 +1,100 @@
+/* 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 <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+
+
+void
+___lll_mutex_lock (futex, newval)
+ int *futex;
+ int newval;
+{
+ int oldval, val;
+
+ do
+ {
+ lll_futex_wait (futex, newval);
+ val = *futex;
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap (futex, oldval, oldval + 1))
+ != oldval);
+ newval = val + 1;
+ }
+ while (val != 0);
+
+ *futex = 2;
+}
+hidden_proto (___lll_mutex_lock)
+
+
+int
+___lll_mutex_timedlock (futex, abstime, newval)
+ int *futex;
+ const struct timespec *abstime;
+ int newval;
+{
+ /* Reject invalid timeouts. */
+ if (abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ int oldval, val;
+ do
+ {
+ /* Get the current time. */
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ struct timespec rt;
+ 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 err = lll_futex_timed_wait (futex, newval, &rt);
+
+ /* If timed out return with an appropriate error. */
+ if (err == -ETIMEDOUT)
+ return ETIMEDOUT;
+
+ val = *futex;
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap (futex, oldval, oldval + 1))
+ != oldval);
+ newval = val + 1;
+ }
+ while (val != 0);
+
+ *futex = 2;
+
+ return 0;
+}
+hidden_proto (___lll_mutex_timedlock)
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c b/nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c
new file mode 100644
index 0000000..6155183
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c
@@ -0,0 +1,108 @@
+/* Special .init and .fini section support for ia64. NPTL version.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ The GNU C Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+__asm__ ("\n\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+ .section .init\n\
+ .align 16\n\
+ .global _init#\n\
+ .proc _init#\n\
+_init:\n\
+ alloc r34 = ar.pfs, 0, 3, 0, 0\n\
+ mov r32 = r12\n\
+ mov r33 = b0\n\
+ adds r12 = -16, r12\n\
+ ;;\n\
+/* we could use r35 to save gp, but we use the stack since that's what\n\
+ * all the other init routines will do --davidm 00/04/05 */\n\
+ st8 [r12] = gp, -16\n\
+ br.call.sptk.many b0 = __pthread_initialize_minimal_internal# ;;\n\
+ ;;\n\
+ adds r12 = 16, r12\n\
+ ;;\n\
+ ld8 gp = [r12]\n\
+ ;;\n\
+ .align 16\n\
+ .endp _init#\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+ .section .init\n\
+ .regstk 0,2,0,0\n\
+ mov r12 = r32\n\
+ mov ar.pfs = r34\n\
+ mov b0 = r33\n\
+ br.ret.sptk.many b0\n\
+ .endp _init#\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+ .section .fini\n\
+ .align 16\n\
+ .global _fini#\n\
+ .proc _fini#\n\
+_fini:\n\
+ alloc r34 = ar.pfs, 0, 3, 0, 0\n\
+ mov r32 = r12\n\
+ mov r33 = b0\n\
+ adds r12 = -16, r12\n\
+ ;;\n\
+ .align 16\n\
+ .endp _fini#\n\
+\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+ .section .fini\n\
+ mov r12 = r32\n\
+ mov ar.pfs = r34\n\
+ mov b0 = r33\n\
+ br.ret.sptk.many b0\n\
+ .endp _fini#\n\
+\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\n\
+ .weak __gmon_start__#\n\
+");
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/pt-vfork.S b/nptl/sysdeps/unix/sysv/linux/ia64/pt-vfork.S
new file mode 100644
index 0000000..7be80e9
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/pt-vfork.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <sysdep.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+/* The following are defined in linux/sched.h, which unfortunately */
+/* is not safe for inclusion in an assembly file. */
+#define CLONE_VM 0x00000100 /* set if VM shared between processes */
+#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
+
+/* pid_t vfork(void); */
+/* Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */
+
+ENTRY(__vfork)
+ alloc r2=ar.pfs,0,0,2,0
+ mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD
+ mov out1=0 /* Standard sp value. */
+ ;;
+ DO_CALL (SYS_ify (clone))
+ cmp.eq p6,p0=-1,r10
+ ;;
+(p6) br.cond.spnt.few __syscall_error
+ ret
+PSEUDO_END(__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c
new file mode 100644
index 0000000..e5cb613
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c
@@ -0,0 +1,97 @@
+/* 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 "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;
+ }
+ while ((val = lll_compare_and_swap (once_control, oldval, newval))
+ != oldval);
+
+ /* 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. */
+ val = *once_control;
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap (once_control, oldval, oldval + 1))
+ != oldval);
+
+ /* 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/nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c
new file mode 100644
index 0000000..5a75962
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c
@@ -0,0 +1,51 @@
+/* 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 <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+
+#include <shlib-compat.h>
+
+
+int
+__new_sem_post (sem_t *sem)
+{
+ int oldval, val;
+ int err;
+
+ val = *(int *) sem;
+ do
+ oldval = val;
+ while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval + 1))
+ != oldval);
+ err = lll_futex_wake ((int *) sem, oldval + 1);
+ if (err < 0)
+ {
+ __set_errno (-err);
+ return -1;
+ }
+ return 0;
+}
+versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_post, __old_sem_post)
+compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c
new file mode 100644
index 0000000..85b4e3c
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c
@@ -0,0 +1,91 @@
+/* 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 <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+
+#include <shlib-compat.h>
+
+
+int
+sem_timedwait (sem, abstime)
+ sem_t *sem;
+ const struct timespec *abstime;
+{
+ int oldval, val;
+
+ val = *(int *) sem;
+ do
+ {
+ while (__builtin_expect (val == 0, 0))
+ {
+ /* Check for invalid timeout values. */
+ if (abstime->tv_nsec >= 1000000000)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* Get the current time. */
+ struct timeval tv;
+ (void) gettimeofday(&tv, NULL);
+
+ /* Compute the relative timeout. */
+ struct timespec rt;
+ 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)
+ {
+ __set_errno (ETIMEDOUT);
+ return -1;
+ }
+
+ /* Do wait. */
+ int err = lll_futex_timed_wait ((int *) sem, 0, &rt);
+
+ /* Returned after timing out? */
+ if (err == -ETIMEDOUT)
+ {
+ __set_errno (ETIMEDOUT);
+ return -1;
+ }
+
+ /* Handle EINTR. */
+ if (err != 0 && err != -EWOULDBLOCK)
+ {
+ __set_errno (-err);
+ return -1;
+ }
+
+ val = *(int *) sem;
+ }
+ oldval = val;
+ }
+ while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval - 1))
+ != oldval);
+ return 0;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c
new file mode 100644
index 0000000..a07d346
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c
@@ -0,0 +1,50 @@
+/* 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 <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+
+#include <shlib-compat.h>
+
+
+int
+__new_sem_trywait (sem_t *sem)
+{
+ int oldval, val = *(int *) sem;
+
+ do
+ {
+ if (__builtin_expect (val == 0, 0))
+ {
+ __set_errno (EAGAIN);
+ return -1;
+ }
+ oldval = val;
+ }
+ while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval - 1))
+ != oldval);
+ return 0;
+}
+versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_trywait, __old_sem_trywait)
+compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c
new file mode 100644
index 0000000..5409237
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c
@@ -0,0 +1,63 @@
+/* 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 <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+
+#include <shlib-compat.h>
+
+
+int
+__new_sem_wait (sem_t *sem)
+{
+ int oldval, val;
+
+ /* Atomically decrement semaphore counter if it is > 0. */
+ val = *(int *) sem;
+ do
+ {
+ while (__builtin_expect (val == 0, 0))
+ {
+ /* Do wait. */
+ int err = lll_futex_wait ((int *) sem, 0);
+
+ /* Handle EINTR. */
+ if (err != 0 && err != -EWOULDBLOCK)
+ {
+ __set_errno (-err);
+ return -1;
+ }
+
+ val = *(int *) sem;
+ }
+ oldval = val;
+ }
+ while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval - 1))
+ != oldval);
+
+ return 0;
+}
+
+versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_wait, __old_sem_wait)
+compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
new file mode 100644
index 0000000..62c693c
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
@@ -0,0 +1,115 @@
+/* Copyright (C) 2002, 2003 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 <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+.text; \
+ENTRY (name) \
+ adds r14 = MULTIPLE_THREADS_OFFSET, r13;; \
+ ld4 r14 = [r14]; \
+ mov r15 = SYS_ify(syscall_name);; \
+ cmp4.ne p6, p7 = 0, r14; \
+(p6) br.cond.spnt .Lpseudo_cancel;; \
+ break __BREAK_SYSCALL;; \
+ cmp.eq p6,p0=-1,r10; \
+(p6) br.cond.spnt.few __syscall_error; \
+ ret;; \
+.Lpseudo_cancel: \
+ .prologue; \
+ .regstk args, 5, args, 0; \
+ .save ar.pfs, loc0; \
+ alloc loc0 = ar.pfs, args, 5, args, 0; \
+ .save rp, loc1; \
+ mov loc1 = rp;; \
+ .body; \
+ CENABLE;; \
+ mov loc2 = r8; \
+ COPY_ARGS_##args \
+ mov r15 = SYS_ify(syscall_name); \
+ break __BREAK_SYSCALL;; \
+ mov loc3 = r8; \
+ mov loc4 = r10; \
+ mov out0 = loc2; \
+ CDISABLE;; \
+ cmp.eq p6,p0=-1,loc4; \
+(p6) br.cond.spnt.few __syscall_error_##args; \
+ mov r8 = loc3; \
+ mov rp = loc1; \
+ mov ar.pfs = loc0; \
+.Lpseudo_end: \
+ ret; \
+ .endp name; \
+.section .gnu.linkonce.t.__syscall_error_##args, "ax"; \
+ .align 32; \
+ .proc __syscall_error_##args; \
+ .global __syscall_error_##args; \
+ .hidden __syscall_error_##args; \
+__syscall_error_##args: \
+ .prologue; \
+ .regstk args, 5, args, 0; \
+ .save ar.pfs, loc0; \
+ .save rp, loc1; \
+ .body; \
+ mov loc4 = r1;; \
+ br.call.sptk.many b0 = __errno_location;; \
+ st4 [r8] = loc3; \
+ mov r1 = loc4; \
+ mov rp = loc1; \
+ mov r8 = -1; \
+ mov ar.pfs = loc0
+
+# ifdef IS_IN_libpthread
+# define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel
+# define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel
+# else
+# define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel
+# define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel
+# endif
+
+#define COPY_ARGS_0 /* Nothing */
+#define COPY_ARGS_1 COPY_ARGS_0 mov out0 = in0;
+#define COPY_ARGS_2 COPY_ARGS_1 mov out1 = in1;
+#define COPY_ARGS_3 COPY_ARGS_2 mov out2 = in2;
+#define COPY_ARGS_4 COPY_ARGS_3 mov out3 = in3;
+#define COPY_ARGS_5 COPY_ARGS_4 mov out4 = in4;
+#define COPY_ARGS_6 COPY_ARGS_5 mov out5 = in5;
+#define COPY_ARGS_7 COPY_ARGS_6 mov out6 = in6;
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P \
+ adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow. */
+# define SINGLE_THREAD_P (1)
+
+#endif