latest merged ppc 32/64 NPTL port

Paul Mackerras <[email protected]>
Newsgroups gmane.comp.lib.phil
Message-ID <[email protected]>
Here is the patch with all the new files needed for NPTL to run on 32
and 64 bit PowerPC under Linux.  I have merged in Steve's changes and
fixed up the coding style.  As suggested by Ulrich, I have moved the
lowlevel lock/mutex/semaphore .c files to sysdeps/unix/sysv/linux and
the pthread spin init/unlock procedures to sysdeps/pthread.  I define
a symbol __LIBC_LOWLEVELLOCK in libc-lowlevellock.c and check that in
lowlevellock.c so that lll_unlock_wake_cb and lll_timedwait_tid don't
get included when compiling libc-lowlevellock.c.

I am using current CVS binutils and current CVS gcc from the
gcc-3_3-branch with a patch from Alan Modra which is available at:

ftp://ftp.linuxppc64.org/pub/people/amodra/gcc-3.3/gcc-20030314-ppc64.diff.gz

In order to pass all the tests I also need to change cleanup.c to
eliminate a bogus assumption about the relative addresses of cleanup
buffers.  There are also a couple of changes required to the rest of
glibc that I have posted.

I haven't changed my versions of lowlevel*.[ch] to use atomic_add
instead of __lll_add because including atomic.h in lowlevellock.h
causes compile errors elsewhere in glibc.


diff -urN nptl-0.29/nptl/sysdeps/powerpc/Makefile libc/nptl/sysdeps/powerpc/Makefile
--- nptl-0.29/nptl/sysdeps/powerpc/Makefile	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/powerpc/Makefile	Wed Mar 05 16:03:37 2003
@@ -0,0 +1,21 @@
+# Copyright (C) 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.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff -urN nptl-0.29/nptl/sysdeps/powerpc/pthread_spin_lock.c libc/nptl/sysdeps/powerpc/pthread_spin_lock.c
--- nptl-0.29/nptl/sysdeps/powerpc/pthread_spin_lock.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/powerpc/pthread_spin_lock.c	Mon Mar 10 22:30:06 2003
@@ -0,0 +1,45 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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;
+{
+  unsigned int __tmp;
+
+  asm volatile (
+       "1:	lwarx	%0,0,%1\n"
+       "	cmpwi	0,%0,0\n"
+       "	bne-	2f\n"
+       "	stwcx.	%2,0,%1\n"
+       "	bne-	2f\n"
+       "	isync\n"
+       "	.subsection 1\n"
+       "2:	lwzx	%0,0,%1\n"
+       "	cmpwi	0,%0,0\n"
+       "	bne	2b\n"
+       "	b	1b\n"
+       "	.previous"
+       : "=&r" (__tmp)
+       : "r" (lock), "r" (1)
+       : "cr0", "memory");
+  return 0;
+}
diff -urN nptl-0.29/nptl/sysdeps/powerpc/pthread_spin_trylock.c libc/nptl/sysdeps/powerpc/pthread_spin_trylock.c
--- nptl-0.29/nptl/sysdeps/powerpc/pthread_spin_trylock.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/powerpc/pthread_spin_trylock.c	Wed Mar 05 14:44:53 2003
@@ -0,0 +1,43 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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;
+{
+  unsigned int old;
+  int err = EBUSY;
+
+  asm ("1:	lwarx	%0,0,%2\n"
+       "	cmpwi	0,%0,0\n"
+       "	bne	2f\n"
+       "	stwcx.	%3,0,%2\n"
+       "	bne-	1b\n"
+       "	li	%1,0\n"
+       "	isync\n"
+       "2:	"
+       : "=&r" (old), "=&r" (err)
+       : "r" (lock), "r" (1), "1" (err)
+       : "cr0", "memory");
+
+  return err;
+}
diff -urN nptl-0.29/nptl/sysdeps/powerpc/pthreaddef.h libc/nptl/sysdeps/powerpc/pthreaddef.h
--- nptl-0.29/nptl/sysdeps/powerpc/pthreaddef.h	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/powerpc/pthreaddef.h	Sat Mar 15 12:45:07 2003
@@ -0,0 +1,44 @@
+/* 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	(4 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  The ABI requires 16
+   bytes (for both 32-bit and 64-bit PowerPC).  */
+#define STACK_ALIGN		16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK	4096
+
+/* 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	__builtin_frame_address (0)
+
+
+/* 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 -urN nptl-0.29/nptl/sysdeps/powerpc/tcb-offsets.sym libc/nptl/sysdeps/powerpc/tcb-offsets.sym
--- nptl-0.29/nptl/sysdeps/powerpc/tcb-offsets.sym	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/powerpc/tcb-offsets.sym	Sat Mar 15 12:45:14 2003
@@ -0,0 +1,12 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+# undef __thread_register
+# define __thread_register	((void *) 0)
+# define thread_offsetof(mem)	((void *) &THREAD_SELF->mem - (void *) 0)
+
+MULTIPLE_THREADS_OFFSET		thread_offsetof (multiple_threads)
+
diff -urN nptl-0.29/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c libc/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c
--- nptl-0.29/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c	Sat Mar 15 11:49:17 2003
@@ -0,0 +1,44 @@
+/* Which thread is running on an LWP?  PowerPC version.
+   Copyright (C) 2002 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;
+
+  th->th_unique = (void *) regs[PT_THREAD_POINTER] - TLS_TCB_OFFSET
+                  - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE;
+
+  /* Found it.  Now complete the `td_thrhandle_t' object.  */
+  th->th_ta_p = (td_thragent_t *) ta;
+
+  return TD_OK;
+}
diff -urN nptl-0.29/nptl/sysdeps/powerpc/tls.h libc/nptl/sysdeps/powerpc/tls.h
--- nptl-0.29/nptl/sysdeps/powerpc/tls.h	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/powerpc/tls.h	Sat Mar 15 12:45:50 2003
@@ -0,0 +1,152 @@
+/* Definition for thread-local data handling.  NPTL/PowerPC 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>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+/* 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
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* The TP points to the start of the thread blocks.  */
+# define TLS_DTV_AT_TP	1
+
+/* For 32-bit, we use the multiple_threads field in the pthread struct */
+#ifndef __powerpc64__
+#define TLS_MULTIPLE_THREADS_IN_TCB	1
+#endif
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+/* This layout is actually wholly private and not affected by the ABI.
+   Nor does it overlap the pthread data structure, so we need nothing
+   extra here at all.  */
+typedef struct
+{
+  dtv_t *dtv;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN	__alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE		sizeof (tcbhead_t)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN		__alignof__ (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+# define TLS_PRE_TCB_SIZE	sizeof (struct pthread)
+
+/* XXX if __alignof__ (struct pthread) > __alignof (tcbhead_t)
+   we could be in trouble.  -- paulus */
+
+# ifndef __powerpc64__
+/* Register r2 (tp) is reserved by the ABI as "thread pointer". */
+register void *__thread_register __asm__ ("r2");
+#  define PT_THREAD_POINTER PT_R2
+# else
+/* Register r13 (tp) is reserved by the ABI as "thread pointer". */
+register void *__thread_register __asm__ ("r13");
+#  define PT_THREAD_POINTER PT_R13
+# endif
+
+/* The following assumes that TP (R2 or R13) points to the end of the
+   TCB + 0x7000 (per the ABI).  This implies that TCB address is
+   TP-(TLS_TCB_SIZE + 0x7000).  As we define TLS_DTV_AT_TP we can
+   assume that the pthread struct is allocated immediately ahead of the
+   TCB.  This implies that the pthread_descr address is
+   TP-(TLS_PRE_TCB_SIZE + TLS_TCB_SIZE + 0x7000).  */
+# define TLS_TCB_OFFSET	0x7000
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(tcbp, dtvp) \
+  ((tcbhead_t *) (tcbp))->dtv = dtvp + 1
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) (THREAD_DTV() = (dtv))
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(tcbp)	(((tcbhead_t *) (tcbp))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(tcbp, secondcall) \
+    (__thread_register = (void *) (tcbp) + TLS_TCB_OFFSET + TLS_TCB_SIZE, NULL)
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+     (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET - TLS_TCB_SIZE))->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+    ((struct pthread *) (__thread_register \
+			 - TLS_TCB_OFFSET - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE))
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member)
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) \
+    ((void)(descr), (THREAD_SELF)->member[idx])
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+    ((void)(descr), (THREAD_SELF)->member = (value))
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+    ((void)(descr), (THREAD_SELF)->member[idx] = (value))
+
+#endif /* __ASSEMBLER__ */
+
+#endif	/* tls.h */
diff -urN nptl-0.29/nptl/sysdeps/pthread/pthread_spin_init.c libc/nptl/sysdeps/pthread/pthread_spin_init.c
--- nptl-0.29/nptl/sysdeps/pthread/pthread_spin_init.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/pthread/pthread_spin_init.c	Mon Mar 10 12:47:16 2003
@@ -0,0 +1,27 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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_init (pthread_spinlock_t *lock, int pshared)
+{
+  *lock = 0;
+  return 0;
+}
diff -urN nptl-0.29/nptl/sysdeps/pthread/pthread_spin_unlock.c libc/nptl/sysdeps/pthread/pthread_spin_unlock.c
--- nptl-0.29/nptl/sysdeps/pthread/pthread_spin_unlock.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/pthread/pthread_spin_unlock.c	Sat Mar 15 14:36:41 2003
@@ -0,0 +1,29 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 <atomic.h>
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  atomic_full_barrier ();
+  *lock = 0;
+  return 0;
+}
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c libc/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c	Sat Mar 15 12:19:58 2003
@@ -0,0 +1,22 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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.  */
+#define __LIBC_LOWLEVELLOCK
+#include "lowlevellock.c"
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/libc-lowlevelmutex.c libc/nptl/sysdeps/unix/sysv/linux/libc-lowlevelmutex.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/libc-lowlevelmutex.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/libc-lowlevelmutex.c	Sat Mar 15 12:21:09 2003
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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.  */
+
+/* Nothing needed here in fact.  */
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/lowlevellock.c libc/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/lowlevellock.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/lowlevellock.c	Sat Mar 15 15:16:52 2003
@@ -0,0 +1,138 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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_lock_wait (int *futex, int val)
+{
+  do {
+      lll_futex_wait (futex, val+1);
+  } while ((val = __lll_add (futex, 1)) != 0);
+  *futex = 2;
+}
+hidden_proto (__lll_lock_wait)
+
+
+int
+__lll_timedlock_wait (int *futex, int val, const struct timespec *abstime)
+{
+  int err;
+
+  /* Reject invalid timeouts.  */
+  if (abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+
+  do {
+    struct timeval tv;
+    struct timespec rt;
+    int sec, nsec;
+
+    /* Get the current time.  */
+    gettimeofday (&tv, NULL);
+
+    /* Compute relative timeout.  */
+    sec = abstime->tv_sec - tv.tv_sec;
+    nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+    if (nsec < 0)
+      {
+	nsec += 1000000000;
+	--sec;
+      }
+
+    /* Already timed out?  */
+    err = -ETIMEDOUT;
+    if (sec < 0)
+      break;
+
+    /* Wait.  */
+    rt.tv_sec = sec;
+    rt.tv_nsec = nsec;
+    err = lll_futex_timed_wait (futex, val+1, &rt);
+  } while (err == 0 && (val = __lll_add (futex, 1)) != 0);
+
+  *futex = 2;
+  return -err;
+}
+hidden_proto (__lll_timedlock_wait)
+
+
+/* These don't get included in libc.so  */
+#ifndef __LIBC_LOWLEVELLOCK
+int
+lll_unlock_wake_cb (int *futex)
+{
+  __lll_add (futex, 1);
+  return 0;
+}
+hidden_proto (lll_unlock_wake_cb)
+
+
+int
+__lll_timedwait_tid (int *tidp, const struct timespec *abstime)
+{
+  int tid;
+  int err = 0;
+
+  if (abstime == NULL || abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+
+  /* Repeat until thread terminated.  */
+  while ((tid = *tidp) != 0)
+    {
+      struct timeval tv;
+      struct timespec rt;
+      int sec, nsec;
+
+      /* Get the current time.  */
+      gettimeofday (&tv, NULL);
+
+      /* Compute relative timeout.  */
+      sec = abstime->tv_sec - tv.tv_sec;
+      nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      if (nsec < 0)
+	{
+	  nsec += 1000000000;
+	  --sec;
+	}
+
+      /* Already timed out?  */
+      err = -ETIMEDOUT;
+      if (sec < 0)
+	break;
+
+      /* Wait.  */
+      rt.tv_sec = sec;
+      rt.tv_nsec = nsec;
+
+      /* Wait until thread terminates.  */
+      err = lll_futex_timed_wait (tidp, tid, &rt);
+      if (err != 0)
+	break;
+    }
+
+  return -err;
+}
+
+hidden_proto (__lll_timedwait_tid)
+#endif
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/lowlevelmutex.c libc/nptl/sysdeps/unix/sysv/linux/lowlevelmutex.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/lowlevelmutex.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/lowlevelmutex.c	Sat Mar 08 12:59:38 2003
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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.  */
+
+/* Nothing needed here in fact.  */
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile libc/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile	Mon Mar 10 14:36:50 2003
@@ -0,0 +1,2 @@
+# pull in __syscall_error routine
+libpthread-routines += sysdep
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h libc/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h	Wed Mar 05 14:13:24 2003
@@ -0,0 +1,166 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 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 deliberately not exposed.  */
+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 deliberately not exposed.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    int __pad;
+    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 deliberately not exposed.  */
+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;
+    /* 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 -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h libc/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h	Wed Mar 05 14:20:01 2003
@@ -0,0 +1,43 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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   ((int) ((~0u) >> 1))
+
+
+typedef union
+{
+  char __size[__SIZEOF_SEM_T];
+  long int __align;
+} sem_t;
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c libc/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c	Fri Mar 07 15:57:41 2003
@@ -0,0 +1,24 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>.
+
+   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 ((void *)(pd) + TLS_TCB_OFFSET + TLS_TCB_SIZE + TLS_PRE_TCB_SIZE)
+
+/* Get the real implementation.	 */
+#include <nptl/sysdeps/pthread/createthread.c>
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c libc/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c	Sat Mar 15 12:46:04 2003
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 (clone, 5,						      \
+		  CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \
+		  NULL, NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h	Sat Mar 15 15:16:03 2003
@@ -0,0 +1,224 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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>
+
+#define __NR_futex		221
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+
+/* Initializer for compatibility lock.	*/
+#define LLL_MUTEX_LOCK_INITIALIZER (0)
+
+#define lll_futex_wait(futexp, val)				\
+  ({								\
+    INTERNAL_SYSCALL_DECL (__err);				\
+    long int __ret;						\
+								\
+    __ret = INTERNAL_SYSCALL (futex, __err, 4,			\
+			      (futexp), FUTEX_WAIT, (val), 0);	\
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret: 0;		\
+  })
+
+#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));	\
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret: 0;			\
+  })
+
+#define lll_futex_wake(futexp, nr) 				\
+  ({								\
+    INTERNAL_SYSCALL_DECL (__err);				\
+    long int __ret;						\
+								\
+    __ret = INTERNAL_SYSCALL (futex, __err, 4,			\
+			      (futexp), FUTEX_WAKE, (nr), 0);	\
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret: 0;		\
+  })
+
+#ifdef UP
+#define __lll_acq_instr	""
+#define __lll_rel_instr	""
+#else
+#define __lll_acq_instr	"isync"
+#define __lll_rel_instr	"sync"
+#endif
+
+/* Set *futex to 1 if it is 0, atomically.  Returns the old value */
+#define __lll_trylock(futex)				\
+  ({ int __val;							\
+     __asm __volatile ("1:	lwarx	%0,0,%2\n"		\
+		       "	cmpwi	0,%0,0\n"		\
+		       "	bne	2f\n"			\
+		       "	stwcx.	%3,0,%2\n"		\
+		       "	bne-	1b\n"			\
+		       "2:	" __lll_acq_instr		\
+		       : "=&r" (__val), "=m" (*futex)		\
+		       : "r" (futex), "r" (1), "1" (*futex)	\
+		       : "cr0", "memory");			\
+     __val;							\
+  })
+
+#define lll_mutex_trylock(lock)	__lll_trylock(&(lock))
+
+/* Add inc to *futex atomically and return the old value. */
+#define __lll_add(futex, inc)						\
+  ({ int __val, __tmp;							\
+     __asm __volatile ("1:	lwarx	%0,0,%3\n"			\
+		       "	addi	%1,%0,%4\n"			\
+		       "	stwcx.	%1,0,%3\n"			\
+		       "	bne-	1b"				\
+		       : "=&b" (__val), "=&r" (__tmp), "=m" (*futex)	\
+		       : "r" (futex), "I" (inc), "2" (*futex)		\
+		       : "cr0");					\
+     __val;								\
+  })
+
+extern void __lll_lock_wait (int *futex, int val) attribute_hidden;
+
+#define lll_mutex_lock(lock)				\
+  (void) ({						\
+    int *__futex = &(lock);				\
+    int __val = __lll_add (__futex, 1);			\
+    __asm __volatile (__lll_acq_instr ::: "memory");	\
+    if (__builtin_expect (__val != 0, 0))		\
+      __lll_lock_wait (__futex, __val);			\
+  })
+
+extern int __lll_timedlock_wait
+	(int *futex, int val, const struct timespec *) attribute_hidden;
+
+#define lll_mutex_timedlock(lock, abstime)			\
+  ({ int *__futex = &(lock);						\
+     int __val = __lll_add (__futex, 1);				\
+     __asm __volatile (__lll_acq_instr ::: "memory");			\
+     if (__builtin_expect (__val != 0, 0))				\
+       __val = __lll_timedlock_wait (__futex, __val, (abstime));	\
+     __val;								\
+  })
+
+#define lll_mutex_unlock(lock)				\
+  (void) ({						\
+    int *__futex = &(lock);				\
+     __asm __volatile (__lll_rel_instr ::: "memory");	\
+    int __val = __lll_add (__futex, -1);		\
+    if (__builtin_expect (__val != 1, 0))		\
+      {							\
+	*__futex = 0;					\
+	lll_futex_wake (__futex, 1);			\
+      }							\
+  })
+
+#define lll_mutex_islocked(futex) \
+  (futex != 0)
+
+
+/* Our internal lock implementation is identical to the binary-compatible
+   mutex implementation. */
+
+/* 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;
+
+/* The states of a lock are:
+    0  -  untaken
+    1  -  taken by one user
+   >1  -  taken by more users */
+
+#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 which 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;						\
+  })
+
+
+/* Decrement *futex if it is > 0, and return the old value */
+#define __lll_dec_if_positive(futex)					\
+  ({ int __val, __tmp;							\
+     __asm __volatile ("1:	lwarx	%0,0,%3\n"			\
+		       "	cmpwi	0,%0,0\n"			\
+		       "	addi	%1,%0,-1\n"			\
+		       "	ble	2f\n"				\
+		       "	stwcx.	%1,0,%3\n"			\
+		       "	bne-	1b\n"				\
+		       "2:	" __lll_acq_instr			\
+		       : "=&b" (__val), "=&r" (__tmp), "=m" (*futex)	\
+		       : "r" (futex), "2" (*futex)			\
+		       : "cr0");					\
+     __val;								\
+  })
+
+
+/* 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 -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h libc/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	Sat Mar 15 11:51:17 2003
@@ -0,0 +1,100 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Franz Sirl <[email protected]>, 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 <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)				\
+  .section ".text";							\
+  ENTRY (name)								\
+    SINGLE_THREAD_P;							\
+    bne- .Lpseudo_cancel;						\
+    DO_CALL (SYS_ify (syscall_name));					\
+    PSEUDO_RET;								\
+  .Lpseudo_cancel:							\
+    stwu 1,-48(1);							\
+    mflr 9;								\
+    stw 9,52(1);							\
+    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
+    CENABLE;								\
+    stw 3,16(1);	/* store CENABLE return value (MASK).  */	\
+    UNDOCARGS_##args;	/* restore syscall args.  */			\
+    DO_CALL (SYS_ify (syscall_name));					\
+    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\
+    stw 3,8(1);								\
+    stw 0,12(1);							\
+    lwz 3,16(1);	/* pass MASK to CDISABLE.  */			\
+    CDISABLE;								\
+    lwz 4,52(1);							\
+    lwz 0,12(1);	/* restore CR/R3. */				\
+    lwz 3,8(1);								\
+    mtlr 4;								\
+    mtcr 0;								\
+    addi 1,1,48;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1	stw 3,20(1); DOCARGS_0
+# define UNDOCARGS_1	lwz 3,20(1); UNDOCARGS_0
+
+# define DOCARGS_2	stw 4,24(1); DOCARGS_1
+# define UNDOCARGS_2	lwz 4,24(1); UNDOCARGS_1
+
+# define DOCARGS_3	stw 5,28(1); DOCARGS_2
+# define UNDOCARGS_3	lwz 5,28(1); UNDOCARGS_2
+
+# define DOCARGS_4	stw 6,32(1); DOCARGS_3
+# define UNDOCARGS_4	lwz 6,32(1); UNDOCARGS_3
+
+# define DOCARGS_5	stw 7,36(1); DOCARGS_4
+# define UNDOCARGS_5	lwz 7,36(1); UNDOCARGS_4
+
+# define DOCARGS_6	stw 8,40(1); DOCARGS_5
+# define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	bl JUMPTARGET(__pthread_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__pthread_disable_asynccancel)
+# else
+#  define CENABLE	bl JUMPTARGET(__libc_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__libc_disable_asynccancel)
+# endif
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P						\
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P						\
+  lwz 10,MULTIPLE_THREADS_OFFSET(2);					\
+  cmpwi 10,0
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h libc/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h	Sat Mar 15 09:05:23 2003
@@ -0,0 +1,101 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Franz Sirl <[email protected]>, 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 <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)				\
+  .section ".text";							\
+  ENTRY (name)								\
+    SINGLE_THREAD_P;							\
+    bne- .Lpseudo_cancel;						\
+    DO_CALL (SYS_ify (syscall_name));					\
+    PSEUDO_RET;								\
+  .Lpseudo_cancel:							\
+    stdu 1,-128(1);							\
+    mflr 9;								\
+    std  9,128+16(1);							\
+    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
+    CENABLE;								\
+    std  3,72(1);	/* store CENABLE return value (MASK).  */	\
+    UNDOCARGS_##args;	/* restore syscall args.  */			\
+    DO_CALL (SYS_ify (syscall_name));					\
+    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\
+    std  3,64(1);								\
+    std  0,8(1);							\
+    ld   3,72(1);	/* pass MASK to CDISABLE.  */			\
+    CDISABLE;								\
+    ld   9,128+16(1);							\
+    ld   0,8(1);	/* restore CR/R3. */				\
+    ld   3,64(1);								\
+    mtlr 9;								\
+    mtcr 0;								\
+    addi 1,1,128;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1	std 3,80(1); DOCARGS_0
+# define UNDOCARGS_1	ld 3,80(1); UNDOCARGS_0
+
+# define DOCARGS_2	std 4,88(1); DOCARGS_1
+# define UNDOCARGS_2	ld 4,88(1); UNDOCARGS_1
+
+# define DOCARGS_3	std 5,96(1); DOCARGS_2
+# define UNDOCARGS_3	ld 5,96(1); UNDOCARGS_2
+
+# define DOCARGS_4	std 6,104(1); DOCARGS_3
+# define UNDOCARGS_4	ld 6,104(1); UNDOCARGS_3
+
+# define DOCARGS_5	std 7,112(1); DOCARGS_4
+# define UNDOCARGS_5	ld 7,112(1); UNDOCARGS_4
+
+# define DOCARGS_6	std 8,120(1); DOCARGS_5
+# define UNDOCARGS_6	ld 8,120(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	bl JUMPTARGET(__pthread_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__pthread_disable_asynccancel)
+# else
+#  define CENABLE	bl JUMPTARGET(__libc_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__libc_disable_asynccancel)
+# endif
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P						\
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, multiple_threads) \
+		    == 0, 1)
+# else
+#   define SINGLE_THREAD_P						\
+  lwz   10,MULTIPLE_THREADS_OFFSET(13);				\
+  cmpdi 10,0
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/pt-vfork.S libc/nptl/sysdeps/unix/sysv/linux/powerpc/pt-vfork.S
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/pt-vfork.S	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/pt-vfork.S	Fri Mar 07 09:14:43 2003
@@ -0,0 +1,35 @@
+/* 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 <sysdep-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+	DO_CALL (SYS_ify (vfork));
+	PSEUDO_RET
+
+PSEUDO_END (__vfork)
+
+weak_alias (__vfork, vfork)
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c	Sat Mar 15 15:14:41 2003
@@ -0,0 +1,99 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 (pthread_once_t *once_control, void (*init_routine) (void))
+{
+  for (;;)
+    {
+      int oldval;
+      int newval;
+      int tmp;
+
+      /* Pseudo code:
+	 newval = __fork_generation | 1;
+	 oldval = *once_control;
+	 if ((oldval & 2) == 0)
+	   *once_control = newval;
+	 Do this atomically.
+      */
+      newval = __fork_generation | 1;
+      __asm __volatile ("1:	lwarx	%0,0,%3\n"
+			"	andi.	%1,%0,2\n"
+			"	bne	2f\n"
+			"	stwcx.	%4,0,%3\n"
+			"2:	isync"
+			: "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
+			: "r" (once_control), "r" (newval), "m" (*once_control)
+			: "cr0");
+
+      /* Check if the initializer has already been done.  */
+      if ((oldval & 2) != 0)
+	return 0;
+
+      /* Check if another thread already runs the initializer.	*/
+      if ((oldval & 1) == 0)
+	break;
+
+      /* Check whether the initializer execution was interrupted by a fork.  */
+      if (oldval != newval)
+	break;
+
+      /* Same generation, some other thread was faster. Wait.  */
+      lll_futex_wait (once_control, oldval);
+    }
+
+
+  /* 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 to take the bottom 2 bits from 01 to 10.  */
+  __lll_add (once_control, 1);
+
+  /* Wake up all other threads.  */
+  lll_futex_wake (once_control, INT_MAX);
+
+  return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_post.c libc/nptl/sysdeps/unix/sysv/linux/sem_post.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_post.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/sem_post.c	Sat Mar 15 12:49:25 2003
@@ -0,0 +1,46 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 <semaphore.h>
+
+#include <shlib-compat.h>
+
+int
+__new_sem_post (sem_t *sem)
+{
+  int *futex = (int *) sem;
+  int err, nr;
+
+  __asm __volatile (__lll_rel_instr ::: "memory");
+  nr = __lll_add (futex, 1);
+  err = lll_futex_wake (futex, nr);
+  if (err == 0)
+    return 0;
+  __set_errno (-err);
+  return -1;
+}
+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 -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c	Sat Mar 15 15:18:05 2003
@@ -0,0 +1,84 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 <semaphore.h>
+
+#include <shlib-compat.h>
+
+
+int
+sem_timedwait (sem_t *sem, const struct timespec *abstime)
+{
+  int *futex = (int *) sem;
+  int val;
+  int err;
+
+  if (*futex > 0)
+    {
+      val = __lll_dec_if_positive (futex);
+      if (val > 0)
+	return 0;
+    }
+
+  err = -EINVAL;
+  if (abstime->tv_nsec >= 1000000000)
+    goto error_return;
+
+  do {
+    struct timeval tv;
+    struct timespec rt;
+    int sec, nsec;
+
+    /* Get the current time.  */
+    gettimeofday (&tv, NULL);
+
+    /* Compute relative timeout.  */
+    sec = abstime->tv_sec - tv.tv_sec;
+    nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+    if (nsec < 0)
+      {
+	nsec += 1000000000;
+	--sec;
+      }
+
+    /* Already timed out?  */
+    err = -ETIMEDOUT;
+    if (sec < 0)
+      goto error_return;
+
+    /* Do wait.  */
+    rt.tv_sec = sec;
+    rt.tv_nsec = nsec;
+    err = lll_futex_timed_wait (futex, 0, &rt);
+    if (err != 0 && err != -EWOULDBLOCK)
+      goto error_return;
+
+    val = __lll_dec_if_positive (futex);
+  } while (val <= 0);
+
+  return 0;
+
+ error_return:
+  __set_errno (-err);
+  return -1;
+}
diff -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_trywait.c libc/nptl/sysdeps/unix/sysv/linux/sem_trywait.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_trywait.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/sem_trywait.c	Sat Mar 15 15:17:31 2003
@@ -0,0 +1,49 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 <semaphore.h>
+
+#include <shlib-compat.h>
+
+
+int
+__new_sem_trywait (sem_t *sem)
+{
+  int *futex = (int *) sem;
+  int val;
+
+  if (*futex > 0)
+    {
+      val = __lll_dec_if_positive (futex);
+      if (val > 0)
+	return 0;
+    }
+
+  __set_errno (EAGAIN);
+  return -1;
+}
+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 -urN nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_wait.c libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c
--- nptl-0.29/nptl/sysdeps/unix/sysv/linux/sem_wait.c	Thu Jan 01 10:00:00 1970
+++ libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c	Sat Mar 15 15:17:20 2003
@@ -0,0 +1,55 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <[email protected]>, 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 <semaphore.h>
+
+#include <shlib-compat.h>
+
+
+int
+__new_sem_wait (sem_t *sem)
+{
+  int *futex = (int *) sem;
+  int val;
+  int err;
+
+  do {
+    if (*futex > 0)
+      {
+	val = __lll_dec_if_positive (futex);
+	if (val > 0)
+	  return 0;
+      }
+
+    err = lll_futex_wait (futex, 0);
+  } while (err == 0 || err == -EWOULDBLOCK);
+
+  __set_errno (-err);
+  return -1;
+}
+
+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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.