OSDN Git Service

Import in NPTL code from glibc. For further information please
author"Steven J. Hill" <sjhill@realitydiluted.com>
Sat, 7 May 2005 02:04:55 +0000 (02:04 -0000)
committer"Steven J. Hill" <sjhill@realitydiluted.com>
Sat, 7 May 2005 02:04:55 +0000 (02:04 -0000)
consult the 'README.NPTL' file.

264 files changed:
libpthread/README.NPTL [new file with mode: 0644]
libpthread/nptl/ANNOUNCE [new file with mode: 0644]
libpthread/nptl/Banner [new file with mode: 0644]
libpthread/nptl/ChangeLog [new file with mode: 0644]
libpthread/nptl/DESIGN-barrier.txt [new file with mode: 0644]
libpthread/nptl/DESIGN-condvar.txt [new file with mode: 0644]
libpthread/nptl/DESIGN-rwlock.txt [new file with mode: 0644]
libpthread/nptl/DESIGN-sem.txt [new file with mode: 0644]
libpthread/nptl/Makefile [new file with mode: 0644]
libpthread/nptl/TODO [new file with mode: 0644]
libpthread/nptl/TODO-kernel [new file with mode: 0644]
libpthread/nptl/TODO-testing [new file with mode: 0644]
libpthread/nptl/Versions [new file with mode: 0644]
libpthread/nptl/alloca_cutoff.c [new file with mode: 0644]
libpthread/nptl/allocatestack.c [new file with mode: 0644]
libpthread/nptl/cancellation.c [new file with mode: 0644]
libpthread/nptl/cleanup.c [new file with mode: 0644]
libpthread/nptl/cleanup_compat.c [new file with mode: 0644]
libpthread/nptl/cleanup_defer.c [new file with mode: 0644]
libpthread/nptl/cleanup_defer_compat.c [new file with mode: 0644]
libpthread/nptl/cleanup_routine.c [new file with mode: 0644]
libpthread/nptl/cond-perf.c [new file with mode: 0644]
libpthread/nptl/descr.h [new file with mode: 0644]
libpthread/nptl/eintr.c [new file with mode: 0644]
libpthread/nptl/events.c [new file with mode: 0644]
libpthread/nptl/forward.c [new file with mode: 0644]
libpthread/nptl/herrno.c [new file with mode: 0644]
libpthread/nptl/init.c [new file with mode: 0644]
libpthread/nptl/libc-cancellation.c [new file with mode: 0644]
libpthread/nptl/old_pthread_atfork.c [new file with mode: 0644]
libpthread/nptl/old_pthread_cond_broadcast.c [new file with mode: 0644]
libpthread/nptl/old_pthread_cond_destroy.c [new file with mode: 0644]
libpthread/nptl/old_pthread_cond_init.c [new file with mode: 0644]
libpthread/nptl/old_pthread_cond_signal.c [new file with mode: 0644]
libpthread/nptl/old_pthread_cond_timedwait.c [new file with mode: 0644]
libpthread/nptl/old_pthread_cond_wait.c [new file with mode: 0644]
libpthread/nptl/perf.c [new file with mode: 0644]
libpthread/nptl/pt-allocrtsig.c [new file with mode: 0644]
libpthread/nptl/pt-cleanup.c [new file with mode: 0644]
libpthread/nptl/pt-system.c [new file with mode: 0644]
libpthread/nptl/pthread-errnos.sym [new file with mode: 0644]
libpthread/nptl/pthreadP.h [new file with mode: 0644]
libpthread/nptl/pthread_atfork.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getdetachstate.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getguardsize.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getinheritsched.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getschedparam.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getschedpolicy.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getscope.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getstack.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getstackaddr.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_getstacksize.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_init.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setdetachstate.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setguardsize.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setinheritsched.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setschedparam.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setschedpolicy.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setscope.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setstack.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setstackaddr.c [new file with mode: 0644]
libpthread/nptl/pthread_attr_setstacksize.c [new file with mode: 0644]
libpthread/nptl/pthread_barrier_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_barrier_init.c [new file with mode: 0644]
libpthread/nptl/pthread_barrierattr_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_barrierattr_getpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_barrierattr_init.c [new file with mode: 0644]
libpthread/nptl/pthread_barrierattr_setpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_cancel.c [new file with mode: 0644]
libpthread/nptl/pthread_clock_gettime.c [new file with mode: 0644]
libpthread/nptl/pthread_clock_settime.c [new file with mode: 0644]
libpthread/nptl/pthread_cond_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_cond_init.c [new file with mode: 0644]
libpthread/nptl/pthread_condattr_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_condattr_getclock.c [new file with mode: 0644]
libpthread/nptl/pthread_condattr_getpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_condattr_init.c [new file with mode: 0644]
libpthread/nptl/pthread_condattr_setclock.c [new file with mode: 0644]
libpthread/nptl/pthread_condattr_setpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_create.c [new file with mode: 0644]
libpthread/nptl/pthread_detach.c [new file with mode: 0644]
libpthread/nptl/pthread_equal.c [new file with mode: 0644]
libpthread/nptl/pthread_exit.c [new file with mode: 0644]
libpthread/nptl/pthread_getattr_np.c [new file with mode: 0644]
libpthread/nptl/pthread_getconcurrency.c [new file with mode: 0644]
libpthread/nptl/pthread_getschedparam.c [new file with mode: 0644]
libpthread/nptl/pthread_getspecific.c [new file with mode: 0644]
libpthread/nptl/pthread_join.c [new file with mode: 0644]
libpthread/nptl/pthread_key_create.c [new file with mode: 0644]
libpthread/nptl/pthread_key_delete.c [new file with mode: 0644]
libpthread/nptl/pthread_kill_other_threads.c [new file with mode: 0644]
libpthread/nptl/pthread_mutex_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_mutex_init.c [new file with mode: 0644]
libpthread/nptl/pthread_mutex_lock.c [new file with mode: 0644]
libpthread/nptl/pthread_mutex_timedlock.c [new file with mode: 0644]
libpthread/nptl/pthread_mutex_trylock.c [new file with mode: 0644]
libpthread/nptl/pthread_mutex_unlock.c [new file with mode: 0644]
libpthread/nptl/pthread_mutexattr_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_mutexattr_getpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_mutexattr_gettype.c [new file with mode: 0644]
libpthread/nptl/pthread_mutexattr_init.c [new file with mode: 0644]
libpthread/nptl/pthread_mutexattr_setpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_mutexattr_settype.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlock_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlock_init.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlock_tryrdlock.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlock_trywrlock.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlockattr_destroy.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlockattr_getkind_np.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlockattr_getpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlockattr_init.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlockattr_setkind_np.c [new file with mode: 0644]
libpthread/nptl/pthread_rwlockattr_setpshared.c [new file with mode: 0644]
libpthread/nptl/pthread_self.c [new file with mode: 0644]
libpthread/nptl/pthread_setcancelstate.c [new file with mode: 0644]
libpthread/nptl/pthread_setcanceltype.c [new file with mode: 0644]
libpthread/nptl/pthread_setconcurrency.c [new file with mode: 0644]
libpthread/nptl/pthread_setegid.c [new file with mode: 0644]
libpthread/nptl/pthread_seteuid.c [new file with mode: 0644]
libpthread/nptl/pthread_setgid.c [new file with mode: 0644]
libpthread/nptl/pthread_setregid.c [new file with mode: 0644]
libpthread/nptl/pthread_setresgid.c [new file with mode: 0644]
libpthread/nptl/pthread_setresuid.c [new file with mode: 0644]
libpthread/nptl/pthread_setreuid.c [new file with mode: 0644]
libpthread/nptl/pthread_setschedparam.c [new file with mode: 0644]
libpthread/nptl/pthread_setschedprio.c [new file with mode: 0644]
libpthread/nptl/pthread_setspecific.c [new file with mode: 0644]
libpthread/nptl/pthread_setuid.c [new file with mode: 0644]
libpthread/nptl/pthread_testcancel.c [new file with mode: 0644]
libpthread/nptl/pthread_timedjoin.c [new file with mode: 0644]
libpthread/nptl/pthread_tryjoin.c [new file with mode: 0644]
libpthread/nptl/res.c [new file with mode: 0644]
libpthread/nptl/sem_close.c [new file with mode: 0644]
libpthread/nptl/sem_destroy.c [new file with mode: 0644]
libpthread/nptl/sem_getvalue.c [new file with mode: 0644]
libpthread/nptl/sem_init.c [new file with mode: 0644]
libpthread/nptl/sem_open.c [new file with mode: 0644]
libpthread/nptl/sem_unlink.c [new file with mode: 0644]
libpthread/nptl/semaphore.h [new file with mode: 0644]
libpthread/nptl/semaphoreP.h [new file with mode: 0644]
libpthread/nptl/sockperf.c [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/pthread_spin_lock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/pthread_spin_trylock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/tcb-offsets.sym [new file with mode: 0644]
libpthread/nptl/sysdeps/alpha/tls.h [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/i486/pthread_spin_trylock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/i586/pthread_spin_trylock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/i686/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/i686/pthread_spin_trylock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/i686/tls.h [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/pthread_spin_init.c [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/pthread_spin_lock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/pthread_spin_unlock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/tcb-offsets.sym [new file with mode: 0644]
libpthread/nptl/sysdeps/i386/tls.h [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/nptl-sysdep.S [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/pthread_spin_lock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/pthread_spin_trylock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/tcb-offsets.sym [new file with mode: 0644]
libpthread/nptl/sysdeps/mips/tls.h [new file with mode: 0644]
libpthread/nptl/sysdeps/powerpc/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/powerpc/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/powerpc/pthread_spin_lock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/powerpc/pthread_spin_trylock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/powerpc/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/powerpc/tcb-offsets.sym [new file with mode: 0644]
libpthread/nptl/sysdeps/powerpc/tls.h [new file with mode: 0644]
libpthread/nptl/sysdeps/pthread/bits/libc-lock.h [new file with mode: 0644]
libpthread/nptl/sysdeps/pthread/bits/sigthread.h [new file with mode: 0644]
libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/pthread_spin_init.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/pthread_spin_lock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/tcb-offsets.sym [new file with mode: 0644]
libpthread/nptl/sysdeps/sh/tls.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc32/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc32/pthread_spin_lock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc32/pthread_spin_trylock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc32/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_lock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_trylock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_unlock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc64/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_lock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_trylock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_unlock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/sparc64/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/tcb-offsets.sym [new file with mode: 0644]
libpthread/nptl/sysdeps/sparc/tls.h [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/Makefile [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/jmpbuf-unwind.h [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/pthread_spin_init.c [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/pthread_spin_lock.c [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/pthread_spin_trylock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/pthread_spin_unlock.S [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/pthreaddef.h [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/tcb-offsets.sym [new file with mode: 0644]
libpthread/nptl/sysdeps/x86_64/tls.h [new file with mode: 0644]
libpthread/nptl/unwind.c [new file with mode: 0644]
libpthread/nptl/vars.c [new file with mode: 0644]
libpthread/nptl_db/Makefile [new file with mode: 0644]
libpthread/nptl_db/Versions [new file with mode: 0644]
libpthread/nptl_db/db_info.c [new file with mode: 0644]
libpthread/nptl_db/fetch-value.c [new file with mode: 0644]
libpthread/nptl_db/proc_service.h [new file with mode: 0644]
libpthread/nptl_db/structs.def [new file with mode: 0644]
libpthread/nptl_db/td_init.c [new file with mode: 0644]
libpthread/nptl_db/td_log.c [new file with mode: 0644]
libpthread/nptl_db/td_symbol_list.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_clear_event.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_delete.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_enable_stats.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_event_addr.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_event_getmsg.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_get_nthreads.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_get_ph.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_get_stats.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_map_id2thr.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_map_lwp2thr.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_new.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_reset_stats.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_set_event.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_setconcurrency.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_thr_iter.c [new file with mode: 0644]
libpthread/nptl_db/td_ta_tsd_iter.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_clear_event.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_dbresume.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_dbsuspend.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_event_enable.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_event_getmsg.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_get_info.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_getfpregs.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_getgregs.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_getxregs.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_getxregsize.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_set_event.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_setfpregs.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_setgregs.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_setprio.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_setsigpending.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_setxregs.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_sigsetmask.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_tls_get_addr.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_tlsbase.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_tsd.c [new file with mode: 0644]
libpthread/nptl_db/td_thr_validate.c [new file with mode: 0644]
libpthread/nptl_db/thread_db.h [new file with mode: 0644]
libpthread/nptl_db/thread_dbP.h [new file with mode: 0644]

diff --git a/libpthread/README.NPTL b/libpthread/README.NPTL
new file mode 100644 (file)
index 0000000..7e50984
--- /dev/null
@@ -0,0 +1,307 @@
+The base NPTL code for uClibc is from the glibc project located at
+<http://sourceware.org/glibc/>. The starting version was the HEAD of
+the glibc CVS repository dated 2005-05-06. Important changes from
+glibc will continue to be brought in as necessary until the version
+for uClibc is standing on its own. All of the files were originally
+brought over verbatim with no modifications. Obviously, these will
+undergo any necessary changes needed for integration into uClibc.
+Additionally (or subtractingly), the files and directories below
+were removed and not imported.
+
+-- Steven J. Hill <sjhill@realitydiluted.com> on 2005-05-06
+
+
+nptl/Makeconfig
+nptl/configure
+nptl/shlib-versions
+nptl/sysdeps/generic
+nptl/sysdeps/ia64
+nptl/sysdeps/pthread/Makefile
+nptl/sysdeps/pthread/Subdirs
+nptl/sysdeps/pthread/allocalim.h
+nptl/sysdeps/pthread/configure
+nptl/sysdeps/pthread/configure.in
+nptl/sysdeps/pthread/createthread.c
+nptl/sysdeps/pthread/flockfile.c
+nptl/sysdeps/pthread/ftrylockfile.c
+nptl/sysdeps/pthread/funlockfile.c
+nptl/sysdeps/pthread/librt-cancellation.c
+nptl/sysdeps/pthread/list.h
+nptl/sysdeps/pthread/malloc-machine.h
+nptl/sysdeps/pthread/posix-timer.h
+nptl/sysdeps/pthread/pt-initfini.c
+nptl/sysdeps/pthread/pt-longjmp.c
+nptl/sysdeps/pthread/pthread-functions.h
+nptl/sysdeps/pthread/pthread.h
+nptl/sysdeps/pthread/pthread_barrier_wait.c
+nptl/sysdeps/pthread/pthread_cond_broadcast.c
+nptl/sysdeps/pthread/pthread_cond_signal.c
+nptl/sysdeps/pthread/pthread_cond_timedwait.c
+nptl/sysdeps/pthread/pthread_cond_wait.c
+nptl/sysdeps/pthread/pthread_getcpuclockid.c
+nptl/sysdeps/pthread/pthread_once.c
+nptl/sysdeps/pthread/pthread_rwlock_rdlock.c
+nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
+nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
+nptl/sysdeps/pthread/pthread_rwlock_unlock.c
+nptl/sysdeps/pthread/pthread_rwlock_wrlock.c
+nptl/sysdeps/pthread/pthread_sigmask.c
+nptl/sysdeps/pthread/pthread_spin_destroy.c
+nptl/sysdeps/pthread/pthread_spin_init.c
+nptl/sysdeps/pthread/pthread_spin_unlock.c
+nptl/sysdeps/pthread/rt-unwind-resume.c
+nptl/sysdeps/pthread/setxid.h
+nptl/sysdeps/pthread/sigaction.c
+nptl/sysdeps/pthread/sigfillset.c
+nptl/sysdeps/pthread/sigprocmask.c
+nptl/sysdeps/pthread/tcb-offsets.h
+nptl/sysdeps/pthread/timer_create.c
+nptl/sysdeps/pthread/timer_delete.c
+nptl/sysdeps/pthread/timer_getoverr.c
+nptl/sysdeps/pthread/timer_gettime.c
+nptl/sysdeps/pthread/timer_routines.c
+nptl/sysdeps/pthread/timer_settime.c
+nptl/sysdeps/pthread/tst-mqueue8x.c
+nptl/sysdeps/pthread/tst-timer.c
+nptl/sysdeps/pthread/unwind-forcedunwind.c
+nptl/sysdeps/pthread/unwind-resume.c
+nptl/sysdeps/s390
+nptl/sysdeps/unix
+nptl/tst-_res1.c
+nptl/tst-_res1mod1.c
+nptl/tst-_res1mod2.c
+nptl/tst-align.c
+nptl/tst-align2.c
+nptl/tst-atfork1.c
+nptl/tst-atfork2.c
+nptl/tst-atfork2mod.c
+nptl/tst-attr1.c
+nptl/tst-attr2.c
+nptl/tst-attr3.c
+nptl/tst-backtrace1.c
+nptl/tst-barrier1.c
+nptl/tst-barrier2.c
+nptl/tst-barrier3.c
+nptl/tst-barrier4.c
+nptl/tst-basic1.c
+nptl/tst-basic2.c
+nptl/tst-basic3.c
+nptl/tst-basic4.c
+nptl/tst-basic5.c
+nptl/tst-basic6.c
+nptl/tst-cancel-wrappers.sh
+nptl/tst-cancel1.c
+nptl/tst-cancel10.c
+nptl/tst-cancel11.c
+nptl/tst-cancel12.c
+nptl/tst-cancel13.c
+nptl/tst-cancel14.c
+nptl/tst-cancel15.c
+nptl/tst-cancel16.c
+nptl/tst-cancel17.c
+nptl/tst-cancel18.c
+nptl/tst-cancel19.c
+nptl/tst-cancel2.c
+nptl/tst-cancel20.c
+nptl/tst-cancel21.c
+nptl/tst-cancel22.c
+nptl/tst-cancel23.c
+nptl/tst-cancel3.c
+nptl/tst-cancel4.c
+nptl/tst-cancel5.c
+nptl/tst-cancel6.c
+nptl/tst-cancel7.c
+nptl/tst-cancel8.c
+nptl/tst-cancel9.c
+nptl/tst-cancelx1.c
+nptl/tst-cancelx10.c
+nptl/tst-cancelx11.c
+nptl/tst-cancelx12.c
+nptl/tst-cancelx13.c
+nptl/tst-cancelx14.c
+nptl/tst-cancelx15.c
+nptl/tst-cancelx16.c
+nptl/tst-cancelx17.c
+nptl/tst-cancelx18.c
+nptl/tst-cancelx2.c
+nptl/tst-cancelx20.c
+nptl/tst-cancelx21.c
+nptl/tst-cancelx3.c
+nptl/tst-cancelx4.c
+nptl/tst-cancelx5.c
+nptl/tst-cancelx6.c
+nptl/tst-cancelx7.c
+nptl/tst-cancelx8.c
+nptl/tst-cancelx9.c
+nptl/tst-cleanup0.c
+nptl/tst-cleanup0.expect
+nptl/tst-cleanup1.c
+nptl/tst-cleanup2.c
+nptl/tst-cleanup3.c
+nptl/tst-cleanup4.c
+nptl/tst-cleanup4aux.c
+nptl/tst-cleanupx0.c
+nptl/tst-cleanupx0.expect
+nptl/tst-cleanupx1.c
+nptl/tst-cleanupx2.c
+nptl/tst-cleanupx3.c
+nptl/tst-cleanupx4.c
+nptl/tst-clock1.c
+nptl/tst-clock2.c
+nptl/tst-cond1.c
+nptl/tst-cond10.c
+nptl/tst-cond11.c
+nptl/tst-cond12.c
+nptl/tst-cond13.c
+nptl/tst-cond14.c
+nptl/tst-cond15.c
+nptl/tst-cond16.c
+nptl/tst-cond17.c
+nptl/tst-cond18.c
+nptl/tst-cond19.c
+nptl/tst-cond2.c
+nptl/tst-cond20.c
+nptl/tst-cond21.c
+nptl/tst-cond3.c
+nptl/tst-cond4.c
+nptl/tst-cond5.c
+nptl/tst-cond6.c
+nptl/tst-cond7.c
+nptl/tst-cond8.c
+nptl/tst-cond9.c
+nptl/tst-context1.c
+nptl/tst-detach1.c
+nptl/tst-dlsym1.c
+nptl/tst-eintr1.c
+nptl/tst-eintr2.c
+nptl/tst-eintr3.c
+nptl/tst-eintr4.c
+nptl/tst-eintr5.c
+nptl/tst-exec1.c
+nptl/tst-exec2.c
+nptl/tst-exec3.c
+nptl/tst-exec4.c
+nptl/tst-execstack-mod.c
+nptl/tst-execstack.c
+nptl/tst-exit1.c
+nptl/tst-exit2.c
+nptl/tst-exit3.c
+nptl/tst-fini1.c
+nptl/tst-fini1mod.c
+nptl/tst-flock1.c
+nptl/tst-flock2.c
+nptl/tst-fork1.c
+nptl/tst-fork2.c
+nptl/tst-fork3.c
+nptl/tst-fork4.c
+nptl/tst-getpid1.c
+nptl/tst-getpid2.c
+nptl/tst-join1.c
+nptl/tst-join2.c
+nptl/tst-join3.c
+nptl/tst-join4.c
+nptl/tst-join5.c
+nptl/tst-key1.c
+nptl/tst-key2.c
+nptl/tst-key3.c
+nptl/tst-key4.c
+nptl/tst-kill1.c
+nptl/tst-kill2.c
+nptl/tst-kill3.c
+nptl/tst-kill4.c
+nptl/tst-kill5.c
+nptl/tst-kill6.c
+nptl/tst-locale1.c
+nptl/tst-locale2.c
+nptl/tst-mutex1.c
+nptl/tst-mutex2.c
+nptl/tst-mutex3.c
+nptl/tst-mutex4.c
+nptl/tst-mutex5.c
+nptl/tst-mutex5a.c
+nptl/tst-mutex6.c
+nptl/tst-mutex7.c
+nptl/tst-mutex7a.c
+nptl/tst-mutex8.c
+nptl/tst-mutex9.c
+nptl/tst-oddstacklimit.c
+nptl/tst-once1.c
+nptl/tst-once2.c
+nptl/tst-once3.c
+nptl/tst-once4.c
+nptl/tst-oncex3.c
+nptl/tst-oncex4.c
+nptl/tst-popen1.c
+nptl/tst-raise1.c
+nptl/tst-rwlock1.c
+nptl/tst-rwlock10.c
+nptl/tst-rwlock11.c
+nptl/tst-rwlock12.c
+nptl/tst-rwlock13.c
+nptl/tst-rwlock14.c
+nptl/tst-rwlock2.c
+nptl/tst-rwlock3.c
+nptl/tst-rwlock4.c
+nptl/tst-rwlock5.c
+nptl/tst-rwlock6.c
+nptl/tst-rwlock7.c
+nptl/tst-rwlock8.c
+nptl/tst-rwlock9.c
+nptl/tst-sched1.c
+nptl/tst-sem1.c
+nptl/tst-sem2.c
+nptl/tst-sem3.c
+nptl/tst-sem4.c
+nptl/tst-sem5.c
+nptl/tst-sem6.c
+nptl/tst-sem7.c
+nptl/tst-sem8.c
+nptl/tst-sem9.c
+nptl/tst-setuid1-static.c
+nptl/tst-setuid1.c
+nptl/tst-signal1.c
+nptl/tst-signal2.c
+nptl/tst-signal3.c
+nptl/tst-signal4.c
+nptl/tst-signal5.c
+nptl/tst-signal6.c
+nptl/tst-spin1.c
+nptl/tst-spin2.c
+nptl/tst-spin3.c
+nptl/tst-stack1.c
+nptl/tst-stack2.c
+nptl/tst-stack3.c
+nptl/tst-stdio1.c
+nptl/tst-stdio2.c
+nptl/tst-sysconf.c
+nptl/tst-tls1.c
+nptl/tst-tls2.c
+nptl/tst-tls3.c
+nptl/tst-tls3mod.c
+nptl/tst-tls4.c
+nptl/tst-tls4moda.c
+nptl/tst-tls4modb.c
+nptl/tst-tls5.c
+nptl/tst-tls5.h
+nptl/tst-tls5mod.c
+nptl/tst-tls5moda.c
+nptl/tst-tls5modb.c
+nptl/tst-tls5modc.c
+nptl/tst-tls5modd.c
+nptl/tst-tls5mode.c
+nptl/tst-tls5modf.c
+nptl/tst-tls6.sh
+nptl/tst-tsd1.c
+nptl/tst-tsd2.c
+nptl/tst-tsd3.c
+nptl/tst-tsd4.c
+nptl/tst-tsd5.c
+nptl/tst-umask1.c
+nptl/tst-unload.c
+nptl/tst-vfork1.c
+nptl/tst-vfork1x.c
+nptl/tst-vfork2.c
+nptl/tst-vfork2x.c
+nptl/version.c
+nptl_db/ChangeLog
+nptl_db/shlib-versions
diff --git a/libpthread/nptl/ANNOUNCE b/libpthread/nptl/ANNOUNCE
new file mode 100644 (file)
index 0000000..b63c657
--- /dev/null
@@ -0,0 +1,92 @@
+Now that the Linux kernel is once again able to run all the tests we
+have and since glibc 2.3 was released it was time for a new code drop.
+I've uploaded the second code drop for the Native POSIX Thread
+Library:
+
+  ftp://people.redhat.com/drepper/nptl/nptl-0.2.tar.bz2
+
+You need
+
+- the latest of Linus' kernel from BitKeeper (or 2.5.41 when it
+  is released);
+
+- glibc 2.3
+
+- the very latest in tools such as
+
+  + gcc either from the current development branch or the gcc 3.2
+    from Red Hat Linux 8;
+
+  + binutils preferrably from CVS, from H.J. Lu's latest release for
+    Linux, or from RHL 8.
+
+
+Compiling glibc should proceed smoothly.  But there are a number of
+tests which fail, mostly because some functionality is missing in
+glibc.  Ignore those errors.  It is only important that all tests in
+nptl/ are passing.  Run
+
+  make subdirs=nptl check
+
+to run all thread tests.
+
+
+This version features several improvements:
+
+- all APIs are now implemented;
+
+- fork handling has been improved; stacks in the child are freed;
+  atfork handlers are removed if they were registered from a module
+  which gets unloaded.
+
+- pthread_tryjoin_np and pthread_timedjoin_np are implemented
+
+- TSD handling corrected and optimized.
+
+- many more tests which also test the underlying kernel implementation.
+
+- the build infrastructure has been implemented so that the DSO and
+  archives are built in usable form and with correct named.
+
+- libthread_db has been implemented.  This is the library which is
+  needed by all program which need to get access to internals of
+  libpthread (mainly debuggers).
+
+- the CPU clock functions are implemented
+
+
+
+The white paper hasn't yet been updated.  It's still available at
+
+  http://people.redhat.com/drepper/nptl-design.pdf
+
+
+This release should be ready for some serious testing.  I know it is
+hard to compile which I why I'm looking into providing binary RPMs.
+They can be used on non-critical systems.  I'll only be able to
+provide binaries for RHL8 based systems, though, and the kernel still
+must be installed separately.
+
+
+The next steps will include:
+
+- write more tests and fix the bugs which are discovered this way
+
+- update the white paper
+
+- write and run more performance tests
+
+- port to IA-64
+
+
+Interested parties are once again invited to join the mailing we
+created:
+
+
+  phil-list@redhat.com
+
+Go to
+
+  https://listman.redhat.com/mailman/listinfo/phil-list
+
+to subscribe, unsubscribe, or review the archive.
diff --git a/libpthread/nptl/Banner b/libpthread/nptl/Banner
new file mode 100644 (file)
index 0000000..7c1487e
--- /dev/null
@@ -0,0 +1 @@
+Native POSIX Threads Library by Ulrich Drepper et al
diff --git a/libpthread/nptl/ChangeLog b/libpthread/nptl/ChangeLog
new file mode 100644 (file)
index 0000000..6fb56a9
--- /dev/null
@@ -0,0 +1,7160 @@
+2005-05-03  Ulrich Drepper  <drepper@redhat.com>
+
+       [BZ #915]
+       * sysdeps/pthread/pthread.h: Avoid empty initializers.
+
+2005-05-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Remove explicit
+       .eh_frame section, use cfi_* directives.
+
+2005-04-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/pthread_getcpuclockid.c: Use <> instead
+       of "" includes.
+
+2005-04-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel17.c (do_test): Add arbitrary factor to make sure
+       aio_write blocks.
+
+2005-04-27  Roland McGrath  <roland@redhat.com>
+
+       * Makefile (tests): Remove tst-clock2.
+
+       * sysdeps/unix/sysv/linux/timer_create.c (timer_create): Handle
+       CLOCK_PROCESS_CPUTIME_ID and CLOCK_PROCESS_THREAD_ID specially,
+       translating to the kernel clockid_t for our own process/thread clock.
+
+       * sysdeps/unix/sysv/linux/pthread_getcpuclockid.c: New file.
+
+2005-04-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * old_pthread_cond_init.c: Include <errno.h>.
+       (__pthread_cond_init_2_0): Fail with EINVAL if COND_ATTR is
+       process shared or uses clock other than CLOCK_REALTIME.
+       * pthread_cond_init.c (__pthread_cond_init): Remove bogus comment.
+
+2005-04-13  David S. Miller  <davem@davemloft.net>
+
+       * sysdeps/sparc/sparc64/jmpbuf-unwind.h: New file.
+       * sysdeps/sparc/sparc64/clone.S: New file.
+
+2005-04-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread.h (__pthread_cleanup_routine): Use
+       __inline instead of inline.
+       * sysdeps/pthread/bits/libc-lock.h (__libc_cleanup_routine): Likewise.
+
+2005-03-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Use
+       functionally equivalent, but shorter instructions.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+
+2005-03-28  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sysdeps/mips/Makefile: New file.
+       * sysdeps/mips/nptl-sysdep.S: New file.
+       * sysdeps/mips/tcb-offsets.sym: New file.
+       * sysdeps/mips/pthread_spin_lock.S: New file.
+       * sysdeps/mips/pthread_spin_trylock.S: New file.
+       * sysdeps/mips/pthreaddef.h: New file.
+       * sysdeps/mips/tls.h: New file.
+       * sysdeps/mips/jmpbuf-unwind.h: New file.
+       * sysdeps/unix/sysv/linux/mips/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/mips/bits/pthreadtypes.h: New file.
+       * sysdeps/unix/sysv/linux/mips/bits/semaphore.h: New file.
+       * sysdeps/unix/sysv/linux/mips/pthread_once.c: New file.
+       * sysdeps/unix/sysv/linux/mips/fork.c: New file.
+       * sysdeps/unix/sysv/linux/mips/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/mips/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/mips/clone.S: New file.
+       * sysdeps/unix/sysv/linux/mips/createthread.c: New file.
+       * sysdeps/unix/sysv/linux/mips/sysdep-cancel.h: New file.
+
+2005-03-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_create.c (__pthread_create_2_1): Rename syscall error
+       variable to scerr.
+
+2005-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-getpid1.c (do_test): Align stack passed to clone{2,}.
+
+2005-02-25  Roland McGrath  <roland@redhat.com>
+
+       * alloca_cutoff.c: Correct license text.
+       * tst-unload.c: Likewise.
+       * sysdeps/pthread/allocalim.h: Likewise.
+       * sysdeps/pthread/pt-initfini.c: Likewise.
+       * sysdeps/pthread/bits/libc-lock.h: Likewise.
+       * sysdeps/pthread/bits/sigthread.h: Likewise.
+       * sysdeps/unix/sysv/linux/bits/local_lim.h: Likewise.
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Likewise.
+
+2005-02-16  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+       Use unsigned int * for ptr_nthreads.
+
+2005-02-14  Alan Modra  <amodra@bigpond.net.au>
+
+       * sysdeps/powerpc/tcb-offsets.sym (thread_offsetof): Redefine to suit
+       gcc4.
+
+2005-02-07  Richard Henderson  <rth@redhat.com>
+
+       [BZ #787]
+       * sysdeps/pthread/pthread.h (__sigsetjmp): Use pointer as first
+       argument.
+
+2004-11-03  Marcus Brinkmann  <marcus@gnu.org>
+
+       * sysdeps/generic/lowlevellock.h (__generic_mutex_unlock): Fix
+       order of arguments in invocation of atomic_add_zero.
+
+2005-01-26  Jakub Jelinek  <jakub@redhat.com>
+
+       [BZ #737]
+       * sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S (__new_sem_trywait):
+       Use direct %gs segment access or, if NO_TLS_DIRECT_SEG_REFS,
+       at least gotntpoff relocation and addition.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S (__new_sem_post):
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S (__new_sem_wait):
+       Likewise.
+
+2005-01-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (init_one_static_tls): Adjust initialization of DTV
+       entry for static tls deallocation fix.
+       * sysdeps/alpha/tls.h (dtv_t): Change pointer type to be struct which
+       also contains information whether the memory pointed to is static
+       TLS or not.
+       * sysdeps/i386/tls.h: Likewise.
+       * sysdeps/ia64/tls.h: Likewise.
+       * sysdeps/powerpc/tls.h: Likewise.
+       * sysdeps/s390/tls.h: Likewise.
+       * sysdeps/sh/tls.h: Likewise.
+       * sysdeps/sparc/tls.h: Likewise.
+       * sysdeps/x86_64/tls.h: Likewise.
+
+2004-12-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (__pthread_initialize_minimal_internal): Use __sigemptyset.
+
+2004-12-21  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/i386/tls.h (CALL_THREAD_FCT): Maintain 16 byte alignment of
+       %esp.
+       * Makefile (tests): Add tst-align2.
+       * tst-align2.c: New test.
+       * sysdeps/i386/Makefile (CFLAGS-tst-align{,2}.c): Add
+       -mpreferred-stack-boundary=4.
+
+2004-12-18  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/local_lim.h:
+       New file removed withdrawn for the moment.
+
+2004-12-17  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/clone.S: New file.
+       * sysdeps/alpha/tcb-offsets.sym (TID_OFFSET): New.
+
+2004-12-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/bits/local_lim.h: New file.
+       Increased PTHREAD_STACK_MIN.
+
+       * tst-context1.c (stacks): Use bigger stack size.
+
+2004-12-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: New file.
+       * sysdeps/sparc/tcb-offsets.sym: Add TID.
+
+2004-12-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/s390-32/clone.S: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/clone.S: New file.
+       * sysdeps/s390/tcb-offsets.sym (TID): Add.
+
+2004-12-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S: New file.
+
+2004-12-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/powerpc/tcb-offsets.sym: Add TID.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: New file.
+
+       * tst-getpid1.c: If child crashes, report this first.  Print which
+       signal.
+
+2004-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (__pthread_initialize_minimal_internal): Also unblock
+       SIGSETXID.
+
+2004-12-01  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h (_POSIX_CPUTIME,
+       _POSIX_THREAD_CPUTIME): Define to 0.
+       * sysdeps/pthread/timer_create.c (timer_create): Remove unused code
+       handling CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
+       * sysdeps/pthread/timer_routines.c (__timer_signal_thread_pclk,
+       __timer_signal_thread_tclk): Remove.
+       (init_module): Remove their initialization.
+       (thread_cleanup): Remove their cleanup assertions.
+       * sysdeps/pthread/posix-timer.h (__timer_signal_thread_pclk,
+       __timer_signal_thread_tclk): Remove.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Removed.
+       * sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h: Removed.
+       * sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h: Removed.
+
+2004-12-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/ia64/tcb-offsets.sym (TID): Add.
+       * sysdeps/unix/sysv/linux/ia64/clone2.S: New file.
+
+       * Makefile (tests): Add tst-getpid2.
+       * tst-getpid1.c (TEST_CLONE_FLAGS): Define.
+       (do_test): Use it.  Use __clone2 instead of clone on ia64.
+       * tst-getpid2.c: New test.
+
+2004-12-07  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/clone.S: New file.
+
+2004-12-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-getpid1.
+       * tst-getpid1.c: New file.
+       * sysdeps/unix/sysv/linux/i386/clone.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/clone.S: New file.
+
+2004-12-02  Roland McGrath  <roland@redhat.com>
+
+       * Makefile (libpthread-nonshared): Variable removed.
+       ($(objpfx)libpthread_nonshared.a): Target removed.
+       ($(inst_libdir)/libpthread_nonshared.a): Likewise.
+       These are now handled by generic magic from
+       libpthread-static-only-routines being set.
+
+2004-11-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h (_POSIX_PRIORITIZED_IO,
+       _POSIX2_CHAR_TERM, _POSIX_THREAD_PRIO_INHERIT,
+       _POSIX_THREAD_PRIO_PROTECT): Define.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h: Likewise.
+
+2004-11-26  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h (_POSIX_ADVISORY_INFO,
+       _POSIX_SPORADIC_SERVER, _POSIX_THREAD_SPORADIC_SERVER, _POSIX_TRACE,
+       _POSIX_TRACE_EVENT_FILTER, _POSIX_TRACE_INHERIT, _POSIX_TRACE_LOG,
+       _POSIX_TYPED_MEMORY_OBJECTS, _POSIX_IPV6, _POSIX_RAW_SOCKETS): Define.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h: Likewise.
+
+2004-11-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/x86_64/Makefile [nptl]: Define CFLAGS-pthread_create.c.
+
+       * Makefile (libpthread-routines): Add pthread_setschedprio.
+       * Versions [libpthread, GLIBC_2.3.4]: Add pthread_setschedprio.
+       * sysdeps/pthread/pthread.h: Declare pthread_setschedprio.
+       * pthread_setschedprio.c: New file.
+
+2004-11-20  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthread_create.c (pthread_cancel): Add PTHREAD_STATIC_FN_REQUIRE.
+       * pthread_cancel.c (pthread_create): Likewise.
+
+       * Makefile (libpthread-routines): Add vars.
+       * sysdeps/pthread/createthread.c (__pthread_multiple_threads): Remove.
+       * init.c (__default_stacksize, __is_smp): Remove.
+       * vars.c: New file.
+       * pthreadP.h (__find_thread_by_id): If !SHARED, add weak_function
+       and define a wrapper macro.
+       (PTHREAD_STATIC_FN_REQUIRE): Define.
+       * allocatestack.c (__find_thread_by_id): Undefine.
+       * pthread_create (__pthread_keys): Remove.
+       (pthread_mutex_lock, pthread_mutex_unlock, pthread_once,
+       pthread_key_create, pthread_setspecific, pthread_getspecific): Add
+       PTHREAD_STATIC_FN_REQUIRE.
+
+2004-11-18  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/tls.h (DB_THREAD_SELF): Set the correct bias
+       parameter to REGISTER macro.
+
+2004-11-17  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/timer_routines.c (__start_helper_thread):
+       Make sure SIGCANCEL is blocked as well.
+
+2004-11-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/setxid.h: New file.
+       * sysdeps/pthread/pthread-functions.h (HAVE_PTR__NPTL_SETXID): Remove.
+       (struct xid_command): Add forward decl.
+       (struct pthread_functions): Change return type of __nptl_setxid hook
+       to int.
+       * pthreadP.h (__nptl_setxid): Change return type to int.
+       * allocatestack.c (__nptl_setxid): Call INTERNAL_SYSCALL_NCS in the
+       calling thread, return its return value and set errno on failure.
+       * descr.h (struct xid_command): Change id type to long array.
+
+       * Makefile: Add rules to build and test tst-setuid1 and
+       tst-setuid1-static.
+       * tst-setuid1.c: New test.
+       * tst-setuid1-static.c: New test.
+
+2004-11-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-exit3.
+       * tst-exit3.c: New test.
+
+2004-11-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-exit2.
+       * tst-exit2.c: New file.
+
+2004-11-09  Roland McGrath  <roland@redhat.com>
+
+       [BZ #530]
+       * sysdeps/pthread/createthread.c (do_clone): Increment __nptl_nthreads
+       here, before calling clone.
+       * pthread_create.c (start_thread): Don't do it here.
+
+2004-11-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/smp.h: Include <errno.h>.
+
+2004-10-29  Kaz  Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S (sem_timedwait):
+       Set ETIMEDOUT to errno when time is up.  Tweak to avoid
+       assembler warning.
+
+2004-10-28  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthread_create.c (__pthread_create_2_1): Avoid leaking stacks
+       if sched_priority is not between minprio and maxprio.
+
+2004-10-25  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Use clock_gettime syscall if exists.
+
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S
+       (__lll_mutex_timedlock_wait): Fix a bad branch condition.
+
+2004-10-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/smp.h (is_smp_system): Use
+       not-cancelable I/O functions.
+
+2004-10-21  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S
+       (__lll_mutex_timedlock_wait): If woken but cannot get the lock,
+       make sure 2 is stored in the futex and we looked at the old value.
+       Fix a few other problems to return the correct value.
+
+2004-10-14  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/alpha/tcb-offsets.sym (thread_offsetof): Redefine to
+       make gcc4 happy.
+
+2004-10-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/jmp-unwind.c: Include pthreadP.h instead
+       of pthread-functions.h and pthreaddef.h.
+       * sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h (pthread_cond_t):
+       Change __data.__nwaiters from int to unsigned int.
+
+       * tst-clock2.c (do_test): Don't fail if _POSIX_THREAD_CPUTIME == 0 and
+       sysconf (_SC_THREAD_CPUTIME) returns negative value.
+
+       * allocatestack.c (__find_thread_by_id): Move attribute_hidden
+       before return type.
+
+       * sysdeps/s390/jmpbuf-unwind.h: Include bits/wordsize.h.
+       (JMPBUF_CFA_UNWINDS_ADJ): Subtract 96 resp. 160 bytes from CFA.
+
+2004-10-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel4.c (tf_msgrcv): Check for failure in msgget.  If the
+       test fails, remove message queue.
+       (tf_msgsnd): Likewise.
+
+2004-10-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-clock1.c: Change #ifdef to #if defined.
+       * tst-clock2.c: Likewise.
+       * tst-cond11.c: Likewise.
+
+       * sysdeps/pthread/timer_create.c (timer_create): Use
+       defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0 instead of
+       defined CLOCK_PROCESS_CPUTIME_ID #ifs and similarly for
+       THREAD_CPUTIME.
+
+2004-10-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h (_POSIX_CPUTIME,
+       _POSIX_THREAD_CPUTIME): Define to 0.
+
+2004-10-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Define _POSIX_CPUTIME
+       and _POSIX_THREAD_CPUTIME to zero.
+       * sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h: Likewise.
+       * tst-barrier2.c: Fix testing for POSIX feature.
+       * tst-clock1.c: Likewise.
+       * tst-clock2.c: Likewise.
+       * tst-cond11.c: Likewise.
+       * tst-cond4.c: Likewise.
+       * tst-cond6.c: Likewise.
+       * tst-flock2.c: Likewise.
+       * tst-mutex4.c: Likewise.
+       * tst-mutex9.c: Likewise.
+       * tst-rwlock12.c: Likewise.
+       * tst-rwlock4.c: Likewise.
+       * tst-signal1.c: Likewise.
+       * tst-spin2.c: Likewise.
+       * sysdeps/pthread/posix-timer.h: Likewise.
+       * sysdeps/pthread/timer_create.c: Likewise.
+       * sysdeps/pthread/timer_routines.c: Likewise.
+
+2004-10-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+       (__lll_mutex_timedlock_wait): Address futex correctly.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+       (__lll_mutex_timedlock_wait): If woken but cannot get the lock,
+       make sure 2 is stored in the futex and we looked at the old value.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+       (__lll_mutex_timedlock_wait): Likewise.  Fix a few other problems
+       which might very well made the code not working at all before.
+       [BZ #417]
+
+2004-09-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/pthread_kill.c (__pthread_kill): Don't
+       allow SIGSETXID to be sent.
+       * sysdeps/pthread/sigaction.c (__sigaction): Don't allow action
+       for SIGSETXID to be defined.
+       * sysdeps/pthread/pthread_sigmask.c (pthread_sigmask): Make sure
+       SIGSETXID cannot be blocked.
+
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_cond_t):
+       Add __extension__ to long long types.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h (struct pthread): Add stopped_start field.
+       * sysdeps/pthread/createthread.c (create_thread): Set
+       start_stopped flag in descriptor for new thread appropriately.
+       * pthread_create.c (start_thread): Only take lock to be stopped on
+       startup if stopped_start flag says so.
+
+2004-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_create.c (__pthread_create_2_1): Remember whether thread
+       is created detached and if yes, do not try to free the stack in case
+       the thread creation failed.
+       * sysdeps/pthread/createthread.c (do_clone): Free stack here if clone
+       call fails.  Don't depend on INTERNAL_SYSCALL_ERRNO return zero in
+       case there has been no error.  [BZ #405]
+
+       * pthread_create.c (start_thread): Don't wait for scheduler data
+       etc to be set at the beginning of the function.  The cancellation
+       infrastructure must have been set up.  And enable async
+       cancellation before potentially going to sleep.  [BZ #401]
+
+2004-09-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * Versions: Remove exports for pthread_set*id_np functions.
+       * sysdeps/pthread/pthread.h: Remove pthread_set*id_np prototypes
+       for now.
+       * Makefile: Don't build pthread_set*id code for now.
+
+2004-09-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/allocrtsig.c: Allocate second signal for
+       internal use.
+       * allocatestack.c (__nptl_setxid): New function.
+       * descr.h (struct xid_command): Define type.
+       * init.c (pthread_functions): Add ptr__nptl_setxid initialization.
+       (sighandler_setxid): New function.
+       (__pthread_initialize_minimal): Register sighandler_setxid for
+       SIGCANCEL.
+       * pt-allocrtsig.c: Update comment.
+       * pthreadP.h: Define SIGSETXID.  Declare __xidcmd variable.
+       Declare __nptl_setxid.
+       * sysdeps/pthread/pthread-functions.h: Add ptr__nptl_setxid.
+       * sysdeps/pthread/pthread.h: Declare pthread_setgid_np,
+       pthread_setuid_np, pthread_setegid_np, pthread_seteuid_np,
+       pthread_setregid_np, pthread_setreuid_np, pthread_setresgid_np,
+       and pthread_setresuid_np.
+       * pthread_setgid_np.c: New file.
+       * pthread_setuid_np.c: New file.
+       * pthread_setegid_np.c: New file.
+       * pthread_seteuid_np.c: New file.
+       * pthread_setregid_np.c: New file.
+       * pthread_setreuid_np.c: New file.
+       * pthread_setresgid_np.c: New file.
+       * pthread_setresuid_np.c: New file.
+       * Versions [libpthread, GLIBC_2.3.4]: Add pthread_setgid_np,
+       pthread_setuid_np, pthread_setegid_np, pthread_seteuid_np,
+       pthread_setregid_np, pthread_setreuid_np, pthread_setresgid_np,
+       and pthread_setresuid_np.
+       * Makefile (libpthread-routines): Add pthread_setuid, pthread_seteuid,
+       pthread_setreuid, pthread_setresuid, pthread_setgid, pthread_setegid,
+       pthread_setregid, and pthread_setresgid.
+
+2004-09-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (allocate_stack): Return EAGAIN instead of
+       ENOMEM when out of memory.
+
+2004-09-10  Roland McGrath  <roland@redhat.com>
+
+       [BZ #379]
+       * allocatestack.c (allocate_stack): Remove [__ASSUME_CLONE_STOPPED]
+       code, since we don't try to use the broken CLONE_STOPPED any more.
+       * pthread_create.c (start_thread): Likewise.
+
+2004-09-15  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/vfork.S: Use libc_hidden_def.
+
+2004-09-01  David Mosberger  <davidm@hpl.hp.com>
+
+       * sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h
+       (__libc_unwind_longjmp): Delete macro and declare as function.
+       * sysdeps/unix/sysv/linux/ia64/Makefile (sysdep_routines): Mention
+       __ia64_longjmp, sigstack_longjmp, and __sigstack_longjmp for
+       nptl directory.
+       * sysdeps/unix/sysv/linux/ia64/__ia64_longjmp.S: New file.
+       * sysdeps/unix/sysv/linux/ia64/__sigstack_longjmp.c: New file.
+       * sysdeps/unix/sysv/linux/ia64/unwind_longjmp.c: New file.
+
+2004-09-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h: Make rwlock prototypes available also
+       for __USE_XOPEN2K.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h: Define rwlock
+       types also for __USE_XOPEN2K.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+       [BZ #320]
+
+2004-09-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h
+       (PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP): Make safe for C++.
+       (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): Likewise.
+       (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP): Likewise.
+       (PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP): Likewise.
+       [BZ #375]
+
+2004-09-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Allow
+       PSEUDO to be used with . prefix.
+
+       * sysdeps/unix/sysv/linux/alpha/pthread_once.c (__pthread_once):
+       Use atomic_increment instead of atomic_exchange_and_add.
+       * sysdeps/unix/sysv/linux/sparc/pthread_once.c (__pthread_once):
+       Likewise.
+       * sysdeps/unix/sysv/linux/ia64/pthread_once.c (__pthread_once):
+       Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once):
+       Likewise.
+
+       * allocatestack.c (allocate_stack): Use atomic_increment_val
+       instead of atomic_exchange_and_add.
+       * sysdeps/unix/sysv/linux/sem_post.c (__new_sem_post): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/sem_post.c (__new_sem_post):
+       Likewise.
+       * sysdeps/pthread/pthread_barrier_wait.c (pthread_barrier_wait):
+       Likewise.
+
+       * sysdeps/pthread/pthread.h (pthread_once): Remove __THROW since
+       the initialization function might throw.
+
+2005-09-05  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (SINGLE_THREAD_P):
+       Move definition inside libpthread, libc, librt check.  Provide
+       definition for rtld.
+
+2004-09-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/alpha/jmpbuf-unwind.h: Define __libc_unwind_longjmp.
+       * sysdeps/i386/jmpbuf-unwind.h: Likewise
+       * sysdeps/powerpc/jmpbuf-unwind.h: Likewise.
+       * sysdeps/s390/jmpbuf-unwind.h: Likewise.
+       * sysdeps/sh/jmpbuf-unwind.h: Likewise.
+       * sysdeps/sparc/sparc32/jmpbuf-unwind.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h: Likewise.
+       * sysdeps/x86_64/jmpbuf-unwind.h: Likewise.
+       * unwind.c: Use it.
+
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_cond_t):
+       Rename __data.__clock to __data.__nwaiters, make it unsigned int.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h (pthread_cond_t):
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S:
+       Decrement __nwaiters.  If pthread_cond_destroy has been called and
+       this is the last waiter, signal pthread_cond_destroy caller and
+       avoid using the pthread_cond_t structure after unlock.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       Read clock type from the least significant bits of __nwaiters instead
+       of __clock.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/internaltypes.h: Define COND_CLOCK_BITS.
+
+2004-08-31  Jakub Jelinek  <jakub@redhat.com>
+
+       [BZ #342]
+       * Makefile (tests): Add tst-cond20 and tst-cond21.
+       * tst-cond20.c: New test.
+       * tst-cond21.c: New test.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
+       (pthread_cond_t): Rename __data.__clock to __data.__nwaiters, make
+       it unsigned int.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h (pthread_cond_t):
+       Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
+       (pthread_cond_t): Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h (pthread_cond_t):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_cond_t):
+       Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h (pthread_cond_t):
+       Likewise.
+       * sysdeps/unix/sysv/linux/lowlevelcond.sym (cond_clock): Remove.
+       (cond_nwaiters): New.
+       (clock_bits): New.
+       * pthread_cond_destroy.c (__pthread_cond_destroy): Return EBUSY
+       if there are waiters not signalled yet.
+       Wait until all already signalled waiters wake up.
+       * sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Decrement
+       __nwaiters.  If pthread_cond_destroy has been called and this is the
+       last waiter, signal pthread_cond_destroy caller and avoid using
+       the pthread_cond_t structure after unlock.
+       (__pthread_cond_wait): Increment __nwaiters in the beginning,
+       decrement it when leaving.  If pthread_cond_destroy has been called
+       and this is the last waiter, signal pthread_cond_destroy caller.
+       * sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
+       Likewise.  Read clock type from the least significant bits of
+       __nwaiters instead of __clock.
+       * pthread_condattr_setclock.c (pthread_condattr_setclock): Check
+       whether clock ID can be encoded in COND_CLOCK_BITS bits.
+       * pthread_condattr_getclock.c (pthread_condattr_getclock): Decode
+       clock type just from the last COND_CLOCK_BITS bits of value.
+       * pthread_cond_init.c (__pthread_cond_init): Initialize __nwaiters
+       instead of __clock, just from second bit of condattr's value.
+
+2004-08-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Include
+       bits/wordsize.h.  Make the header match i386 header when __WORDSIZE
+       != 64.
+       * sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h: Likewise.
+
+2004-08-15  Roland McGrath  <roland@frob.com>
+
+       * pthread_atfork.c: Update copyright terms including special exception
+       for these trivial files, which are statically linked into executables
+       that use dynamic linking for the significant library code.
+
+2004-08-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * DESIGN-rwlock.txt: Add decreasing of nr_readers_queued to
+       pthread_rwlock_rdlock.
+       * sysdeps/pthread/pthread_rwlock_rdlock (__pthread_rwlock_rdlock):
+       Decrease __nr_readers_queued after reacquiring lock.
+       * sysdeps/pthread/pthread_rwlock_timedrdlock
+       (pthread_rwlock_timedrdlock): Likewise.
+       Reported by Bob Cook <bobcook47@hotmail.com>.
+
+2004-08-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-rwlock14.c (tf): Read main thread handle from *ARG
+       before pthread_barrier_wait.
+
+2004-08-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S:
+       Remove unnecessary exception handling data.
+
+2004-07-23  Jakub Jelinek  <jakub@redhat.com>
+
+       [BZ #284]
+       * sysdeps/pthread/pthread.h (pthread_getcpuclockid): Use __clockid_t
+       instead of clockid_t.
+
+2004-07-21  Roland McGrath  <roland@redhat.com>
+
+       * Makefile ($(objpfx)multidir.mk): Use $(make-target-directory).
+
+2004-07-19  Roland McGrath  <roland@redhat.com>
+
+       * tst-cancel4.c (tf_waitid): Use WEXITED flag bit if available.
+
+2004-07-02  Roland McGrath  <roland@redhat.com>
+
+       * configure: Don't exit.
+
+2004-07-14  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Check for invalid nanosecond in
+       timeout value.
+
+2004-07-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile: Add rules to build and run tst-fini1.
+       * tst-fini1.c: New file.
+       * tst-fini1mod.c: New file.
+
+2004-07-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Define NO_CANCELLATION
+       if no cancellation support is needed.
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise.
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define __NR_futex
+       only if not already defined.
+
+2004-07-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_unlock): Use
+       constraint "m" instead of "0" for futex.
+
+       * shlib-versions: Add powerpc64-.*-linux.*.
+
+2004-07-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+       (pthread_rwlock_timedrdlock): Use cmpq instead of cmpl to check
+       for valid tv_nsec.
+       * tst-rwlock14.c (do_test): Test for invalid tv_nsec equal to
+       1 billion and 64-bit tv_nsec which is valid when truncated to 32
+       bits.
+
+2004-06-29  Roland McGrath  <roland@redhat.com>
+
+       * Banner: NPTL no longer has its own version number.
+       * Makefile (nptl-version): Variable removed.
+       * sysdeps/pthread/Makefile (CFLAGS-confstr.c): Set LIBPTHREAD_VERSION
+       using $(version), the glibc version number.
+
+2004-06-29  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/pthread_once.S (__pthread_once):
+       Fix branch offset for a PLT entry.
+       * sysdeps/unix/sysv/linux/sh/sem_post.S (__new_sem_post):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S (sem_timedwait):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_trywait.S (__new_sem_trywait):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S (__new_sem_wait):
+       Likewise.
+
+2004-06-28  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/alpha/tcb-offsets.sym (MULTIPLE_THREADS_OFFSET): Define
+       unconditionally.
+
+2004-06-28  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread_rwlock_timedwrlock.c
+       (pthread_rwlock_timedwrlock): Return EINVAL if tv_nsec is negative,
+       instead of tv_sec.
+       * sysdeps/pthread/pthread_rwlock_timedrdlock.c
+       (pthread_rwlock_timedrdlock): Likewise.
+
+2004-06-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (lll_futex_requeue):
+       Set __r7 to val, not mutex.
+
+2004-06-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile: Add rules to build tst-rwlock14.
+       * tst-rwlock14.c: New file.
+
+2004-06-24  Boris Hu  <boris.hu@intel.com>
+
+       * sysdeps/pthread/pthread_rwlock_timedrdlock.c: Add timeout validation
+       check.
+       * sysdeps/pthread/pthread_rwlock_timedwrlock.c: Likewise.
+
+2004-06-19  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Fix
+       assembler in last patch.
+
+2004-06-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_timedwait.c
+       (__pthread_cond_timedwait): Also check for negativ nanoseconds.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Check for invalid nanosecond in
+       timeout value.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * tst-cond19.c: New file.
+       * Makefile: Add rules to build and run tst-cond19.
+
+2004-06-15  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * tst-context1.c (GUARD_PATTERN): Defined.
+       (tst_context_t): Define struct containing ucontext_t & guard words.
+       (ctx): Declare as an array of tst_context_t.
+       (fct): Verify uc_link & guard words are still valid.
+       (tf): Initialize guard words in ctx.  Adjust ctx refs for new struct.
+
+2004-06-13  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_cond_t):
+       Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
+       (__pthread_cond_signal): Increment __futex at the same time as
+       __wakeup_seq or __total_seq.  Pass address of __futex instead of
+       address of low 32-bits of __wakeup_seq to futex syscall.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+       (__pthread_cond_wait): Likewise.  Pass __futex value from before
+       releasing internal lock to FUTEX_WAIT.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+       (FUTEX_CMP_REQUEUE): Define.
+       (__pthread_cond_broadcast): Set __futex to 2 * __total_seq.
+       Use FUTEX_CMP_REQUEUE operation instead of FUTEX_REQUEUE.
+       Pass __futex value from before the unlock and __futex address instead
+       of address of low 32-bits of __wakeup_seq to futex syscall.
+       Fallback to FUTEX_WAKE all on any errors.
+
+2004-06-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthread_mutexattr_getpshared.c (pthread_mutex_getpshared): Fix
+       comment typo.
+       * pthread_mutexattr_gettype.c (pthread_mutexattr_gettype): Likewise.
+       * pthread_mutexattr_init.c (__pthread_mutexattr_init): Likewise.
+       * pthread_mutexattr_settype.c (__pthread_mutexattr_settype): Likewise.
+       * pthread_mutexattr_setpshared.c (pthread_mutexattr_setpshared):
+       Likewise.  Reported by Bob Cook <bobcook47@hotmail.com>.
+
+2004-06-11  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (lll_compare_and_swap):
+       Add memory clobber to inline assembly.
+       (__lll_mutex_trylock): Likewise.
+       (__lll_mutex_cond_trylock): Likewise.
+
+2004-06-07  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (lll_futex_requeue):
+       Pass val argument as 6th system call argument in %r7.
+
+2004-05-21  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-cond16.
+       * sysdeps/unix/sysv/linux/lowlevelcond.sym (cond_futex): Add.
+       * pthread_cond_init.c (__pthread_cond_init): Clear __data.__futex.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_cond_t):
+       Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/unix/sysv/linux/i386/pthread_cond_signal.S
+       (__pthread_cond_signal): Increment __futex at the same time as
+       __wakeup_seq or __total_seq.  Pass address of __futex instead of
+       address of low 32-bits of __wakeup_seq to futex syscall.
+       * sysdeps/unix/sysv/linux/i386/pthread_cond_wait.S
+       (__pthread_cond_wait): Likewise.  Pass __futex value from before
+       releasing internal lock to FUTEX_WAIT.
+       * sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/i386/pthread_cond_broadcast.S
+       (FUTEX_CMP_REQUEUE): Define.
+       (__pthread_cond_broadcast): Set __futex to 2 * __total_seq.
+       Use FUTEX_CMP_REQUEUE operation instead of FUTEX_REQUEUE.
+       Pass __futex value from before the unlock and __futex address instead
+       of address of low 32-bits of __wakeup_seq to futex syscall.
+       Fallback to FUTEX_WAKE all on any errors.
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_CMP_REQUEUE):
+       Define.
+       (lll_futex_requeue): Add val argument, use FUTEX_CMP_REQUEUE
+       internally.  Return non-zero if error, zero if success.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_cond_t):
+       Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_CMP_REQUEUE):
+       Define.
+       (lll_futex_requeue): Add val argument, return 1 unconditionally
+       for the time being.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h (pthread_cond_t):
+       Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (FUTEX_CMP_REQUEUE):
+       Define.
+       (lll_futex_requeue): Add val argument, use FUTEX_CMP_REQUEUE
+       internally.  Return non-zero if error, zero if success.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
+       (pthread_cond_t): Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/unix/sysv/linux/sparc/lowlevellock.h (FUTEX_CMP_REQUEUE):
+       Define.
+       (lll_futex_requeue): Add val argument, use FUTEX_CMP_REQUEUE
+       internally.  Return non-zero if error, zero if success.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h (pthread_cond_t):
+       Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (FUTEX_CMP_REQUEUE):
+       Define.
+       (lll_futex_requeue): Add val argument, use FUTEX_CMP_REQUEUE
+       internally.  Return non-zero if error, zero if success.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h (pthread_cond_t):
+       Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h (pthread_cond_t):
+       Add __data.__futex field, reshuffle __data.__clock.
+       * sysdeps/pthread/pthread_cond_signal.c (__pthread_cond_signal):
+       Increment __futex at the same time as __wakeup_seq or __total_seq.
+       Pass address of __futex instead of address of low 32-bits of
+       __wakeup_seq to futex syscall.
+       * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Likewise.
+       Pass __futex value from before releasing internal lock
+       to FUTEX_WAIT.
+       * sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
+       Likewise.  Avoid unnecessary shadowing of variables.
+       * sysdeps/pthread/pthread_cond_broadcast.c (__pthread_cond_broadcast):
+       Set __futex to 2 * __total_seq.  Pass __futex value from before the
+       unlock and __futex address instead of address of low 32-bits of
+       __wakeup_seq to futex_requeue macro, adjust for new return value
+       meaning.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+       (__pthread_cond_signal): Increment __futex at the same time as
+       __wakeup_seq or __total_seq.  Pass address of __futex instead of
+       address of low 32-bits of __wakeup_seq to futex syscall.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+       (__pthread_cond_wait): Likewise.  Pass __futex value from before
+       releasing internal lock to FUTEX_WAIT.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+       (FUTEX_CMP_REQUEUE): Define.
+       (__pthread_cond_broadcast): Set __futex to 2 * __total_seq.
+       Use FUTEX_CMP_REQUEUE operation instead of FUTEX_REQUEUE.
+       Pass __futex value from before the unlock and __futex address instead
+       of address of low 32-bits of __wakeup_seq to futex syscall.
+       Fallback to FUTEX_WAKE all on any errors.
+
+2004-06-03  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h (lll_mutex_lock):
+       Add nop to align the end of critical section.
+       (lll_mutex_cond_lock, lll_mutex_timedlock): Likewise.
+
+2004-06-01  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_cond_t):
+       Add __broadcast_seq field.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: Mark
+       all waiters as woken with woken_seq and bump broadcast counter.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Use new
+       __broadcast_seq.  Increment __woken_seq correctly when cleanuped.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+       Comment typo fixes.  Avoid returning -ETIMEDOUT.
+
+2004-06-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__condvar_tw_cleanup): Fix access to saved broadcast_seq value.
+       Reported by Kaz Kojima.
+
+2004-05-25  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/aio_misc.h: New file.
+
+2004-05-21  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Compare
+       __broadcast_seq with bc_seq after acquiring internal lock instead of
+       before it.
+
+2004-05-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (.NOTPARALLEL): Only serialize make check/xcheck, not
+       compilation.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Avoid returning -ETIMEDOUT.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+       (pthread_cond_t): Add __data.__broadcast_seq field.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+       (FRAME_SIZE): Define.
+       (__pthread_cond_timedwait): Use it.  Store/check broadcast_seq.
+       Comment typo fixes.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S (FRAME_SIZE):
+       Define.
+       (__pthread_cond_wait): Use it.  Store/check broadcast_seq.  Comment
+       typo fixes.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Increment broadcast_seq.  Comment typo
+       fixes.
+
+2004-05-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/lowlevelcond.sym: Add broadcast_seq entry.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_cond_t):
+       Add __broadcast_seq field.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Mark
+       all waiters as woken with woken_seq and bump broadcast counter.
+       * sysdeps/pthread/pthread_cond_broadcast.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Use new
+       __broadcast_seq field.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/pthread/pthread_cond_wait.c: Likewise.
+       * sysdeps/pthread/pthread_cond_timedwait.c: Likewise.
+       * pthread_cond_init.c: Initialize __broadcast_seq field.
+       * Makefile (tests): Add tst-cond17 and tst-cond18.
+       Add .NOTPARALLEL goal.
+       * tst-cond16.c: New file.  From Jakub.
+       * tst-cond17.c: New file.  From Jakub.
+       * tst-cond18.c: New file.  From Jakub.
+
+2004-05-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Correct some
+       unwind info.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S:
+       Parametrize frame size.  Correct some unwind info.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+
+2004-05-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-stack3.c: Note testing functionality beyond POSIX.
+
+2004-05-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (USE___THREAD):
+       Change conditional from ifdef to if.
+
+2004-04-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (SYSDEP_CANCEL_ERRNO,
+       SYSDEP_CANCEL_ERROR): Define.
+       (PSEUDO): Use it.
+
+2004-05-01  Jakub Jelinek  <jakub@redhat.com>
+
+       * Versions (libpthread): Remove __pthread_cleanup_upto@@GLIBC_PRIVATE.
+
+2004-04-20  Jakub Jelinek  <jakub@redhat.com>
+
+       * sem_unlink.c (sem_unlink): Change EPERM into EACCES.
+
+2004-04-19  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Add frame info.
+       Use HIDDEN_JUMPTARGET to jump to __pthread_unwind.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S: Remove unneeded frame
+       info.  Use HIDDEN_JUMPTARGET to jump to __pthread_unwind.
+
+2004-04-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/timer_routines.c: Make sure helper
+       thread has all signals blocked.
+
+2004-04-18  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h
+       (SEM_VALUE_MAX): Add missing brace.
+
+2004-04-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/Makefile (tests): Add tst-mqueue8x
+       in rt subdir.
+       (CFLAGS-tst-mqueue8x.c): Add -fexceptions.
+       * sysdeps/pthread/tst-mqueue8x.c: New test.
+       * tst-cancel4.c: Update comment about message queues.
+
+       * sysdeps/pthread/timer_gettime.c (timer_gettime): For expired timer
+       return it_value { 0, 0 }.
+       * sysdeps/pthread/timer_create.c (timer_create): Handle SIGEV_NONE
+       like SIGEV_SIGNAL.
+       * sysdeps/pthread/timer_routines.c (thread_expire_timer): Remove
+       assertion for SIGEV_NONE.
+       (thread_attr_compare): Compare all attributes, not just a partial
+       subset.
+
+2004-04-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/mq_notify.c: Include stdlib.h.
+
+2004-04-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/bits/semaphore.h (SEM_VALUE_MAX):
+       Just use a plain number.
+       * sysdeps/unix/sysv/linux/i386/bits/semaphore.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/semaphore.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/semaphore.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/semaphore.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/semaphore.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h: Likewise.
+
+2004-04-16  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Remove unneeded
+       frame info.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+
+2004-04-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/timer_routines.c: Include errno.h.
+       (timer_helper_thread): Use inline rt_sigtimedwait syscall instead
+       of calling sigwaitinfo.
+
+2004-04-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (allocate_stack): Set reported_guardsize
+       unconditionally.
+       * pthread_getattr_np.c (pthread_getattr_np): Use
+       reported_guardsize instead of guardsize.
+       * descr.h (struct pthread): Add reported_guardsize field.
+
+2004-04-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/mq_notify.c: Shut up GCC warning.
+
+2004-04-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/mq-notify.c: New file.
+
+2004-04-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/bits/local_lim.h (MQ_PRIO_MAX): Define.
+       * sysdeps/unix/sysv/linux/alpha/bits/local_lim.h (MQ_PRIO_MAX): Define.
+       * sysdeps/unix/sysv/linux/ia64/bits/local_lim.h (MQ_PRIO_MAX): Define.
+       * sysdeps/unix/sysv/linux/sparc/bits/local_lim.h (MQ_PRIO_MAX): Define.
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h (_POSIX_MESSAGE_PASSING):
+       Define.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h
+       (_POSIX_MESSAGE_PASSING): Define.
+       * sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h
+       (_POSIX_MESSAGE_PASSING): Define.
+       * sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h
+       (_POSIX_MESSAGE_PASSING): Define.
+
+2004-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-context1.c (fct): Check whether correct stack is used.
+
+2004-04-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Never use
+       matching constraints for asm mem parameters.
+
+       * tst-clock2.c (tf): Don't define unless needed.
+
+2004-03-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * Makefile (link-libc-static): Use $(static-gnulib) instead of
+       $(gnulib).
+
+2004-03-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread-functions.h: Add ptr__nptl_deallocate_tsd.
+       * init.c (pthread_functions): Add ptr__nptl_deallocate_tsd.
+       * pthreadP.h: Declare __nptl_deallocate_tsd.
+       * pthread_create.c (deallocate_tsd): Remove to __nptl_deallocate_tsd.
+       Adjust caller.
+
+       * Makefile (tests): Add tst-tsd5.
+       * tst-tsd5.c: New file.
+
+2004-03-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
+       (__pthread_attr_setaffinity_old): Prepend GLIBC_ to version names
+       is SHLIB_COMPAT check.
+       * sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c
+       (__pthread_attr_getaffinity_old): Likewise.
+       * sysdeps/unix/sysv/linux/pthread_getaffinity.c
+       (__pthread_getaffinity_old): Likewise.
+       * sysdeps/unix/sysv/linux/pthread_setaffinity.c
+       (__pthread_setaffinity_old): Likewise.
+
+2004-03-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (_make_stacks_executable): Call
+       _dl_make_stack_executable first.
+
+2004-03-24  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/i386/pthread_spin_lock.c (pthread_spin_lock): Use "m"
+       constraint instead of "0".
+
+2004-03-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+       (lll_mutex_cond_trylock): Define as wrapper around __lll_cond_trylock.
+
+       * sysdeps/unix/sysv/linux/getpid.c (really_getpid): Reorganize
+       code to avoid warning.
+
+2004-03-24  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
+       (__pthread_attr_setaffinity_old): Remove const.
+
+2004-03-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/smp.h: New file.
+       * sysdeps/unix/sysv/linux/sh/smp.h: New file.
+       * init.c: Define __is_smp.
+       (__pthread_initialize_minimal_internal): Call is_smp_system to
+       initialize __is_smp.
+       * pthreadP.h: Declare __is_smp.
+       Define MAX_ADAPTIVE_COUNT is necessary.
+       * pthread_mutex_init.c: Add comment regarding __spins field.
+       * pthread_mutex_lock.c: Implement adaptive mutex type.
+       * pthread_mutex_timedlock.c: Likewise.
+       * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_mutex_t):
+       Add __spins field.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h: Define
+       lll_mutex_cond_trylock.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
+       Define BUSY_WAIT_NOP.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+
+       * tst-mutex5.c: Add support for testing adaptive mutexes.
+       * tst-mutex7.c: Likewise.
+       * tst-mutex5a.c: New file.
+       * tst-mutex7a.c: New file.
+       * Makefile (tests): Add tst-mutex5a and tst-mutex7a.
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+       (__lll_mutex_timedlock_wait): Preserve r8 and r9 since the
+       vgettimeofday call might destroy the content.
+
+       * sysdeps/ia64/pthread_spin_lock.c (pthread_spin_lock): Use hint
+       @pause in the loop.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_mutex_trylock):
+       No need to restrict type of ret.  Make it int.  Add comment.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_mutex_trylock):
+       Remove unnecessary setne instruction.
+
+2004-03-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/pthread_getaffinity.c
+       (__pthread_getaffinity_new): Use INT_MAX instead of UINT_MAX.
+       * pthread_getattr_np.c (pthread_getattr_np): Double size every cycle.
+       If realloc fails, break out of the loop.
+
+2004-03-20  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/pthread_setaffinity.c
+       (__pthread_setaffinity_old): Fix interface.
+       * sysdeps/unix/sysv/linux/pthread_getaffinity.c
+       (__pthread_getaffinity_old): Likewise.
+
+       * sysdeps/unix/sysv/linux/pthread_setaffinity.c
+       (__pthread_setaffinity_new): Remove duplicate declaration.
+
+2004-03-20  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (CENABLE): Save
+       the return value to a safe register.
+       (CDISABLE): Set the function argument correctly.
+
+2004-03-17  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h (XCHG): Define.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S (__lll_mutex_lock_wait):
+       Rewrite so that only one locked memory operation per round is needed.
+       * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
+       (pthread_barrier_wait): After wakeup, release lock only when the
+       last thread stopped using the barrier object.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+       (__pthread_cond_wait): Don't store mutex address if the current
+       value is ~0l.  Add correct cleanup support and unwind info.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Don't use requeue for pshared condvars.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Update comment.
+       * sysdeps/unix/sysv/linux/sh/pthread_once.S (__pthread_once):
+       Add correct cleanup support and unwind info.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S (__new_sem_wait): Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Add unwind
+       information for syscall wrappers.
+
+2004-03-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/internaltypes.h (struct pthread_attr): Add
+       cpusetsize field, remove next.
+       * sysdeps/pthread/pthread.h (pthread_getaffinity_np): Add new second
+       parameter for size of the CPU set.
+       (pthread_setaffinity_np): Likewise.
+       (pthread_attr_getaffinity_np): Likewise.
+       (pthread_attr_setaffinity_np): Likewise.
+       * sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c: Implement
+       interface change, keep compatibility code.
+       * sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c: Likewise.
+       * sysdeps/unix/sysv/linux/pthread_getaffinity.c: Likewise.
+       * sysdeps/unix/sysv/linux/pthread_setaffinity.c: Likewise.
+       * pthreadP.h: Remove hidden_proto for pthread_getaffinity_np.  Declare
+       __pthread_getaffinity_np.
+       * Versions: Add version for changed interfaces.
+       * tst-attr3.c: Adjust test for interface change.
+       * pthread_getattr_np.c: Query the kernel about the affinity mask with
+       increasing buffer sizes.
+       * pthread_attr_destroy.c: Remove unused list handling.
+       * pthread_attr_init.c: Likewise.
+
+2004-03-17  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/timer_create.c (timer_create): Pass missing
+       first argument to clock_getres so we ever enable kernel timers.
+
+2004-03-15  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * init.c (nptl_version): Add __attribute_used__ to nptl_version.
+
+2004-03-12  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Propagate
+       oldvalue from CENABLE to CDISABLE.
+
+2004-03-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/bits/local_lim.h: Define HOST_NAME_MAX.
+       * sysdeps/unix/sysv/linux/alpha/bits/local_lim.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/local_lim.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/local_lim.h: Likewise.
+
+2004-03-11  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/alpha/tcb-offsets.sym (PID_OFFSET): New.
+       * sysdeps/unix/sysv/linux/alpha/pt-vfork.S: Save/restore PID.
+       * sysdeps/unix/sysv/linux/alpha/vfork.S: New file.
+
+2004-03-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/s390-64/vfork.S (__vfork): Use jgnl
+       instead of jnl instruction to jump to SYSCALL_ERROR_LABEL.
+       * sysdeps/unix/sysv/linux/s390/s390-64/pt-vfork.S (__vfork): Likewise.
+
+2004-03-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * forward.c (__pthread_cond_broadcast_2_0,
+       __pthread_cond_destroy_2_0, __pthread_cond_init_2_0,
+       __pthread_cond_signal_2_0, __pthread_cond_wait_2_0,
+       __pthread_cond_timedwait_2_0): Use return 0 as defaction instead of 0.
+
+2004-03-11  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/tcb-offsets.sym: Add PID.
+       * sysdeps/unix/sysv/linux/sh/pt-vfork.S: Properly handle PID cache.
+       * sysdeps/unix/sysv/linux/sh/vfork.S: New file.
+
+2004-03-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S: No need to
+       include <sysdep-cancel.h>, vfork is no cancellation point.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S: Likewise.
+
+2004-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/s390-32/vfork.S (__vfork): Add
+       libc_hidden_def.
+       * sysdeps/unix/sysv/linux/s390/s390-64/vfork.S (__vfork): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S (__vfork):
+       Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S (__vfork):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S (__vfork): Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S (__vfork): Likewise.
+       * sysdeps/unix/sysv/linux/ia64/pt-vfork.S: Include tcb-offsets.h.
+       * sysdeps/unix/sysv/linux/ia64/vfork.S (__vfork): Use DO_CALL instead
+       of DO_CALL_VIA_BREAK.  Work around a gas problem.
+
+       * sysdeps/unix/sysv/linux/powerpc/pt-vfork.S: Remove.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S: New file.
+       * sysdeps/powerpc/tcb-offsets.sym: Add PID.
+
+       * sysdeps/unix/sysv/linux/ia64/pt-vfork.S (__vfork): Don't use
+       a local register for saving old PID.  Negate PID in parent upon exit.
+
+       * sysdeps/unix/sysv/linux/s390/s390-32/pt-vfork.S: Include
+       tcb-offsets.h.
+       (__vfork): Negate PID if non-zero and set to INT_MIN if zero
+       before syscall, set to the old value in the parent afterwards.
+       * sysdeps/unix/sysv/linux/s390/s390-32/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/pt-vfork.S: Include
+       tcb-offsets.h.
+       (__vfork): Negate PID if non-zero and set to INT_MIN if zero
+       before syscall, set to the old value in the parent afterwards.
+       * sysdeps/unix/sysv/linux/s390/s390-64/vfork.S: New file.
+       * sysdeps/s390/tcb-offsets.sym: Add PID.
+
+       * sysdeps/unix/sysv/linux/sparc/pt-vfork.S: Remove.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S: New file.
+       * sysdeps/sparc/tcb-offsets.sym: Add PID.
+
+2004-03-10  Andreas Schwab  <schwab@suse.de>
+
+       * sysdeps/ia64/tcb-offsets.sym: Add PID.
+       * sysdeps/unix/sysv/linux/ia64/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/ia64/pt-vfork.S: Properly handle PID cache.
+
+2004-03-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-cancel20.c (do_one_test): Clear in_sh_body first.
+       * tst-cancel21.c (do_one_test): Likewise.
+       Reported by Gordon Jin <gordon.jin@intel.com>.
+
+2004-02-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/vfork.S (SAVE_PID): Negate PID
+       if non-zero and set to INT_MIN if zero.
+       * sysdeps/unix/sysv/linux/x86_64/vfork.S (SAVE_PID): Likewise.
+       * sysdeps/unix/sysv/linux/i386/pt-vfork.S: Include tcb-offsets.h.
+       (SAVE_PID, RESTORE_PID): Define.
+       (__vfork): Use it.
+       * sysdeps/unix/sysv/linux/x86_64/pt-vfork.S: Include tcb-offsets.h.
+       Use relative path to avoid including NPTL i386/vfork.S.
+       (SAVE_PID, RESTORE_PID): Define.
+       * sysdeps/unix/sysv/linux/raise.c: Include limits.h.
+       (raise): Handle THREAD_SELF->pid INT_MIN the same as 0.
+       * Makefile (tests): Add tst-vfork1, tst-vfork2, tst-vfork1x and
+       tst-vfork2x.
+       (tests-reverse): Add tst-vfork1x and tst-vfork2x.
+       * tst-vfork1.c: New test.
+       * tst-vfork2.c: New test.
+       * tst-vfork1x.c: New test.
+       * tst-vfork2x.c: New test.
+
+2004-03-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/tcb-offsets.sym: Add PID.
+       * sysdeps/x86_64/tcb-offsets.sym: Likewise.
+       * sysdeps/unix/sysv/linux/i386/vfork.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/vfork.S: New file.
+
+2004-03-08  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/Versions: Remove leading tabs.
+
+2004-03-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * sysdeps/s390/tls.h (INIT_SYSINFO): _dl_sysinfo is now in
+       _rtld_global_ro.
+
+2004-03-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/ia64/tls.h (INIT_SYSINFO): _dl_sysinfo is now in
+       _rtld_global_ro.
+
+       * tst-once4.c: Remove unnecessary macro definition.
+
+       * tst-mutex7.c (do_test): Limit thread stack size.
+       * tst-once2.c (do_test): Likewise.
+       * tst-tls3.c (do_test): Likewise.
+       * tst-tls1.c (do_test): Likewise.
+       * tst-signal3.c (do_test): Likewise.
+       * tst-kill6.c (do_test): Likewise.
+       * tst-key4.c (do_test): Likewise.
+       * tst-join4.c (do_test): Likewise.
+       * tst-fork1.c (do_test): Likewise.
+       * tst-context1.c (do_test): Likewise.
+       * tst-cond2.c (do_test): Likewise.
+       * tst-cond10.c (do_test): Likewise.
+       * tst-clock2.c (do_test): Likewise.
+       * tst-cancel10.c (do_test): Likewise.
+       * tst-basic2.c (do_test): Likewise.
+       * tst-barrier4.c (do_test): Likewise.
+
+2004-03-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/tls.h: Use GLRO instead of GL where appropriate.
+
+2004-03-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Optimize wakeup test.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+       (__pthread_cond_wait): Likewise.
+       * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Likewise.
+       * sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
+       Likewise.
+
+2004-02-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+       (__lll_mutex_lock_wait): Optimize a bit more.  Just one copy of
+       the atomic instruction needed.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+       (__lll_mutex_lock_wait): Likewise.
+
+2004-02-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-cond14 and tst-cond15.
+       * tst-cond14.c: New file.
+       * tst-cond15.c: New file.
+
+2004-02-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/createthread.c (create_thread): Remove use of
+       CLONE_STOPPED.  We cannot use SIGCONT which means CLONE_STOPPED
+       needs to be implemented differently to be useful.
+
+2004-02-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_attr_setschedparam.c: Don't test priority against limits
+       here.  Set ATTR_FLAG_SCHED_SET flag.
+       * pthread_attr_setschedpolicy.c: Set ATTR_FLAG_POLICY_SET flag.
+       * pthread_create.c (__pthread_create_2_1): Copy scheduling attributes
+       from parent thread to child.  If attribute is used and scheduling
+       parameters are not inherited, copy parameters from attribute or
+       compute them.  Check priority value.
+       * pthread_getschedparam.c: If the parameters aren't known yet get
+       them from the kernel.
+       * pthread_setschedparam.c: Set ATTR_FLAG_SCHED_SET and
+       ATTR_FLAG_POLICY_SET flag for thread.
+       * sysdeps/unix/sysv/linux/internaltypes.h: Define ATTR_FLAG_SCHED_SET
+       and ATTR_FLAG_POLICY_SET.
+
+       * sysdeps/pthread/createthread.c: Use tgkill if possible.
+
+       * pthread_attr_getstackaddr.c (__pthread_attr_getstackaddr): Don't
+       fail if stack address hasn't been set.  Just return 0.
+
+2004-02-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests-nolibpthread): Add tst-unload.  Don't link with
+       libpthread for the files in this list.
+       (CFLAGS-tst-unload): Removed.
+       * tst-unload.c (do_test): Don't use complete path for
+       LIBPHREAD_SO.
+
+       * Makefile: Define sonames for tst-tls5mod, tst-_res1mod1, and
+       tst-_res1mod2.
+
+2004-02-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+       (__lll_mutex_lock_wait): Rewrite so that only one locked memory
+       operation per round is needed.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+       (__lll_mutex_lock_wait): Likewise.
+
+2004-02-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel9.c (cleanup): Don't print to stderr.
+
+2004-02-20  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/jmpbuf-unwind.h (_JMPBUF_UNWINDS_ADJ): Fix variable name.
+
+2004-02-20  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
+       (__syscall_error_handler2): Call CDISABLE.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
+       (__syscall_error_handler2): Call CDISABLE.
+
+       * sysdeps/pthread/pthread_barrier_wait.c (pthread_barrier_wait):
+       Release lock before the loop, don't reacquire it.
+
+       * sysdeps/unix/sysv/linux/ia64/dl-sysdep.h (DL_ARGV_NOT_RELRO): Define.
+
+2004-02-19  Andreas Schwab  <schwab@suse.de>
+
+       * sysdeps/pthread/pthread_barrier_wait.c (pthread_barrier_wait):
+       Fix last change.
+
+2004-02-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
+       (pthread_barrier_wait): After wakeup, release lock only when the
+       last thread stopped using the barrier object.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
+       (pthread_barrier_wait): Likewise.
+       * sysdeps/pthread/pthread_barrier_wait.c (pthread_barrier_wait):
+       Likewise.
+       * Makefile (tests): Add tst-barrier4.
+       * tst-barrier4.c: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Perform timeout test while holding
+       internal lock to prevent wakeup race.
+       Patch by Dinakar Guniguntala <dgunigun@in.ibm.com>.
+       * sysdeps/pthread/pthread_cond_timedwait.c
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Likewise.
+
+2004-02-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
+       (__pthread_rwlock_unlock): Access WRITER as 32-bit value.
+       * Makefile (tests): Add tst-rwlock13.
+       * tst-rwlock13.c: New test.
+
+2004-02-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__condvar_tw_cleanup): Little optimization.
+       Patch by Dinakar Guniguntala <dgunigun@in.ibm.com>.
+
+2004-02-16  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c: Replace libc with
+       libpthread as "lib" parameter to SHLIB_COMPAT.
+       (__novmx_siglongjmp): Fix typo in function name.
+       (__novmx_longjmp): Fix typo in function name.
+
+2004-02-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Add a
+       __builtin_expect.
+
+       * sysdeps/generic/pt-longjmp.c: Moved to...
+       * sysdeps/pthread/pt-longjmp.c: ...here.  New file.
+
+2004-01-29  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * Makefile (libpthread-routines): Add pt-cleanup.
+       * pt-longjmp.c: Removed.
+       * pt-cleanup.c: Copied __pthread_cleanup_upto to here. New file.
+       * sysdeps/generic/pt-longjmp.c: Copied longjmp to here. New file.
+       * sysdeps/unix/sysv/linux/powerpc/Versions: New file.
+       Version longjmp, siglongjmp for GLIBC_2.3.4.
+       * sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c: New File.
+
+2004-02-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_timedwait.c
+       (__pthread_cond_timedwait): Optimize.  Drop internal lock earlier.
+       Reuse code.  Add __builtin_expects.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Get internal lock in case timeout has
+       passed before the futex syscall.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+2004-01-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c: Pretty printing.
+
+       * sysdeps/pthread/createthread.c (create_thread): Don't add
+       CLONE_DETACHED bit if it is not necessary.
+
+2004-01-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_getattr_np.c: Include ldsodefs.h.
+
+2004-01-16  Richard Henderson  <rth@redhat.com>
+
+       * allocatestack.c: Don't declare __libc_stack_end.
+       * init.c (__pthread_initialize_minimal_internal): Likewise.
+       * pthread_getattr_np.c (pthread_getattr_np): Likewise.
+
+2004-01-15  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/alpha/tls.h (tcbhead_t): Add private.
+       (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN, TLS_TCB_SIZE,
+       TLS_PRE_TCB_SIZE, TLS_TCB_ALIGN, INSTALL_DTV, INSTALL_NEW_DTV,
+       GET_DTV, THREAD_DTV, THREAD_SELF, DB_THREAD_SELF): Match ia64.
+       (TLS_TCB_OFFSET, THREAD_ID, NO_TLS_OFFSET): Remove.
+       (THREAD_GETMEM, THREAD_GETMEM_NC): Simplify.
+       (THREAD_SETMEM, THREAD_SETMEM_NC): Likewise.
+       * sysdeps/unix/sysv/linux/alpha/createthread.c (TLS_VALUE): Match ia64.
+
+2004-01-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (pthread_functions): Make array const.
+
+2004-01-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (__make_stacks_executable): Change interface.
+       Check parameters.  Pass parameter on to libc counterpart.
+       * pthreadP.h: Change declaration.
+
+2004-01-13  Richard Henderson  <rth@redhat.com>
+
+       * pthread_attr_setstack.c (__old_pthread_attr_setstack): Use
+       prototype form.
+       * pthread_attr_setstacksize.c (__old_pthread_attr_setstacksize):
+       Likewise.
+
+       * sysdeps/alpha/Makefile: New file.
+       * sysdeps/alpha/tcb-offsets.sym: New file.
+       * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (SINGLE_THREAD_P):
+       Use MULTIPLE_THREADS_OFFSET to implement !libpthread !libc version.
+
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Rewrite based
+       on powerpc version.
+
+2004-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-backtrace1.
+       * tst-backtrace1.c: New test.
+
+2003-12-11  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * sysdeps/alpha/tls.h (DB_THREAD_SELF): Pass bit size of thread
+       register as second parameter to the REGISTER macro.
+       * sysdeps/ia64/tls.h (DB_THREAD_SELF): Likewise.
+       * sysdeps/powerpc/tls.h (DB_THREAD_SELF): Likewise.
+       * sysdeps/sh/tls.h (DB_THREAD_SELF): Likewise.
+       * sysdeps/sparc/tls.h (DB_THREAD_SELF): Likewise.
+       * sysdeps/s390/tls.h (DB_THREAD_SELF): Pass __WORDSIZE as bit size
+       of thread register as second parameter to REGISTER macro in 64 case.
+
+2004-01-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/Makefile (CFLAGS-getpid.c): Removed.
+       (CFLAGS-getpid.o): Defined.
+       (CFLAGS-getpid.os): Defined.
+
+2003-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_getattr_np.c (pthread_getattr_np): Make sure stack info
+       returned for main thread does not overlap with any other VMA.
+       Patch by Jakub Jelinek.
+
+2003-12-29  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-raise1.c: Include stdio.h.
+
+2003-12-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/raise.c (raise): Protect pid = selftid
+       setting with __ASSUME_TGKILL || defined __NR_tgkill.
+       If pid is 0, set it to selftid.
+       * sysdeps/unix/sysv/linux/getpid.c (really_getpid): Make inline.
+       Don't set self->pid but self->tid.  If self->pid == 0 and self->tid
+       != 0, return self->tid without doing a syscall.
+       * descr.h (struct pthread): Move pid field after tid.
+
+       * Makefile (tests): Add tst-raise1.
+       * tst-raise1.c: New file.
+
+2003-12-23  Roland McGrath  <roland@redhat.com>
+
+       * tst-oddstacklimit.c: New file.
+       * Makefile (tests): Add it.
+       (tst-oddstacklimit-ENV): New variable.
+
+       * init.c (__pthread_initialize_minimal_internal): Round stack rlimit
+       value up to page size for __default_stacksize.
+
+2003-12-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-eintr5.
+       * tst-eintr5.c: New file.
+
+       * eintr.c (eintr_source): Prevent sending signal to self.
+
+       * tst-eintr2.c (tf1): Improve error message.
+
+2003-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/Makefile (CFLAGS-getpid.c): Define.
+       * sysdeps/unix/sysv/linux/getpid.c: New file.
+       * pthread_cancel.c: Add comment explaining use of PID field.
+       * sysdeps/unix/sysv/linux/pthread_kill.c: Likewise.
+       * pthread_getattr_np.c: Use abs() when comparing PID and TID fields.
+       * sysdeps/unix/sysv/linux/fork.c: Negate PID field of parent
+       temporarily to signal the field must not be relied on and updated
+       by getpid().
+       * sysdeps/unix/sysv/linux/pt-raise.c: Handle case where PID is
+       temporarily negative.
+       * sysdeps/unix/sysv/linux/raise.c: Likewise.
+
+2003-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * eintr.c (setup_eintr): Add new parameter.  Pass to thread function.
+       (eintr_source): If ARG != NULL, use pthread_kill.
+       * tst-eintr1.c: Adjust for this change.
+       * tst-eintr2.c: Likewise.
+       * Makefile (tests): Add tst-eintr3 and tst-eintr4.
+       * tst-eintr3.c: New file.
+       * tst-eintr4.c: New file.
+
+2003-12-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * libc-cancellation.c (__libc_enable_asynccancel): Don't cancel
+       if CANCELSTATE_BITMASK is set.
+       * sysdeps/pthread/librt-cancellation.c (__librt_enable_asynccancel):
+       Likewise.
+
+       * Makefile (tests): Add tst-cancel22 and tst-cancel23.
+       (tests-reverse): Add tst-cancel23.
+       * tst-cancel22.c: New test.
+       * tst-cancel23.c: New test.
+
+2003-12-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-eintr1.c: Better error messages.
+
+       * Makefile (tests): Add tst-eintr2.
+       * tst-eintr2.c: New file.
+
+2003-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-cancel21 and tst-cancelx21.
+       (CFLAGS-tst-cancelx21.c): Set.
+       * tst-cancel21.c: New test.
+       * tst-cancelx21.c: New test.
+
+       * unwind.c (FRAME_LEFT): Add adj argument.  Subtract it from each
+       comparison operand.
+       (unwind_stop): Use _JMPBUF_CFA_UNWINDS_ADJ macro instead of
+       _JMPBUF_CFA_UNWINDS.  Adjust FRAME_LEFT invocations.
+       * pt-longjmp.c: Include jmpbuf-unwind.h.
+       (__pthread_cleanup_upto): Use _JMPBUF_UNWINDS_ADJ macro instead of
+       _JMPBUF_UNWINDS.  Adjust compared pointers.
+       * init.c (__pthread_initialize_minimal_internal): Initialize
+       pd->stackblock_size.
+       * sysdeps/pthread/jmpbuf-unwind.h: Removed.
+       * sysdeps/alpha/jmpbuf-unwind.h: New file.
+       * sysdeps/i386/jmpbuf-unwind.h: New file.
+       * sysdeps/powerpc/jmpbuf-unwind.h: New file.
+       * sysdeps/s390/jmpbuf-unwind.h: New file.
+       * sysdeps/sh/jmpbuf-unwind.h: New file.
+       * sysdeps/sparc/sparc32/jmpbuf-unwind.h: New file.
+       * sysdeps/x86_64/jmpbuf-unwind.h: New file.
+       * sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h: Include stdint.h.
+       (_JMPBUF_CFA_UNWINDS): Remove.
+       (_JMPBUF_CFA_UNWINDS_ADJ, _JMPBUF_UNWINDS_ADJ): Define.
+
+2003-12-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-cancel20 and tst-cancelx20.
+       (CFLAGS-tst-cancelx20.c): Set.
+       * tst-cancel20.c: New test.
+       * tst-cancelx20.c: New test.
+
+2003-12-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (__pthread_initialize_minimal_internal): Don't treat
+       architectures with separate register stack special here when
+       computing default stack size.
+
+2003-12-17  Roland McGrath  <roland@redhat.com>
+
+       * Makefile (tst-cancelx7-ARGS): New variable.
+       Reportd by Greg Schafer <gschafer@zip.com.au>.
+
+2003-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-stack3.  Depend on $(objpfx)tst-stack3-mem.
+       (generated): Add tst-stack3.mtrace and tst-stack3-mem.
+       (tst-stack3-ENV): Set.
+       ($(objpfx)tst-stack3-mem): New.
+       * tst-stack3.c: New test.
+
+2003-12-10  David Mosberger  <davidm@hpl.hp.com>
+
+       * sysdeps/unix/sysv/linux/ia64/pt-initfini.c (_init_EPILOG_BEGINS):
+       Add unwind directives.  Drop unused .regstk directive.
+       (_fini_EPILOG_BEGINS): Add unwind directives.
+
+2003-12-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_futex_wait):
+       Assume parameter is a pointer.
+       (lll_futex_wake): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_futex_wait):
+       Likewise.
+       (lll_futex_wake): Likewise.
+       Reported by Boris Hu.
+       * sysdeps/unix/sysv/linux/unregister-atfork.c
+       (__unregister_atfork): Pass pointer to refcntr to lll_futex_wait.
+
+       * sysdeps/unix/sysv/linux/sem_wait.c (__new_sem_wait): Simplify a bit.
+
+2003-12-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/bits/libc-lock.h (__rtld_lock_initialize): Define.
+       * sysdeps/unix/sysv/linux/fork.c (__libc_fork): Call
+       __rtld_lock_initialize for ld.so lock.
+       Patch in part by Adam Li <adam.li@intel.com>.
+
+2003-12-02  David Mosberger  <davidm@hpl.hp.com>
+
+       * Makefile (link-libc-static): Remove -lgcc_eh---it's already mentioned
+       in $(gnulib).  Also, remove stale comment.
+
+2003-11-12  David Mosberger  <davidm@hpl.hp.com>
+
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (PSEUDO): Take
+       advantage of new syscall stub and optimize accordingly.
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__NR_futex): Rename
+       from SYS_futex, to match expectations of
+       sysdep.h:DO_INLINE_SYSCALL.
+       (lll_futex_clobbers): Remove.
+       (lll_futex_timed_wait): Rewrite in terms of DO_INLINE_SYSCALL.
+       (lll_futex_wake): Likewise.
+       (lll_futex_requeue): Likewise.
+       (__lll_mutex_trylock): Rewrite to a macro, so we can include this
+       file before DO_INLINE_SYSCALL is defined (proposed by Jakub
+       Jelinek).
+       (__lll_mutex_lock): Likewise.
+       (__lll_mutex_cond_lock): Likewise.
+       (__lll_mutex_timed_lock): Likewise.
+       (__lll_mutex_unlock): Likewise.
+       (__lll_mutex_unlock_force): Likewise.
+
+       * sysdeps/ia64/tls.h: Move declaration of __thread_self up so it
+       comes before the include of <sysdep.h>.
+       (THREAD_SELF_SYSINFO): New macro.
+       (THREAD_SYSINFO): Likewise.
+       (INIT_SYSINFO): New macro.
+       (TLS_INIT_TP): Call INIT_SYSINFO.
+
+       * sysdeps/ia64/tcb-offsets.sym: Add SYSINFO_OFFSET.
+
+       * sysdeps/pthread/createthread.c (create_thread): Use
+       THREAD_SELF_SYSINFO and THREAD_SYSINFO instead of open code.
+       * allocatestack.c (allocate_stack): Use THREAD_SYSINFO and
+       THREAD_SELF_SYSINFO instead of open code.
+       * sysdeps/i386/tls.h (THREAD_SELF_SYSINFO): New macro.
+       (THREAD_SYSINFO): Likewise.
+
+       * sysdeps/unix/sysv/linux/ia64/dl-sysdep.h: New file.
+
+       * sysdeps/unix/sysv/linux/ia64/pt-vfork.S: Work around gas problem.
+
+2003-12-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/pt-initfini.c: Use .init_array
+       instead of .init.  Patch by David Mosberger.
+
+2003-11-30  Thorsten Kukuk  <kukuk@suse.de>
+
+       * sysdeps/pthread/configure.in: Remove broken declaration in C
+       cleanup handling check.
+
+2003-11-30  Andreas Jaeger  <aj@suse.de>
+
+       * Makefile (CFLAGS-pt-initfini.s): Add $(fno_unit_at_a_time).
+       * sysdeps/unix/sysv/linux/x86_64/Makefile (CFLAGS-pt-initfini.s):
+       Likewise.
+
+2003-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/internaltypes.h (ATTR_FLAG_OLDATTR): Define.
+       * pthread_attr_destroy.c: Include shlib-compat.h.
+       (__pthread_attr_destroy): Return immediately if ATTR_FLAG_OLDATTR
+       is set in iattr->flags.
+       * pthread_attr_init.c (__pthread_attr_init_2_0): Set ATTR_FLAG_OLDATTR.
+
+2003-11-21  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (distribute): Add tst-cleanup4aux.c.
+
+       * tst-cond12.c (prepare): Add prototype.  Move after test-skeleton.c
+       include.
+
+2003-11-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cond12.c (do_test): If USE_COND_SIGNAL is defined, use
+       pthread_cond_signal.
+
+       * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Don't
+       store mutex address if the current value is ~0l.
+       * sysdeps/pthread/pthread_cond_timedwait.c
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/pthread/pthread_cond_broadcast.c
+       (__pthread_cond_broadcast): Don't use requeue for pshared
+       condvars.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+       (__pthread_cond_wait): Don't store mutex address if the current
+       value is ~0l.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Don't use requeue for pshared
+       condvars.
+
+       * pthread_cond_init.c (__pthread_cond_init): Initialize __mutex
+       element with ~0l for pshared condvars, with NULL otherwise.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+       (__pthread_cond_wait): Don't store mutex address if the current
+       value is ~0l.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Don't use requeue for pshared
+       condvars.
+
+       * Makefile: Add rules to build and run tst-cond12 and tst-cond13.
+       * tst-cond12.c: New file.
+       * tst-cond13.c: New file.
+
+2003-11-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/configure.in: Make missing forced unwind support
+       fatal.
+
+2003-11-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h: Don't declare __pthread_unwind as weak inside libpthread.
+
+2003-11-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile: Add magic to clean up correctly.
+
+2003-11-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * unwind.c (FRAME_LEFT): Define.
+       (unwind_stop): Handle old style cleanups here.
+       (__pthread_unwind): Handle old style cleanups only if
+       !HAVE_FORCED_UNWIND.
+       * Makefile (tests): Add tst-cleanup4 and tst-cleanupx4.
+       (CFLAGS-tst-cleanupx4.c): Add -fexceptions.
+       ($(objpfx)tst-cleanup4): Depend on $(objpfx)tst-cleanup4aux.o.
+       ($(objpfx)tst-cleanupx4): Likewise.
+       * tst-cleanup4.c: New test.
+       * tst-cleanup4aux.c: New.
+       * tst-cleanupx4.c: New test.
+
+2003-11-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/bits/stdio-lock.h: Use lll_*lock instead of
+       lll_mutex_*lock macros to skip atomic operations on some archs.
+
+2003-11-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/tst-timer.c (main): Initialize
+       sigev2.sigev_value as well.
+
+2003-10-15  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/pthread/configure.in: Barf if visibility attribute support
+       is missing.
+       * sysdeps/pthread/configure: Regenerated.
+
+2003-10-09  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Completely revamp the
+       locking macros.  No distinction between normal and mutex locking
+       anymore.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Rewrite mutex locking.
+       Merge bits from lowlevelmutex.S we still need.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S: Remove.
+       * sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/not-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Adjust for
+       new mutex implementation.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (PSEUDO): Also defined
+       symbol for entry point to avoid cancellation.
+
+2003-10-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Backout 2003-10-02
+       changes.
+       (SAVE_OLDTYPE_0): Fix a typo.
+
+2003-10-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S (__pthread_once):
+       Check __sigsetjmp return value.  Reported by Daniel Jacobowitz.
+
+2003-10-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (DOCARGS_1): Use
+       correct offset.
+
+2003-10-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-cancel19.
+       * tst-cancel19.c: New test.
+
+2003-10-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Fix saving and
+       restoring of the old cancellation type.
+
+2003-09-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/malloc-machine.h: Remove misleading comment.
+
+2003-09-27  Wolfram Gloger  <wg@malloc.de>
+
+       * sysdeps/pthread/malloc-machine.h: New file
+
+2003-09-24  Roland McGrath  <roland@redhat.com>
+
+       * allocatestack.c (__make_stacks_executable): Don't ignore return
+       value from _dl_make_stack_executable.
+
+2003-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (__make_stacks_executable): Also change
+       permission of the currently unused stacks.
+
+       * allocatestack.c (change_stack_perm): Split out from
+       __make_stacks_executable.
+       (allocate_stack): If the required permission changed between the time
+       we started preparing the stack and queueing it, change the permission.
+       (__make_stacks_executable): Call change_stack_perm.
+
+       * Makefile: Build tst-execstack-mod locally.
+       * tst-execstack-mod.c: New file.
+
+2003-09-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Only add tst-execstack if have-z-execstack is yes.
+
+2003-09-23  Roland McGrath  <roland@redhat.com>
+
+       * tst-execstack.c: New file.
+       * Makefile (tests): Add it.
+       ($(objpfx)tst-execstack, $(objpfx)tst-execstack.out): New targets.
+       (LDFLAGS-tst-execstack): New variable.
+
+       * allocatestack.c (allocate_stack): Use GL(dl_stack_flags) to decide
+       whether to use PROT_EXEC for stack mmap.
+       (__make_stacks_executable): New function.
+       * pthreadP.h: Declare it.
+       * init.c (__pthread_initialize_minimal_internal): Set
+       GL(dl_make_stack_executable_hook) to that.
+
+2003-09-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Adjust for latest
+       recommendation from AMD re avoidance of lock prefix.
+
+2003-09-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/lowlevellock.c (__lll_timedlock_wait): Use
+       lll_futex_timed_wait instead of lll_futex_wait.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/lowlevelmutex.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/libc-lowlevellock.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/libc-lowlevelmutex.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/sem_trywait.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/sem_wait.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/sem_post.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c: Removed.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Include atomic.h.
+       Completely revamp the locking macros.  No distinction between
+       normal and mutex locking anymore.
+       * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_lock_wait,
+       __lll_lock_timedwait): Fix prototypes.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (__lll_lock_wait,
+       __lll_lock_timedwait): Likewise.
+       (lll_mutex_lock, lll_mutex_cond_lock): Use _val instead of _bool
+       macros, add __builtin_expect.
+       (lll_mutex_timedlock): Likewise.  Fix return value.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S: Removed.
+       * sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S: Removed.
+       * sysdeps/unix/sysv/linux/i386/i586/lowlevelmutex.S: Removed.
+       * sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S: Removed.
+       * sysdeps/unix/sysv/linux/i386/i686/lowlevelmutex.S: Removed.
+       * sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S: Removed.
+       * sysdeps/unix/sysv/linux/lowlevelmutex.c: Removed.
+       * sysdeps/unix/sysv/linux/libc-lowlevelmutex.c: Removed.
+
+2003-09-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+       (__lll_mutex_lock_wait): Minor optimization to avoid one atomic
+       operation if possible.
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Don't play tricks
+       like jumping over the lock prefix.
+
+2003-09-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Completely revamp the
+       locking macros.  No distinction between normal and mutex locking
+       anymore.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Rewrite mutex
+       locking.  Merge bits from lowlevelmutex.S we still need.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/lowlevellock.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S: Removed.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S: Removed.
+       * Makefile (routines): Remove libc-lowlevelmutex.
+       (libpthread-rountines): Remove lowlevelmutex.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Adjust
+       for new mutex implementation.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S: Likewise
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: Likewise.
+       Don't use requeue.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Likewise.
+       * sysdeps/pthread/pthread_cond_signal.c: Don't use requeue.
+
+2003-09-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Don't match memory
+       in parameters of asm with output parameters.
+
+       * pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Change
+       type of DECR parameter to int.
+       * pthreadP.h: Adjust prototype of __pthread_mutex_unlock_usercnt.
+
+2003-09-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-attr3.c (tf, do_test): Print stack start/end/size and
+       guardsize for each thread.
+
+2003-09-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread.h (pthread_getattr_np): Clarify usage.
+       * sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
+       (pthread_attr_setaffinity_np): Handle cpuset == NULL.
+
+       * sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c
+       (pthread_attr_getaffinity_np): Don't segfault if iattr->cpuset is
+       NULL.
+       * pthread_getattr_np.c: Set cpuset using pthread_getaffinity_np.
+       * pthreadP.h (pthread_getaffinity_np): Add hidden_proto.
+       * sysdeps/unix/sysv/linux/pthread_getaffinity.c
+       (pthread_getaffinity_np): Add hidden_def.
+
+       * Makefile (tests): Add tst-attr3.
+       * tst-attr3.c: New test.
+
+       * sysdeps/i386/Makefile (CFLAGS-tst-align.c): Remove.
+
+2003-09-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/i386/Makefile (CFLAGS-pthread_create.c,
+       CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
+
+2003-09-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (CFLAGS-tst-align.c): Add $(stack-align-test-flags).
+       * tst-align.c: Include tst-stack-align.h.
+       (tf, do_test): Use TEST_STACK_ALIGN macro.
+
+2003-09-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_attr_init.c (__pthread_attr_init_2_0): Remove unused
+       variable.
+
+2003-09-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_getattr_np.c (pthread_getattr_np): Correctly fill in the
+       stack-related values for the initial thread.
+
+2003-09-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (CFLAGS-pthread_once.c): Add $(uses-callbacks).
+
+2003-09-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_mutex_lock.c: Minor code rearrangements.
+
+2003-09-05  Roland McGrath  <roland@redhat.com>
+
+       * pthread_create.c (__pthread_pthread_sizeof_descr): Removed.
+       Instead, include ../nptl_db/db_info.c to do its magic.
+       * pthread_key_create.c (__pthread_pthread_keys_max): Removed.
+       (__pthread_pthread_key_2ndlevel_size): Likewise.
+       * sysdeps/alpha/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/i386/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/ia64/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/powerpc/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/s390/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/sh/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/sparc/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/x86_64/tls.h (DB_THREAD_SELF): New macro.
+       * sysdeps/alpha/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/generic/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/i386/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/ia64/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/powerpc/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/s390/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/sh/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/sparc/td_ta_map_lwp2thr.c: File removed.
+       * sysdeps/x86_64/td_ta_map_lwp2thr.c: File removed.
+
+2003-09-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Change type
+       of pthread_t to be compatible with LT.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
+
+2003-09-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/not-cancel.h (fcntl_not_cancel): Define.
+
+2003-09-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * unwind-forcedunwind.c: Move to...
+       * sysdeps/pthread/unwind-forcedunwind.c: ...here.
+       (pthread_cancel_init): Use ARCH_CANCEL_INIT if defined.
+       * sysdeps/pthread/jmpbuf-unwind.h: New file.
+       * sysdeps/unix/sysv/linux/ia64/unwind-forcedunwind.c: New file.
+       * sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h: New file.
+       * unwind.c: Include jmpbuf-unwind.h.
+       (unwind_stop): Use _JMPBUF_CFA_UNWINDS macro.
+
+2003-09-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/bits/local_lim.h: New file.
+       * sysdeps/unix/sysv/linux/ia64/Versions (libpthread): Export
+       pthread_attr_setstack and pthread_attr_setstacksize @@GLIBC_2.3.3.
+       * sysdeps/unix/sysv/linux/alpha/bits/local_lim.h: New file.
+       * sysdeps/unix/sysv/linux/alpha/Versions: New file.
+       * sysdeps/unix/sysv/linux/sparc/bits/local_lim.h: New file.
+       * sysdeps/unix/sysv/linux/sparc/Versions: New file.
+       * pthread_attr_setstack.c (__old_pthread_attr_setstack): New function.
+       (pthread_attr_setstack): If PTHREAD_STACK_MIN != 16384, export
+       as @@GLIBC_2.3.2 and also export compatibility @GLIBC_2.2.
+       * pthread_attr_setstacksize.c (__old_pthread_attr_setstacksize): New
+       function.
+       (pthread_attr_setstacksize): If PTHREAD_STACK_MIN != 16384, export
+       as @@GLIBC_2.3.2 and also export compatibility @GLIBC_2.1.
+       * Makefile (tests): Add tst-stack2.
+       * tst-stack2.c: New test.
+       * tst-stack1.c: Include limits.h and sys/param.h.
+       (do_test): Set size to MAX (4 * getpagesize (), PTHREAD_STACK_MIN).
+
+       * pthread_condattr_setpshared.c: Include errno.h.
+       (pthread_condattr_setpshared): Return EINVAL if pshared
+       is neither PTHREAD_PROCESS_PRIVATE nor PTHREAD_PROCESS_SHARED.
+
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO): Also
+       defined symbol for entry point to avoid cancellation.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO):
+       Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (PSEUDO):
+       Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h (PSEUDO):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h (PSEUDO):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h (PSEUDO):
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/not-cancel.h (__open_nocancel,
+       __close_nocancel, __read_nocancel, __write_nocancel,
+       __waitpid_nocancel): Add attribute_hidden.  If not in libc.so,
+       libpthread.so or librt.so, define to corresponding function
+       without _nocancel suffix.
+       * sysdeps/unix/sysv/linux/s390/not-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/powerpc/not-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/sparc/not-cancel.h: New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/not-cancel.h: Fix a typo.
+
+2003-09-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/not-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/x86_64/not-cancel.h: New file.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Make sure the code
+       in subsections has a symbol associated with it.
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (PSEUDO): Also
+       defined symbol for entry point to avoid cancellation.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Likewise.
+
+2003-09-01  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests): Add tst-tls5.
+       (module-names): Add tst-tls5mod{,a,b,c,d,e,f}.
+       ($(objpfx)tst-tls5mod{,a,b,c,d,e,f}.so-no-z-defs): Set to yes.
+       ($(objpfx)tst-tls5): New.
+       ($(objpfx)tst-tls6.out): Likewise.
+       (tests): Depend on $(objpfx)tst-tls6.out.
+       * tst-tls3.c: Include stdint.h and pthreaddef.h.
+       (do_test): Check pthread_self () return value alignment.
+       * tst-tls3mod.c: Include stdint.h and pthreaddef.h.
+       (tf): Check pthread_self () return value alignment.
+       * tst-tls5.c: New test.
+       * tst-tls5.h: New.
+       * tst-tls5mod.c: New.
+       * tst-tls5moda.c: New.
+       * tst-tls5modb.c: New.
+       * tst-tls5modc.c: New.
+       * tst-tls5modd.c: New.
+       * tst-tls5mode.c: New.
+       * tst-tls5modf.c: New.
+       * tst-tls6.sh: New test.
+
+       * sysdeps/pthread/pthread-functions.h (struct pthread_functions): Add
+       ptr___pthread_cond_timedwait and ptr___pthread_cond_timedwait_2_0.
+       * init.c (pthread_functions): Initialize them.
+       * forward.c (pthread_cond_timedwait@GLIBC_2.0,
+       pthread_cond_timedwait@@GLIBC_2.3.2): New forwards.
+       * Versions (libc): Export pthread_cond_timedwait@GLIBC_2.0,
+       pthread_cond_timedwait@@GLIBC_2.3.2.
+
+2003-09-01  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/timer_create.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/timer_delete.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/timer_getoverr.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/timer_gettime.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/timer_settime.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/Versions: New file.
+
+       * sysdeps/unix/sysv/linux/alpha/aio_cancel.c: New file.
+
+       * sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h: Define
+       _POSIX_THREAD_PRIORITY_SCHEDULING.
+       * sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h: Likewise.
+
+2003-08-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/bits/stdio-lock.h (_IO_acquire_lock): Avoid
+       nested function, use static inline function from libio.h.
+       Code by Richard Henderson.
+
+       * sysdeps/pthread/bits/libc-lock.h: Mark pthread_setcancelstate as
+       weak.
+
+2003-08-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/sparc/sparc64/Versions: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: New file.
+       * sysdeps/unix/sysv/linux/sparc/bits/semaphore.h: New file.
+       * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/sparc/pthread_once.c: New file.
+       * sysdeps/unix/sysv/linux/sparc/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/sparc/fork.c: New file.
+       * sysdeps/unix/sysv/linux/sparc/aio_cancel.c: New file.
+       * sysdeps/sparc/sparc32/sparcv9/pthread_spin_lock.c: New file.
+       * sysdeps/sparc/sparc32/sparcv9/pthread_spin_trylock.c: New file.
+       * sysdeps/sparc/sparc32/sparcv9/pthread_spin_unlock.c: New file.
+       * sysdeps/sparc/sparc32/pthread_spin_lock.c: New file.
+       * sysdeps/sparc/sparc32/pthread_spin_trylock.c: New file.
+       * sysdeps/sparc/sparc32/pthreaddef.h: New file.
+       * sysdeps/sparc/sparc64/pthread_spin_lock.c: New file.
+       * sysdeps/sparc/sparc64/pthread_spin_trylock.c: New file.
+       * sysdeps/sparc/sparc64/pthread_spin_unlock.c: New file.
+       * sysdeps/sparc/sparc64/pthreaddef.h: New file.
+       * sysdeps/sparc/tls.h: New file.
+       * sysdeps/sparc/tcb-offsets.sym: New file.
+       * sysdeps/sparc/Makefile: New file.
+       * sysdeps/sparc/td_ta_map_lwp2thr.c: New file.
+       * init.c [__sparc__] (__NR_set_tid_address): Define.
+
+2003-08-29  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/bits/stdio-lock.h (_IO_acquire_lock,
+       _IO_release_lock): Define.
+
+2003-08-29  Jakub Jelinek  <jakuB@redhat.com>
+
+       * tst-cancel4.c (tf_sigwait, tf_sigwaitinfo, tf_sigtimedwait): Add
+       sigemptyset before sigaddset.  Reported by jreiser@BitWagon.com.
+
+2003-08-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h (pthread_exit): Remove __THROW.
+       (__pthread_cleanup_class): Add missing return types of member
+       functions.
+
+2003-08-26  Steven Munroe <sjmunroe@us.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+       (lll_mutex_unlock_force): Add memory barrier between store and futex
+       syscall.
+
+2003-08-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel4.c (do_test): Also unlink tempfname and remove
+       tempmsg in first loop.
+
+2003-08-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
+       _POSIX_THREAD_PRIORITY_SCHEDULING.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Likewise.
+
+2003-08-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/bits/libc-lock.h [_LIBC && SHARED]
+       (__rtld_lock_default_lock_recursive,
+       __rtld_lock_default_unlock_recursive): Define.
+       [_LIBC && SHARED] (__rtld_lock_lock_recursive,
+       __rtld_lock_unlock_recursive): Define using
+       GL(_dl_rtld_*lock_recursive).
+       * init.c (__pthread_initialize_minimal_internal): Initialize
+       _dl_rtld_lock_recursive and _dl_rtld_unlock_recursive.
+       Lock GL(_dl_load_lock) the same number of times as
+       GL(_dl_load_lock) using non-mt implementation was nested.
+
+       * pthreadP.h (__pthread_cleanup_upto): Add hidden_proto.
+       * pt-longjmp.c (__pthread_cleanup_upto): Add hidden_def.
+
+2003-08-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-cancel17.c (do_test): Make len2 maximum of page size and
+       PIPE_BUF.
+
+2003-08-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthread_create.c (__pthread_create_2_0): Clear new_attr.cpuset.
+
+2003-08-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/createthread.c (do_clone): Move error handling
+       to first syscall error check.  Move syscall error check for tkill
+       into __ASSUME_CLONE_STOPPED #ifdef.
+
+2003-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/createthread.c (do_clone): If __ASSUME_CLONE_STOPPED
+       is not defined, do explicit synchronization.
+       (create_thread): Do not lock pd->lock here.  If __ASSUME_CLONE_STOPPED
+       is not defined also unlock pd->lock for non-debugging case in case
+       it is necessary.
+       * pthread_create.c (start_thread): Always get and release pd->lock
+       if __ASSUME_CLONE_STOPPED is not defined.
+       (start_thread_debug): Removed.  Adjust users.
+       * allocatestack.c (allocate_stack): Always initialize lock if
+       __ASSUME_CLONE_STOPPED is not defined.
+       * Makefile (tests): Add tst-sched1.
+       * tst-sched1.c: New file.
+
+       * sysdeps/pthread/createthread.c (do_clone): Only use
+       sched_setschduler and pass correct parameters.
+
+2003-07-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread.h (pthread_attr_setstackaddr,
+       pthread_attr_setstacksize): Change PTHREAD_STACK_SIZE to
+       PTHREAD_STACK_MIN in comments.
+
+2003-07-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
+       Shut up warnings if INTERNAL_SYSCALL_ERROR_P does not use its first
+       argument.
+       * sysdeps/unix/sysv/linux/timer_create.c (timer_create): Likewise.
+       * pthread_condattr_setclock.c (pthread_condattr_setclock): Likewise.
+       * sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Include pthreaddef.h.
+       (__pthread_cleanup_upto): Fix prototype.
+       (_longjmp_unwind): Adjust caller.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (__lll_mutex_timedlock):
+       Change second argument to const struct pointer.
+       * tst-sem8.c (main): Remove unused s2 and s3 variables.
+       * tst-sem9.c (main): Likewise.
+       * unwind.c: Include string.h for strlen prototype.
+
+2003-07-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Don't use cmov unless HAVE_CMOV is defined.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S:
+       Define HAVE_CMOV.
+       Patch by Nicholas Miell <nmiell@attbi.com>.
+
+2003-07-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * init.c (__pthread_initialize_minimal_internal): Initialize
+       GL(dl_init_static_tls).
+       * pthreadP.h (__pthread_init_static_tls): New prototype.
+       * allocatestack.c (init_one_static_tls, __pthread_init_static_tls):
+       New functions.
+       * Makefile (tests): Add tst-tls4.
+       (modules-names): Add tst-tls4moda and tst-tls4modb.
+       ($(objpfx)tst-tls4): Link against libdl and libpthread.
+       ($(objpfx)tst-tls4.out): Depend on tst-tls4moda.so and
+       tst-tls4modb.so.
+       * tst-tls4.c: New file.
+       * tst-tls4moda.c: New file.
+       * tst-tls4modb.c: New file.
+
+2003-06-19  Daniel Jacobowitz  <drow@mvista.com>
+
+       * sysdeps/pthread/timer_create.c (timer_create): Call timer_delref
+       before __timer_dealloc.
+       * sysdeps/pthread/timer_routines.c (__timer_thread_find_matching):
+       Don't call list_unlink.
+
+2003-07-29  Roland McGrath  <roland@redhat.com>
+
+       * Makefile [$(build-shared) = yes] (tests): Depend on $(test-modules).
+
+2003-07-25  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-cancel17.c (do_test): Check if aio_cancel failed.
+       Don't reuse struct aiocb A if it failed.
+       Write fpathconf (fds[1], _PC_PIPE_BUF) + 2 bytes using aio_write,
+       not just one byte, as that does not block.
+
+2003-07-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/unwind-resume.c: New file.
+       * sysdeps/pthread/Makefile (routines, shared-only-routines): Add
+       unwind-resume in csu subdir.
+       (CFLAGS-unwind-resume.c, CFLAGS-rt-unwind-resume.c): Compile with
+       exceptions.
+       (librt-sysdep_routines, librt-shared-only-routines): Add
+       rt-unwind-resume.
+       * sysdeps/pthread/rt-unwind-resume.c: New file.
+       * unwind-forcedunwind.c: New file.
+       * Makefile (libpthread-routines): Add unwind-forcedunwind.
+       (libpthread-shared-only-routines): Likewise.
+       (CFLAGS-unwind-forcedunwind.c): Compile with exceptions.
+       * pthreadP.h (pthread_cancel_init): New prototype.
+       * pthread_cancel.c (pthread_cancel): Call pthread_cancel_init.
+
+       * sysdeps/pthread/createthread.c (do_thread, create_thread): Make
+       attr argument const struct pthread_attr *.
+
+       * res.c (__res_state): Return __resp.
+       * descr.h: Include resolv.h.
+       (struct pthread): Add res field.
+       * pthread_create.c: Include resolv.h.
+       (start_thread): Initialize __resp.
+       * Makefile (tests): Add tst-_res1.
+       (module-names): Add tst-_res1mod1, tst-_res1mod2.
+       ($(objpfx)tst-_res1mod2.so): Depend on $(objpfx)tst-_res1mod1.so.
+       ($(objpfx)tst-_res1): Depend on $(objpfx)tst-_res1mod2.so and
+       libpthread.
+       * tst-_res1.c: New file.
+       * tst-_res1mod1.c: New file.
+       * tst-_res1mod2.c: New file.
+
+2003-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/createthread.c: Don't define CLONE_STOPPED.
+
+       * Makefile: Define various *-no-z-defs variables for test DSOs
+       which has undefined symbols.
+
+2003-07-21  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once):
+       Retry if the stwcx fails to store once_control.
+
+2003-07-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (libpthread-routines): Add pthread_attr_getaffinity and
+       pthread_attr_setaffinity.
+       * Versions [libpthread] (GLIBC_2.3.3): Likewise.
+       * sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c: New file.
+       * sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c: New file.
+       * pthread_attr_destroy.c: Free cpuset element if allocated.
+       * pthread_create.c: Pass iattr as additional parameter to
+       create_thread.
+       * sysdeps/pthread/createthread.c: If attribute is provided and
+       a new thread is created with affinity set or scheduling parameters,
+       start thread with CLONE_STOPPED.
+       * sysdeps/pthread/pthread.h: Declare pthread_attr_getaffinity and
+       pthread_attr_setaffinity.
+       * sysdeps/unix/sysv/linux/internaltypes.h (struct pthread_attr): Add
+       cpuset element.
+
+2003-07-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-tcancel-wrappers.sh: lseek and llseek are not cancelation points.
+
+2003-07-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/configure.in: Require CFI directives also for
+       ppc and s390.
+
+2003-07-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h (PSEUDO):
+       Add cfi directives.
+
+2003-07-12  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/tcb-offsets.sym: Add RESULT, TID, CANCELHANDLING and
+       CLEANUP_JMP_BUF.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Use more
+       registers as variables.  Call __pthread_mutex_unlock_usercnt.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Store TID
+       not self pointer in __writer.  Compare with TID to determine
+       deadlocks.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S: Add cancellation support.
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Define all the nice
+       macros also when compiling librt.
+
+2003-07-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (CFLAGS-pthread_once.c): Add -fexceptions
+       -fasynchronous-unwind-tables.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+       (PSEUDO): Add cfi directives.
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO):
+       Likewise.
+
+2003-07-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthreadP.h (__pthread_unwind_next, __pthread_register_cancel,
+       __pthread_unregister_cancel): Add prototypes and hidden_proto.
+       * unwind.c (__pthread_unwind_next): Add hidden_def.
+       * cleanup.c (__pthread_register_cancel, __pthread_unregister_cancel):
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S (__new_sem_wait):
+       Use HIDDEN_JUMPTARGET to jump to __pthread_unwind.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S (sem_wait): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S (__pthread_once): Use
+       HIDDEN_JUMPTARGET to call __pthread_register_cancel,
+       __pthread_unregister_cancel and __pthread_unwind_next.
+
+2003-07-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (PSEUDO): Use
+       different symbol for the cancellation syscall wrapper and
+       non-cancellation syscall wrapper.
+       (PSEUDO_END): Define.
+
+2003-07-05  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/alpha/elf/pt-initfini.c: Avoid .ent/.end.
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_futex_wait,
+       lll_futex_timed_wait, lll_futex_wake, lll_futex_requeue): On success
+       return actual return value from the syscall, not 0.
+
+2003-07-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h (struct pthread): Add pid field.
+       * allocatestack.c (allocate_stack): Initialize pid field in descriptor.
+       (__reclaim_stacks): Likewise.
+       * init.c (sigcancel_handler): If __ASSUME_CORRECT_SI_PID is defined
+       also check for PID of the signal source.
+       (__pthread_initialize_minimal_internal): Also initialize pid field
+       of initial thread's descriptor.
+       * pthread_cancel.c: Use tgkill instead of tkill if possible.
+       * sysdeps/unix/sysv/linux/fork.c: Likewise.
+       * sysdeps/unix/sysv/linux/pt-raise.c: Likewise.
+       * sysdeps/unix/sysv/linux/pthread_kill.c: Likewise.
+       * sysdeps/unix/sysv/linux/raise.c: Likewise.
+
+2003-07-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_cleanup_push): Renamed.
+       Fix use of parameter.
+       (__libc_cleanup_pop): Likewise.
+
+2003-07-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (sigcancel_handler): Change parameters to match handler
+       for SA_SIGACTION.  Check signal number and code to recognize
+       invalid invocations.
+
+2003-07-03  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/ia64/td_ta_map_lwp2thr.c (td_ta_map_lwp2thr):
+       Apply sizeof (struct pthread) bias to r13 value.
+
+2003-07-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/configure.in: Require CFI directives.
+
+       * sysdeps/pthread/librt-cancellation.c (__pthread_unwind): Remove
+       definition.
+       * pthreadP.h (__pthread_unwind): Add hidden_proto if used in
+       libpthread compilation.
+       * unwind.c (__pthread_unwind): Add hidden_def.
+       * Versions (libpthread) [GLIBC_PRIVATE]: Add __pthread_unwind.
+
+2003-07-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * libc-cancellation.c (__libc_cleanup_routine): Define.
+       * sysdeps/pthread/bits/libc-lock.h (__pthread_cleanup_push): Define.
+       (__pthread_cleanup_pop): Define.
+
+2003-07-01  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/alpha/elf/pt-initfini.c: New file.
+       * sysdeps/alpha/pthread_spin_lock.S: New file.
+       * sysdeps/alpha/pthread_spin_trylock.S: New file.
+       * sysdeps/alpha/pthreaddef.h: New file.
+       * sysdeps/alpha/td_ta_map_lwp2thr.c: New file.
+       * sysdeps/alpha/tls.h: New file.
+       * sysdeps/unix/sysv/linux/alpha/Makefile: New file.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h: New file.
+       * sysdeps/unix/sysv/linux/alpha/bits/semaphore.h: New file.
+       * sysdeps/unix/sysv/linux/alpha/createthread.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/fork.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/alpha/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/alpha/pthread_once.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/sem_post.c: New file.
+       * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: New file.
+
+2003-07-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Add correct
+       cleanup support and unwind info.
+
+2003-06-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S (__pthread_once):
+       Use correct cleanup handler registration.  Add unwind info.
+       * sysdeps/unix/sysv/linux/unwindbuf.sym: New file.
+       * sysdeps/unix/sysv/linux/Makefile: Add rule to build unwindbuf.h.
+       * tst-once3.c: Add cleanup handler and check it is called.
+       * tst-once4.c: Likewise.
+       * tst-oncex3.c: New file.
+       * tst-oncex4.c: New file.
+       * Makefile: Add rules to build and run tst-oncex3 and tst-oncex4.
+
+2003-06-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/configure.in: Check for C cleanup handling in gcc.
+
+2003-06-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel4.c (tf_msgrcv): Use IPC_PRIVATE in msgget call.
+       (tf_msgsnd): Likewise.
+
+       * tst-cancel4.c (tf_msgrcv): Strengthen test against valid
+       premature returns a bit more.
+
+2003-06-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/librt-cancellation.c: Move __pthread_unwind
+       definition to the front.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Rename
+       the cleanup functions to make the names unique.  Fix dwarf opcode
+       un unwind table.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Rename cleanup
+       functions to make the names unique.  Fix CFA offset for two blocks.
+
+2003-06-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h (class __pthread_cleanup_class): Add
+       missing closing braces.
+       Patch by Christophe Saout <christophe@saout.de>.
+
+2003-06-24  Roland McGrath  <roland@redhat.com>
+
+       * pthread_mutex_trylock.c (__pthread_mutex_trylock): Typo fix.
+
+2003-06-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h: New file.
+       * sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h: New file.
+
+       * pthreadP.h: Declare __find_thread_by_id.
+       * allocatestack.c [HP_TIMING_AVAIL]: Define __find_thread_by_id.
+       * pthread_clock_gettime.c: Allow using other thread's clock.
+       * pthread_clock_settime.c: Likewise.
+       * sysdeps/pthread/pthread_getcpuclockid.c: Likewise.
+       * Makefile: Add rules to build and run tst-clock2.
+       * tst-clock2.c: New file.
+
+2003-06-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Rewrite
+       to use exception-based cleanup handler.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+
+       * tst-cond8.c (ch): Announce that we are done.
+
+       * pthreadP.h (__pthread_mutex_cond_lock): Mark with internal_function.
+
+       * tst-cancel17.c (tf): Retry aio_suspend in case of EINTR.
+       Also test aio_suspend with timeout value.
+
+2003-06-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h: Mark __pthread_mutex_unlock_usercnt also hidden.
+       * pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Add
+       attribute_hidden.
+
+       * pthreadP.h (__pthread_mutex_init_internal): Mark hidden.
+       (__pthread_mutex_lock_internal): Likewise.
+       (__pthread_mutex_unlock_internal): Likewise.
+       (__pthread_mutex_unlock_usercnt): Declare.
+       * pthread_mutex_destroy.c: Always fail if used in any way.
+       * pthread_mutex_init.c: Update comment.
+       * pthread_mutex_lock.c: If NO_INCR is not defined adjust __nusers.
+       * pthread_mutex_timedlock.c: Adjust __nusers.
+       * pthread_mutex_trylock.c: Adjust __nusers.
+       * pthread_mutex_unlock.c: Old code is in __pthread_mutex_unlock_usercnt
+       and public interfaces are wrapper with pass additional parameter.
+       __pthread_mutex_unlock_usercnt does not adjust __nusers if second
+       parameter zero.
+       * tst-mutex8.c: New file.
+       * Makefile (tests): Add tst-mutex8.
+       * sysdeps/pthread/pthread_cond_timedwait.c: Call
+       __pthread_mutex_unlock_usercnt.
+       * sysdeps/pthread/pthread_cond_wait.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Define NO_INCR.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_mutex_t):
+       Add __nusers.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+
+       * pthread_mutex_lock.c: Don't store THREAD_ID in __owner, use TID.
+       * pthread_mutex_timedlock.c: Likewise.
+       * pthread_mutex_trylock.c: Adjust __nusers.
+       * pthread_mutex_unlock.c: Compare with TID not THREAD_ID.
+       * tst-mutex9.c: New file.
+       * Makefile (tests): Add tst-mutex9.
+       * sysdeps/i386/tls.h: Remove THREAD_ID definition.
+       * sysdeps/ia64/tls.h: Likewise.
+       * sysdeps/powerpc/tls.h: Likewise.
+       * sysdeps/s390/tls.h: Likewise.
+       * sysdeps/sh/tls.h: Likewise.
+       * sysdeps/x86_64/tls.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_mutex_t):
+       Change type of __owner.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+
+2003-06-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/sem_post.c: Move to...
+       * sysdeps/unix/sysv/linux/sem_post.c: ...here.
+
+       * sysdeps/unix/sysv/linux/sem_post.c: Move to...
+       * sysdeps/unix/sysv/linux/powerpc/sem_post.c: ... here.  Pass nr + 1
+       instead of nr to lll_futex_wake.  Only set errno and return -1
+       if err < 0.
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (lll_futex_wait,
+       lll_futex_timed_wait, lll_futex_wake, lll_futex_requeue): On success
+       return actual return value from the syscall, not 0.
+
+2003-06-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel4.c (tf_msgsnd): Don't always use 100 as the type,
+       find a random value.
+       (tf_msgrcv): Likewise.  Also don't report msgrcv returns if
+       errno==EIDRM.
+
+       * sysdeps/unix/sysv/linux/timer_settime.c: Add prototype for
+       compat_timer_settime.
+       * sysdeps/unix/sysv/linux/timer_gettime.c: Add prototype for
+       compat_timer_gettime.
+       * sysdeps/unix/sysv/linux/timer_getoverr.c: Add prototype for
+       compat_timer_getoverrun.
+       * sysdeps/unix/sysv/linux/timer_delete.c: Add prototype for
+       compat_timer_delete.
+
+       * pthread_mutex_destroy.c (__pthread_mutex_destroy): For
+       error-checking mutex detect busy mutexes.
+
+2003-06-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_mutex_lock):
+       Add ax to clobber list.
+       (lll_mutex_cond_lock): Likewise.
+       (lll_mutex_unlock): Likewise.
+       (lll_lock): Likewise.
+       (lll_unlock): Likewise.
+
+       * Makefile: Add rules to build and run tst-cancel18 and tst-cancelx18.
+       * tst-cancel18.c: New file.
+       * tst-cancelx18.c: New file.
+
+       * tst-cancel4.c: Test connect, creat, msgrcv, msgsnd, sendmsg, sendto,
+       and tcdrain.
+
+       * Makefile: Add rules to build and run tst-cancel17 and tst-cancel17x.
+       * tst-cancel17.c: New file.
+       * tst-cancelx17.c: New file.
+
+       * sysdeps/unix/sysv/linux/sigtimedwait.c: New file.
+       * sysdeps/unix/sysv/linux/sigwait.c: New file.
+       * sysdeps/unix/sysv/linux/sigwaitinfo.c: New file.
+
+       * tst-cancel4.c: Test open, close, pread, pwrite, fsync, and msync.
+
+2003-06-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/createthread.c (create_thread): Set
+       header.multiple_threads unconditionally.
+       * allocatestack.c (allocate_stack): Likewise.
+       * descr.h (struct pthread): Add header.multiple_threads
+       unconditionally.
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (CENABLE, CDISABLE):
+       Define for librt.  #error if neither libpthread, libc nor librt.
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (CENABLE, CDISABLE):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (CENABLE,
+       CDISABLE): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (CENABLE,
+       CDISABLE): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h (CENABLE,
+       CDISABLE): Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (CENABLE,
+       CDISABLE): Likewise.  Access header.multiple_threads outside of
+       libc and libpthread.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (CENABLE, CDISABLE):
+       Likewise.
+       * sysdeps/x86_64/tls.h (tcbhead_t): Add multiple_threads.
+       * sysdeps/x86_64/tcb-offsets.sym (MULTIPLE_THREADS_OFFSET): Define.
+
+2003-06-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel4.c: Add tests for the socket and signal functions, pause.
+       Also test early cancellation before the thread reaches the cancellation
+       point.
+
+       * Makefile: Compile forward.c with exceptions.
+
+       * sysdeps/unix/sysv/linux/sleep.c: New file.
+
+2003-06-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile: Add CFLAGS definition to compile function wrappers
+       duplicated from libc with exceptions.
+       * tst-cancel4.c: Also check cancellation handlers.
+
+       * Makefile: Add rules to build and run tst-cancel16 and
+       tst-cancelx16.  Add missing CFLAGS definitions.
+       * tst-cancel16.c: New file.
+       * tst-cancelx16.c: New file.
+
+2003-06-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h
+       (DL_SYSINFO_IMPLEMENTATION): Use CFI opcodes.
+       * sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h
+       (DL_SYSINFO_IMPLEMENTATION): Likewise.
+
+       * pthreadP.h (LIBC_CANCEL_ASYNC): Also define for librt.
+       (LIBC_CANCEL_RESET): Likewise.
+       Declare __librt_enable_asynccancel and __librt_disable_asynccancel.
+       * sysdeps/pthread/Makefile (librt-sysdep_routines): Add
+       librt-cancellation.
+       (CFLAGS-libcrt-cancellation.c): Define.
+       * sysdeps/pthread/librt-cancellation.c: New file.
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Define all the nice
+       macros also when compiling librt.
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise.
+
+       * sysdeps/unix/sysv/linux/timer_create.c: Add prototype for
+       compat_timer_create.
+
+2003-06-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/posix-timer.h (timespec_compare): Always inline.
+
+       * sysdeps/unix/sysv/linux/fork.h: Add libc_hidden_proto for
+       __register_atfork.
+       * sysdeps/unix/sysv/linux/register-atfork.c (__register_atfork):
+       Add libc_hidden_def.
+
+2003-06-13  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/x86_64/td_ta_map_lwp2thr.c (td_ta_map_lwp2thr): Pass FS
+       constant from <sys/reg.h> to ps_get_thread_area, not register contents.
+
+2003-06-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (queue_stack): Always inline.
+       * ptreadhP.h (__do_cancel): Likewise.
+
+2003-06-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c (sem_timedwait): Fix
+       a typo.
+
+2003-06-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+       (__pthread_cond_signal): Remove incorrect second addition for
+       cond_lock!=0.
+
+2003-06-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+       (__pthread_cond_signal): Use correct futex pointer in
+       __lll_mutex_lock_wait call.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+       (__pthread_cond_signal): Some more tweaks to handle cond_lock!=0.
+
+2003-06-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/sem_wait.c (__new_sem_wait): Make
+       cancelable.
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c (sem_timedwait):
+       Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Remove
+       hand-written CFI generation code.  Since ENTRY/END also initiated
+       CFI frames this caused two CFI sets to be generated.
+
+2003-06-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * cleanup_routine.c: New file.
+       * Versions (libpthread) [GLIBC_2.3.3]: Add __pthread_cleanup_routine.
+       * sysdeps/pthread/pthread.h: Add support for fully exception-based
+       cleanup handling.
+       * Makefile (libpthread-routines): Add cleanup_routine.
+       Add more CFLAGS variables to compile with exceptions.  Add comments
+       why which file needs unwind tables.
+       (tests) [have-forced-unwind==yes]: Add tst-cancelx* and tst-cleanupx*
+       tests.
+       * tst-cancelx1.c: New file.
+       * tst-cancelx2.c: New file.
+       * tst-cancelx3.c: New file.
+       * tst-cancelx4.c: New file.
+       * tst-cancelx5.c: New file.
+       * tst-cancelx6.c: New file.
+       * tst-cancelx7.c: New file.
+       * tst-cancelx8.c: New file.
+       * tst-cancelx9.c: New file.
+       * tst-cancelx10.c: New file.
+       * tst-cancelx11.c: New file.
+       * tst-cancelx12.c: New file.
+       * tst-cancelx13.c: New file.
+       * tst-cancelx14.c: New file.
+       * tst-cancelx15.c: New file.
+       * tst-cleanupx0.c: New file.
+       * tst-cleanupx0.expect: New file.
+       * tst-cleanupx1.c: New file.
+       * tst-cleanupx2.c: New file.
+       * tst-cleanupx3.c: New file.
+
+       * tst-cleanup0.c: Make standard compliant.
+       * tst-cleanup1.c: Likewise.
+
+       * sysdeps/unix/sysv/linux/sem_timedwait.c: Add cancellation support.
+       * sysdeps/unix/sysv/linux/sem_wait.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+       * sysdeps/i386/tcb-offsets.sym: Add RESULT, CANCELHANDLING, and
+       CLEANUP_JMP_BUF.
+       * sysdeps/x86_64/tcb-offsets.sym: Likewise.
+       * tst-cancel12.c: New file.
+       * tst-cancel13.c: New file.
+       * tst-cancel14.c: New file.
+       * tst-cancel15.c: New file.
+       * Makefile (tests): Add tst-cancel12, tst-cancel13, tst-cancel14,
+       and tst-cancel15.
+
+       * tst-cancel1.c: Add some comments.
+
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Compute relative
+       timeout correctly.
+
+2003-06-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (CFLAGS-pthread_cancel.c): Define.
+
+2003-06-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_rwlock_t):
+       Change type of __writer element to int.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/i386/tcb-offsets.sym: Replace SELF entry with TID entry.
+       * sysdeps/x86_64/tcb-offsets.sym: Likewise.
+       * pthread_rwlock_trywrlock.c: Store TID not self pointer in __writer.
+       Compare with TID to determine deadlocks.
+       * sysdeps/pthread/pthread_rwlock_rdlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_timedrdlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_timedwrlock.: Likewise.
+       * sysdeps/pthread/pthread_rwlock_wrlock.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+       * Makefile (tests): Add tst-rwlock12.
+       * tst-rwlock12.c: New file.
+
+2003-06-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/lowlevellock.c (__lll_lock_wait,
+       __lll_timedlock_wait, lll_unlock_wake_cb, __lll_timedwait_tid):
+       Remove bogus hidden_proto.
+       * sysdeps/unix/sysv/linux/s390/libc-lowlevellock.c (___lll_lock):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.c (___lll_lock,
+       lll_unlock_wake_cb, ___lll_timedwait_tid): Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevelmutex.c (___lll_mutex_lock,
+       ___lll_mutex_timedlock): Likewise.
+
+2003-06-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+       (__pthread_cond_signal): Add some code to eventually handle
+       cond_lock!=0.
+
+2003-06-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-exec4.
+       (tst-exec4-ARGS): Define.
+       * tst-exec4.c: New file.
+
+2003-05-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/lowlevellock.c (__lll_timedlock_wait):
+       Also fail if tv_nsec < 0.
+       (__lll_timedwait_tid): Likewise.
+       * sysdeps/unix/sysv/linux/sem_timedwait.c (sem_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_timedwait_tid):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.c (___lll_timedwait_tid):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevelmutex.c (__lll_mutex_timedlock):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c (sem_timedwait):
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_timedwait_tid):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h (lll_timedwait_tid):
+       Likewise.
+
+       * Makefile (tests): Add tst-sem8 and tst-sem9.
+       * tst-sem8.c: New file.
+       * tst-sem9.c: New file.
+       * sem_open.c: Fix creation of in_use record if the file exists but
+       no internal record.
+
+       * posix-timer.h: Remove old, unused timer_id2ptr and timer_ptr2id
+       definitions.
+
+       * sysdeps/pthread/timer_create.c (timer_create): In case
+       evp==NULL, assign timer ID to sival_ptr.
+
+       * descr.h (struct pthread_unwind_buf): Change type of prev element to
+       struct pthread_unwind_buf *.
+       (struct pthread): Likewise for cleanup_jmp_buf element.
+
+       * cleanup.c (__pthread_register_cancel): Add cast to avoid warning.
+       * cleanup_defer.c (__pthread_register_cancel_defer): Likewise.
+       * unwind.c (__pthread_unwind_next): Likewise.
+
+2003-05-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+       (lll_futex_timed_wait): Use int for futex value parameter.
+       (lll_futex_wake): Likewise.
+       (lll_futex_requeue): Likewise.
+
+       * sysdeps/unix/sysv/linux/lowlevellock.c (__lll_lock_wait):
+       Replace one memory operation with one register operation.
+
+       * tst-join4.c (do_test): Fix error message.
+
+       * tst-rwlock6.c (do_test): Use correct format specifier.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S
+       (__lll_mutex_lock_wait): Replace one memory operation with one
+       register operation.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S
+       (__lll_mutex_lock_wait): Likewise.
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+       (__lll_mutex_cond_lock): Add one to value parameter of
+       __lll_lock_wait to reflect reality in the futex syscall.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+       (lll_mutex_cond_lock): Likewise.
+
+2003-05-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (__lll_mutex_cond_lock):
+       New function.
+       (lll_mutex_cond_lock): Define.
+
+2003-05-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-signal6.
+       * tst-signal6.c: New file.
+
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h
+       (__lll_mutex_unlock_force): New function
+       (lll_mutex_unlock_force): Use __lll_mutex_unlock_force.
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+       (__lll_mutex_unlock_force): New function.
+       (lll_mutex_unlock_force): Use __lll_mutex_unlock_force.
+
+       * tst-rwlock7.c (do_test): Use correct format specifier.
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (lll_futex_requeue):
+       Find break parameter in correct asm argument.
+
+2003-05-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (lll_futex_clobbers):
+       Remove out4.
+       (lll_futex_requeue): Fix __o3 constraint, return negative errno if
+       error occured.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h (pthread_cond_t):
+       Add __mutex.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_REQUEUE,
+       lll_futex_requeue, lll_mutex_unlock_force): Define.
+
+2003-05-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
+       (pthread_cond_t): Add __mutex.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (FUTEX_REQUEUE,
+       lll_futex_requeue, lll_mutex_unlock_force): Define.
+
+2003-05-28  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/tcb-offsets.sym: Define MUTEX_FUTEX.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_cond_t):
+       Add __mutex field.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h (SYSCALL_WITH_INST_PAD):
+       Define.
+       (lll_futex_wait, lll_futex_wake): Define.
+       * sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: Try using
+       FUTEX_REQUEUE instead of FUTEX_WAIT.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Remember
+       mutex which was used in condvar structure.  Call
+       __pthread_mutex_cond_lock instead of __pthread_mutex_lock_internal.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Don't
+       include tcb-offsets.h.  Read wakeup value in locked region.
+       Use the value of gbr register as THREAD_ID.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/sh/sem_trywait.S: Remove futex related
+       macros.
+
+2003-05-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_broadcast.c
+       (__pthread_cond_broadcast): Fix typo: MAX_INT -> INT_MAX.
+
+2003-05-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: Fix
+       typo in register name.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Use parameters
+       correctly.  Actually use requeue.  Little optimization.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Store
+       mutex address early.  Handle cancellation state as 32-bit value.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       Remove unnecessary label.
+
+2003-05-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_broadcast.c: Try using FUTEX_REQUEUE
+       instead of FUTEX_WAIT.
+       * sysdeps/pthread/pthread_cond_signal.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Likewise.
+       * sysdeps/pthread/pthread_cond_timedwait.c: Remember mutex which was
+       used in condvar structure.  Call __pthread_mutex_cond_lock instead
+       of __pthread_mutex_lock_internal.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/pthread/pthread_cond_wait.c: Likewise.
+       (__condvar_cleanup): Always call __pthread_mutex_cond_lock.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/Makefile (libpthread-sysdep_routines):
+       Add pthread_mutex_cond_lock.
+       * sysdeps/unix/sysv/linux/lowlevelcond.sym: Add dep_mutex.
+       * sysdeps/unix/sysv/linux/pthread_cond_mutex_lock.c: New file.
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Define
+       lll_mutex_cond_lock.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_cond_t):
+       Add __mutex field.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+
+       * sysdeps/i386/tcb-offsets.sym: Define MUTEX_FUTEX.
+       * sysdeps/x86_64/tcb-offsets.sym: Likewise.
+
+       * pthreadP.h: Declare __pthread_mutex_cond_lock.
+       * pthread_mutex_lock.c: Define LLL_MUTEX_LOCK if not already defined.
+       Use it instead of lll_mutex_lock.  If __pthread_mutex_lock is a
+       macro don't define aliases.
+
+       * cancellation.c: Remove __pthread_enable_asynccancel_2.
+       * pthreadP.h: Remove declaration of __pthread_enable_asynccancel_2.
+       * sysdeps/pthread/pthread_cond_timedwait.c: Use
+       __pthread_enable_asynccancel instead of __pthread_enable_asynccancel_2.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/pthread/pthread_cond_wait.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+
+2003-05-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sem_open.c: Fix one endless loop.  Implement correct semantics
+       wrt opening the same semaphore more then once.
+       * sem_close.c: Adjust for sem_open change.
+       * semaphoreP.h: Include <semaphore.h>.  Define struct inuse_sem.
+       Declare __sem_mappings, __sem_mappings_lock, __sem_search.
+       * Makefile (tests): Add tst-sem7.
+       * tst-sem7.c: New file.
+
+2003-05-16  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/register-atfork.c (libc_freeres_fn): Fix
+       uninitialized variable braino.
+
+2003-05-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/timer_gettime.c (timer_gettime): Correct
+       test for syscall availability.
+
+       * sysdeps/unix/sysv/linux/timer_settime.c (timer_settime): Set
+       __no_posix_timers to -1 if the syscalls don't exist.
+
+       * pthread_join.c (pthread_join): Set tid field of the joined
+       thread to -1.  This isn't necessary but helps to recognize some
+       error conditions with almost no cost.
+
+       * allocatestack.c (FREE_P): Also negative values indicate an
+       unused stack.
+
+       * unwind.c: Include <unistd.h>.
+
+2003-05-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile ($(objpfx)$(multidir)): Add rule to create the directory.
+
+2003-05-14  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (crti-objs, crtn-objs): New variables.
+       (omit-deps, extra-objs): Add crtn.
+       ($(objpfx)libpthread.so): Depend on both crti and crtn
+       and links to them in multidir.
+       ($(objpfx)crtn.S, $(objpfx)crtn.o): New rules.
+
+2003-05-12  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+       (lll_mutex_unlock): Use atomic_exchange_rel.
+
+2003-05-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * cond-perf.c (cons): Add missing locking around setting of alldone.
+
+2003-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S: Remove futex
+       related macros.
+       * sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: Likewise.
+
+2003-05-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-sem6.c: New file.
+       * Makefile (tests): Add tst-sem6.
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (___lll_mutex_unlock):
+       Use atomic_exchange_rel instead of atomic_exchange.
+       * sysdeps/unix/sysv/linux/lowlevellock.c (lll_unlock_wake_cb):
+       Likewise.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Improve quality of
+       code for lll_futex_wait and lll_futex_wake in static apps.  Use
+       vsyscall is possible.
+
+       * sysdeps/unix/sysv/linux/pthread_getaffinity.c: New file.
+       * sysdeps/unix/sysv/linux/pthread_setaffinity.c: New file.
+       * sysdeps/pthread/pthread.h: Declare pthread_getaffinity_np and
+       pthread_setaffinity_np.
+       * Versions [libpthread] (GLIBC_2.3.3): Add pthread_getaffinity_np
+       and pthread_setaffinity_np.
+       * Makefile (libpthread-routines): Add pthread_getaffinity and
+       pthread_setaffinity.
+
+       * allocatestack.c (allocate_stack): If ARCH_RETRY_MMAP is defined,
+       use it in case mmap to allocate the stack fails.
+       * sysdeps/unix/sysv/linux/x86_64/Makefile: Don't define
+       ARCH_MAP_FLAGS here.
+       * sysdeps/x86_64/pthreaddef.h: Define ARCH_MAP_FLAGS and
+       ARCH_RETRY_MMAP.
+
+2003-05-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/fork.c: Complete rewrite of the atfork
+       handler implementation.  It is now lockless in fork().
+       * sysdeps/unix/sysv/linux/register-atfork.c: Likewise.
+       * sysdeps/unix/sysv/linux/unregister-atfork.c: Likewise.
+       * sysdeps/unix/sysv/linux/fork.h: Don't include <link.h>.  Don't
+       declare the __fork_*_lists.
+       (struct fork_handler): Include pointers to all three functions.
+       Add next, refcntr and need_signal elements.
+       (__fork_handlers): New declaration.
+       (__register_atfork_malloc): Remove declaration.
+       (HAVE_register_atfork_malloc): Remove definition.
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c: Remove
+       __pthread_child_handler variable.
+       (__libc_pthread_init): Use __register_atfork instead of explicitly
+       adding to the list.
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Define lll_futex_wait
+       and lll_futex_wake.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+
+       * unwind.c (unwind_cleanup): Print error message and then abort.  This
+       function must never be reached.
+
+       * cond-perf.c: New file.
+
+2003-05-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/tls.h (TLS_INIT_TP): Include \n in error message.
+
+2003-05-04  Roland McGrath  <roland@redhat.com>
+
+       * Makefile ($(objpfx)../libc.so): New target.
+
+2003-05-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
+       (pthread_condattr_t): Size is only an int, don't use long for
+       alignment.
+       (pthread_mutexattr_t): Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+
+2003-05-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/tls.h: Define THREAD_ID.
+       * sysdeps/ia64/tls.h: Likewise.
+       * sysdeps/powerpc/tls.h: Likewise.
+       * sysdeps/s390/tls.h: Likewise.
+       * sysdeps/sh/tls.h: Likewise.
+       * sysdeps/x86_64/tls.h: Likewise.
+       * pthread_mutex_lock.c: Use THREAD_ID instead of THREAD_SELF to
+       record ownership.
+       * pthread_mutex_timedlock.c: Likewise.
+       * pthread_mutex_trylock.c: Likewise.
+       * pthread_mutex_unlock.c: Likewise.
+       * pthread_rwlock_trywrlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlocklock_rdlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_timedrdlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_timedwrlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_wrlock.c: Likewise.
+
+       * sysdeps/pthread/createthread.c (create_thread): Use CLONE_SYSVSEM
+       flag.
+
+2003-04-29  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+       (__SIZEOF_PTHREAD_COND_T): Define to 48.
+       (pthread_rwlock_t): Add 16 bytes of pad instead of 8 before __flags.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h (pthread_cond_t):
+       Make __align long long instead of long.
+       (pthread_rwlock_t): Formatting.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
+       (pthread_rwlock_t): Formatting.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
+       (pthread_cond_t): Make __align long long instead of long.
+       (pthread_rwlock_t): Move __flags field to the same position as in
+       linuxthreads.
+
+2003-04-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-rwlock6.c (do_test): Use correct printf format specifiers.
+       * tst-rwlock7.c (do_test): Likewise.
+
+2003-04-26  Roland McGrath  <roland@redhat.com>
+
+       * Makefile ($(test-modules)): Depend on $(common-objpfx)shlib.lds.
+
+2003-04-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * allocatestack.c (TLS_TPADJ): Add TLS_PRE_TCB_SIZE instead of
+       sizeof (struct pthread).
+       (allocate_stack): Subtract TLS_PRE_TCB_SIZE bytes instead of
+       1 struct pthread.
+       * sysdeps/powerpc/tls.h (TLS_INIT_TCB_SIZE, TLS_TCB_SIZE): Define
+       to 0.
+       (TLS_INIT_TCB_ALIGN, TLS_TCB_ALIGN): Define to alignment of
+       struct pthread.
+       (TLS_PRE_TCB_SIZE): Increase to cover tcbhead_t preceeded by pad
+       to 32-bit bytes.
+       (INSTALL_DTV, GET_DTV, THREAD_DTV): tcbhead_t is immediately before
+       tcbp.
+       (TLS_INIT_TP, THREAD_SELF, INIT_THREAD_SELF): Don't add TLS_TCB_SIZE
+       unneccessarily.
+       (NO_TLS_OFFSET): Define.
+       * sysdeps/unix/sysv/linux/powerpc/createthread.c (TLS_VALUE): Don't
+       add TLS_TCB_SIZE unnecessarily.
+
+2003-04-22  Roland McGrath  <roland@redhat.com>
+
+       * Makeconfig (shared-thread-library): Reverse link order to work
+       around linker bug.
+
+2003-04-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * semaphore.h: Fix typo in comment.
+
+2003-04-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/sigfillset.c: New file.
+
+       * init.c (__pthread_initialize_minimal): Don't block SIGTIMER.
+       * pthreadP.h: Make SIGTIMER and SIGCANCEL the same.
+       * sysdeps/pthread/pthread_sigmask.c: Remove handling of SIGTIMER.
+       * sysdeps/pthread/sigaction.c: Likewise.
+       * sysdeps/pthread/sigprocmask.c: New file.
+       * sysdeps/unix/sysv/linux/allocrtsig.c (current_rtmin): Define as
+       __SIGRTMIN+1.
+       * sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread):
+       Block SIGTIMER.  Also handle SI_TKILL events and terminate thread
+       in this case.
+
+2003-04-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h
+       (DL_SYSINFO_IMPLEMENTATION): Add .eh_frame information.
+
+       * sysdeps/unix/sysv/linux/unregister-atfork.c
+       (__unregister_atfork): Don't free memory not allocated dynamically.
+
+       * semaphore.h: Remove __THROW marker from cancellation points.
+       * nptl/sysdeps/pthread/pthread.h: Likewise.
+
+2003-04-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h: Don't mark pthread_testcancel,
+       pthread_cancel, pthread_setcancelstate, and pthread_setcanceltype with
+       __THROW.
+
+2003-04-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-cancel4.c (do_test): Use %zd instead of %d when printing cnt.
+
+2003-04-15  Roland McGrath  <roland@redhat.com>
+
+       * forward.c (__pthread_unwind): Tweak to avoid warning.
+
+2003-04-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h: Move THREAD_ATOMIC_* replacements to the top.
+
+2003-04-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Don't
+       overflow CFA advance instructions.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+2003-04-14  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/i386/tls.h: Rename LOCK to LOCK_PREFIX.
+       * sysdeps/i386/pthread_spin_lock.c: Likewise.
+       * sysdeps/x86_64/tls.h: Likewise.  Define LOCK_PREFIX if not already
+       defined.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Use
+       DW_CFA_advance_loc2 for .Laddl-.Lsubl.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Use
+       DW_CFA_advance_loc for .Laddl-.Lsubl.
+
+2003-04-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Don't use
+       position-independent unwind data for static libraries.
+       Add missing unwind info.  Add comments.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Add unwind info.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+
+2003-04-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile: Make sure all cancellation points are compiled with
+       exception and asynchronous unwind tables.
+
+       * sysdeps/x86_64/tls.h (THREAD_SETMEM): Word around compiler bug
+       which mishandles loading of global object addresses in PIC.
+       (THREAD_SETMEM_NC): Likewise.
+
+2003-04-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread.h: Define new data structure for cleanup buffer.  Declare
+       new cleanup handler interfaces.
+       * descr.h: Include <unwind.h> if necessary.  Define pthread_unwind_buf.
+       (struct pthread): Add cleanup_jmp_buf pointer.  Define
+       HAVE_CLEANUP_JMP_BUF and not HAVE_CANCELBUF.
+       * pthreadP.h: Declare __pthread_unwind.  Define __do_cancel to use
+       it.  Declare old cleanup handler installation functions.
+       * cleanup.c: Rewrite.  Install handler for unwind-based cleanup
+       handling.
+       * cleanup_defer.c: Likewise.
+       * cleanup_compat.c: New file.  Old cleanup code.
+       * cleanup_def_compat.c: New file.  Old cleanup code.
+       * pthread_create.c (start_thread): Initialize cleanup_jmp_buf element
+       if own thread descriptor.
+       * unwind.c: New file.
+       * forward.c: Add __pthread_unwind.
+       * init.c (pthread_functions): Add __pthread_unwind.
+       * sysdeps/pthread/pthread-functions.s (struct pthread_functions):
+       Add ptr___pthread_unwind.
+       * Versions [GLIBC_2.3.3] (libpthread): Export new cleanup handling
+       and unwind function.
+       * Makefile (libpthread-routines): Add cleanup_compat,
+       cleanup_def_compat, and unwind.  Define CFLAGS to enable unwind
+       table generation if necessary.
+       * version.c: Record whether unwind support is compiled in.
+       * sysdeps/pthread/configure.in: Add checks for unwind unterfaces.
+       * sysdeps/pthread/bits/libc-lock.h: Add prototypes of the old cleanup
+       handler interfaces.
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Add quite a bit of
+       complication to generate unwind information for syscall wrappers.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Define
+       __cleanup_fct_attribute.
+
+       * Makefile: Add rules to build and run tst-cleanup0.
+       * tst-cleanup0.c: New file.
+       * tst-cleanup0.expect: New file.
+
+       * pthread_create.c (deallocate_tsd): Don't take parameter.  Adjust
+       caller.  Optimize to avoid often unecessary local variable.
+
+2003-04-11  Roland McGrath  <roland@redhat.com>
+
+       * Makefile ($(objpfx)multidir.mk): New target, generated makefile that
+       sets variable `multidir'; include that.
+       (generated): Add it.
+       ($(objpfx)$(multidir)/crti.o): New target.
+       [$(multidir) != .] (generated-dirs, extra-objs, omit-deps): Add it.
+
+2003-04-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-attr2.c (do_test): Add cast to avoid warning.
+       * tst-mutex4.c (do_test): Likewise.
+
+2003-04-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/fork.c (__libc_fork): Reset CPU clocks
+       in child.
+
+2003-04-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-detach1.
+       * tst-detach1.c: New file.
+
+2003-04-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h: Remove duplicate
+       pthread_cleanup_{push,pop} definitions.
+
+       * tst-barrier2.c: Eliminate warnings.
+       * tst-cancel4.c: Likewise.
+       * tst-cond4.c: Likewise.
+       * tst-cond6.c: Likewise.
+       * tst-detach1.c: Likewise.
+       * tst-rwlock4.c: Likewise.
+       * tst-rwlock6.c: Likewise.
+       * tst-rwlock7.c: Likewise.
+       * tst-sem3.c: Likewise.
+       * tst-spin2.c: Likewise.
+       * tst-umask1.c: Likewise.
+
+2003-04-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_detach.c (pthread_detach): Fix test for invalid TID.
+
+2003-04-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h (struct pthread): Move cancelhandling member to the front.
+
+2003-04-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/register-atfork.c: Define malloc_prepare,
+       malloc_parent, and malloc_child statically.
+       (__register_atfork_malloc): New function.
+       (free_mem): Don't free any of the malloc_* variables on the list.
+       * sysdeps/unix/sysv/linux/fork.h: Declare __register_atfork_malloc.
+       Define HAVE_register_atfork_malloc.
+
+2003-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/createthread.c (create_thread): Add some more
+       comments explaining when to set multiple_threads and when not.
+
+       * pthreadP.h: Define THREAD_ATOMIC_CMPXCHG_VAL and
+       THREAD_ATOMIC_BIT_SET if not already defined.
+       * sysdeps/i386/tls.h: Define THREAD_ATOMIC_CMPXCHG_VAL and
+       THREAD_ATOMIC_BIT_SET:
+       * sysdeps/x86_64/tls.h: Likewise.
+       * cleanup_defer.c (_pthread_cleanup_push_defer): Rewrite to use
+       THREAD_ATOMIC_CMPXCHG_VAL.
+       (_pthread_cleanup_pop_restore): Likewise.
+       * cancellation.c (__pthread_enable_asynccancel): Likewise.
+       (__pthread_enable_asynccancel_2): Likewise.
+       (__pthread_disable_asynccancel): Likewise.
+       * libc-cancellation.c (__libc_enable_asynccancel): Likewise.
+       (__libc_disable_asynccancel): Likewise.
+       * init.c (sigcancel_handler): Likewise.
+       * pthread_setcancelstate.c (__pthread_setcancelstate): Likewise.
+       * pthread_setcanceltype.c (__pthread_setcanceltype): Likewise.
+
+2003-04-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (sigcancel_handler): Don't set EXITING_BIT here.
+       * libc-cancellation.c (__libc_enable_asynccancel): Likewise.
+       * pthreadP.h (__do_cancel): Set EXITING_BIT here.
+       * Makefile (tests): Add tst-cancel11.
+       * tst-cancel11.c: New file.
+
+2003-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_create.c (deallocate_tsd): Clear/free memory after the last
+       round, not the first.  Use specific_used flag instead of local
+       found_nonzero variable.  Use THREAD_[SG]ETMEM where possible.
+       (__free_tcb): Don't call deallocate_tsd here.
+       (start_thread): Call deallocate_tsd here.
+       * pthread_setspecific.c: Set specific_used flag really only when
+       needed.
+       * Makefile (tests): Add tst-tsd3.c and tst-tsd4.
+       * tst-tsd3.c: New file.
+       * tst-tsd4.c: New file.
+
+2003-03-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_mutex_lock):
+       Use atomic_exchange_and_add instead of __lll_add.
+       (__lll_mutex_timedlock): Likewise.
+       Patch by Ian Wienand.
+
+2003-03-24  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+       (SINGLE_THREAD_P): Fix typo.
+       * tst-cancel-wrappers.sh: Handle '.'ed symbols.
+
+2003-03-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-align.
+       * tst-align.c: New file.
+       * sysdeps/i386/Makefile: Define CFLAGS-tst-align.
+
+       * sysdeps/i386/tls.h (CALL_THREAD_FCT): Align stack of called
+       function correctly.
+
+       * tst-tsd2.c: Add casts to avoid warnings.
+
+2003-03-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h (struct pthread): Move most often used elements to the front.
+
+2003-03-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (libpthread-routines): Add pthread_atfork.
+       (libpthread-static-only-routines): Add pthread_atfork.
+
+2003-03-28  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/tls.h: Include nptl/descr.h after the definition
+       of TLS_DTV_AT_TP.
+       (INSTALL_DTV): Add parens.
+       (THREAD_GETMEM, THREAD_GETMEM_NC, THREAD_SETMEM, THREAD_SETMEM_NC):
+       Use passed descr instead of THREAD_SELF.
+       * sysdeps/unix/sysv/linux/sh/lowlevelmutex.S
+       (__lll_mutex_timedlock_wait): Correct expected value after
+       spurious wakeup.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S:
+       Release lock before waking up the waiters.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Correct exit
+       criteria.  Reorderstruct passed to cleanup handler.  Fix
+       handling of cancellation and failung pthread_mutex_unlock call.
+       Use __pthread_enable_asynccancel_2 instead of
+       __pthread_enable_asynccancel.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+       Return result of lock re-get if it fails.
+       * sysdeps/unix/sysv/linux/sh/pthread_once.S: Fix wrong argument
+       for __pthread_cleanup_push.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Fix
+       completely broken rwlock implementation.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_post.S: Fix error value.  Use
+       versioned_symbol macro.
+       * sysdeps/unix/sysv/linux/sh/sem_trywait.S: Use versioned_symbol macro.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S: Likewise.
+
+2003-03-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/kernel-posix-timers.h: Don't declare
+       __timer_helper_thread.  Declare __start_helper_thread, __helper_once,
+       and __helper_tid.
+       (struct timer): Remove th and bar field.
+       * sysdeps/unix/sysv/linux/timer_create.c (timer_create): Remove
+       debugging code.  Create only one helper thread.
+       * sysdeps/unix/sysv/linux/timer_delete.c (timer_delete): Don't kill
+       helper thread.
+       * sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread):
+       Renamed.  Define statically.  Use thread info from siginfo.
+       (__helper_once): New variable.
+       (__helper_tid): New variable.
+       (__reset_helper_control): New function.
+       (__start_helper_thread): New function.
+
+       * pthread_create.c (start_thread): Don't use setjmp inside
+       __builtin_expect to work around gcc bug.
+
+       * sysdeps/unix/sysv/linux/timer_delete.c (timer_delete): Even if
+       timer_delete syscall fails, but not with ENOSYS, set
+       __no_posix_timers.
+
+       * sysdeps/unix/sysv/linux/timer_settime.c [!__ASSUME_POSIX_TIMERS]
+       (timer_settime): Fix typo.
+       * sysdeps/unix/sysv/linux/timer_getoverr.c
+       [!__ASSUME_POSIX_TIMERS] (timer_getoverrun): Likewise.
+
+2003-03-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Fix
+       offset of cleanupbuf.__prev.
+
+2003-03-26  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/timer_getoverr.c: Fix typo in name
+       of included file.
+
+2003-03-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/timer_create.c (timer_create): If EVP ==
+       NULL provide default definition to syscall.
+
+2003-03-25  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/pthread/posix-timer.h (TIMER_MAX): Define if not defined.
+       (timer_id2ptr): Fix typo.
+
+2003-03-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h: Define SIGCANCEL and SIGTIMER.
+       * sysdeps/i386/pthreaddef.h: Remove SIGCANCEL definition.
+       * sysdeps/ia64/pthreaddef.h: Likewise.
+       * sysdeps/powerpc/pthreaddef.h: Likewise.
+       * sysdeps/s390/pthreaddef.h: Likewise.
+       * sysdeps/sh/pthreaddef.h: Likewise.
+       * sysdeps/x86_64/pthreaddef.h: Likewise.
+       * init.c (__pthread_initialize_minimal): Block SIGTIMER.
+       * sysdeps/pthread/sigaction.c: Also prevent SIGTIMER handler from
+       being changed.
+       * sysdeps/pthread/pthread_sigmask.c (pthread_sigmask): Make sure
+       SIGTIMER is not unblocked.
+       * sysdeps/unix/sysv/linux/allocrtsig.c (current_rtmin): One more
+       RT signal taken.
+       * sysdeps/unix/sysv/linux/pthread_kill.c: Do not allow SIGTIMER to
+       be send.
+       * sysdeps/pthread/posix-timer.h (timer_id2ptr, timer_ptr2id): Just
+       pass pointer through as ID.
+       * sysdeps/unix/sysv/linux/bits/local_lim.h (TIMER_MAX): Removed.
+       * sysdeps/unix/sysv/linux/kernel-posix-timers.h: New file.
+       * sysdeps/unix/sysv/linux/timer_create.c: New file.
+       * sysdeps/unix/sysv/linux/timer_delete.c: New file.
+       * sysdeps/unix/sysv/linux/timer_getoverr.c: New file.
+       * sysdeps/unix/sysv/linux/timer_gettime.c: New file.
+       * sysdeps/unix/sysv/linux/timer_routines.c: New file.
+       * sysdeps/unix/sysv/linux/timer_settime.c: New file.
+       * sysdeps/unix/sysv/linux/ia64/Versions: New file.
+       * sysdeps/unix/sysv/linux/ia64/timer_create.c: New file.
+       * sysdeps/unix/sysv/linux/ia64/timer_delete.c: New file.
+       * sysdeps/unix/sysv/linux/ia64/timer_getoverr.c: New file.
+       * sysdeps/unix/sysv/linux/ia64/timer_gettime.c: New file.
+       * sysdeps/unix/sysv/linux/ia64/timer_settime.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_create.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/Versions: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/timer_create.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/timer_delete.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/timer_getoverr.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/timer_gettime.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/timer_settime.c: New file.
+       * sysdeps/unix/sysv/linux/x86_64/Versions: New file.
+       * sysdeps/unix/sysv/linux/x86_64/compat-timer.h: New file.
+       * sysdeps/unix/sysv/linux/x86_64/timer_create.c: New file.
+       * sysdeps/unix/sysv/linux/x86_64/timer_delete.c: New file.
+       * sysdeps/unix/sysv/linux/x86_64/timer_getoverr.c: New file.
+       * sysdeps/unix/sysv/linux/x86_64/timer_gettime.c: New file.
+       * sysdeps/unix/sysv/linux/x86_64/timer_settime.c: New file.
+
+       * pthreadP.h: Remove FRAME_LEFT definition.
+       * cleanup.c (_pthread_cleanup_push): Don't check for reference to
+       already left frame.  Programs which have this problem are not POSIX
+       compliant.
+       * cleanup_defer.c (_pthread_cleanup_push_defer): Likewise.
+
+2003-03-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/tst-timer.c: Check return values of the
+       functions we test.
+
+2003-03-23  Roland McGrath  <roland@redhat.com>
+
+       * tst-tls3.c (do_test) [! HAVE___THREAD]: Don't test anything.
+       * tst-tls3mod.c: Likewise.
+       * tst-tls1.c: Likewise.
+       * tst-tls2.c: Likewise.
+
+       * tst-mutex5.c (do_test): Unlock before destroy, otherwise we invoke
+       undefined behavior.
+
+       * tst-join5.c (tf1, tf2): Add a cast.
+
+       * Makeconfig (includes): Append -I$(..)nptl to this variable.
+
+       * tst-barrier2.c (do_test) [! _POSIX_THREAD_PROCESS_SHARED]:
+       Don't test anything.
+       * tst-cond4.c: Likewise.
+       * tst-cond6.c: Likewise.
+       * tst-flock2.c: Likewise.
+       * tst-mutex4.c: Likewise.
+       * tst-rwlock4.c: Likewise.
+       * tst-signal1.c: Likewise.
+       * tst-spin2.c: Likewise.
+       * tst-cond11.c [! _POSIX_CLOCK_SELECTION]: Likewise.
+
+       * tst-mutex4.c: Use test-skeleton.c.
+       * tst-spin2.c: Likewise.
+       * tst-sysconf.c: Likewise.
+       * tst-barrier2.c: Likewise.
+       * tst-cond4.c: Likewise.
+       * tst-cond6.c: Likewise.
+       * tst-rwlock4.c: Likewise.
+       * tst-unload.c: Likewise.
+       * tst-flock2.c (do_test): Use return instead of exit.
+
+2003-03-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/fork.c (__fork): Add libc_hidden_def.
+
+2003-03-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+       (__lll_mutex_trylock): Use atomic_compare_and_exchange_val_acq
+       instead of __lll_compare_and_swap.
+       * sysdeps/unix/sysv/linux/ia64/pthread_once.c (__pthread_once):
+       Likewise.
+       Removed definition if __lll_compare_and_swap.
+
+       * cancellation.c: Adjust for new form of compare&exchange macros.
+       * cleanup_defer.c: Likewise.
+       * init.c: Likewise.
+       * libc-cancellation.c: Likewise.
+       * old_pthread_cond_broadcast.c: Likewise.
+       * old_pthread_cond_signal.c: Likewise.
+       * old_pthread_cond_timedwait.c: Likewise.
+       * old_pthread_cond_wait.c: Likewise.
+       * pthread_cancel.c: Likewise.
+       * pthread_create.c: Likewise.
+       * pthread_detach.c: Likewise.
+       * pthread_join.c: Likewise.
+       * pthread_key_delete.c: Likewise.
+       * pthread_setcancelstate.c: Likewise.
+       * pthread_setcanceltype.c: Likewise.
+       * pthread_timedjoin.c: Likewise.
+       * pthread_tryjoin.c: Likewise.
+       * sysdeps/pthread/createthread.c: Likewise.
+
+2003-03-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Include <atomic.h>.
+       Remove __lll_add, __lll_dec_if_positive, and __lll_test_and_set
+       definitions.  Replace uses with calls to atomic_* functions.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/lowlevellock.c: Replace __lll_add and
+       __lll_test_and_set calls with atomic_exchange_and_add and
+       atomic_exchange calls respectively.
+       * sysdeps/unix/sysv/linux/sem_post.c: Likewise.
+       * sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/sem_trywait.c: Likewise.
+       * sysdeps/unix/sysv/linux/sem_wait.c: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/pthread_once.c: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/sem_port.c: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/pthread_once.c: Likewise.
+
+       * allocatestack.c (allocate_stack): Assume atomic_exchange_and_add
+       returns the old value.
+
+2003-03-20  Martin Schwidefsky  <sky@mschwid3.boeblingen.de.ibm.com>
+
+       * sysdeps/s390/pthread_spin_lock.c (pthread_spin_lock): Use type
+       int for variable OLDVAL and correct inline assembler contraint.
+       * sysdeps/s390/pthread_spin_trylock.c (pthread_spin_trylock): Use
+       type int for variable OLD.
+
+       * sysdeps/s390/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Define it
+       only for s390-32.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
+       (SINGLE_THREAD_P): Use global variable __local_multiple_threads
+       instead of multiple_threads field in the TCB.
+
+2003-03-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/i686/bits/atomic.h: Removed.
+       * sysdeps/i386/i586/bits/atomic.h: Removed.
+       * sysdeps/i386/i486/bits/atomic.h: Removed.  Moved to glibc.
+       * sysdeps/x86_64/bits/atomic.h: Removed.  Moved to glibc.
+       * sysdeps/s390/bits/atomic.h: Removed.  Moved to glibc.
+       * sysdeps/sh/bits/atomic.h: Removed.  Moved to glibc.
+       * sysdeps/ia64/bits/atomic.h: Removed.  Moved to glibc.
+       * sysdeps/powerpc/bits/atomic.h: Removed.  Moved to glibc.
+       * atomic.h: Removed.  Moved to glibc.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Add
+       support for clock selection.
+
+       * sysdeps/pthread/pthread_cond_broadcast.c: Release lock before
+       signalling waiters.
+
+2003-03-18  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (__lll_test_and_set):
+       Add __lll_rel_instr first.  Add memory clobber.
+       (lll_mutex_unlock): Use __lll_test_and_set.
+       From Paul Mackerras <paulus@samba.org>.
+
+       * sysdeps/powerpc/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Define
+       unconditionally.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+       (SINGLE_THREAD_P):  Add `header.' prefix.
+       From Paul Mackerras <paulus@samba.org>.
+
+       * Versions (libpthread: GLIBC_2.3.2): Move pthread_tryjoin_np and
+       pthread_timedjoin_np to ...
+       (libpthread: GLIBC_2.3.3): ... here.
+       (libpthread: GLIBC_2.2): Move pthread_barrierattr_getpshared there too.
+
+       * sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
+       Avoid shadowing VAL variable.
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (__lll_test_and_set):
+       New macro.
+
+2003-03-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-cond11.
+       * tst-cond11.c: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Reorder
+       struct passed to cleanup handler to eliminate one more
+       instruction.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+       (pthrad_cond_t): Replace __unused field with __clock.
+
+       * sysdeps/pthread/pthread_cond_wait.c: Release condvar lock before
+       waken all waiters in cleanup handler.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+
+       * pthread_condattr_getclock.c: New file.
+       * pthread_condattr_setclock.c: New file.
+       * sysdeps/pthread/pthread.h: Declare these new functions.
+       * Versions [GLIBC_2.3.3] (libpthread): Add the new functions.
+       * Makefile (libpthread-routines): Add the new functions.
+       * sysdeps/unix/sysv/linux/internaltypes.h (struct pthread_condattr):
+       Renamed field to value.  Document use of the bits.
+       * pthread_condattr_getpshared.c: Adjust for struct pthread_condattr
+       change.
+       * pthread_condattr_setpshared.c: Likewise.
+       * pthread_cond_init.c (__pthread_cond_init): Initialized __clock field.
+       * sysdeps/unix/sysv/linux/lowlevelcond.sym: Add cond_clock symbol.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_cond_t):
+       Add __clock field.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S:
+       Implement clock selection.
+       * sysdeps/pthread/pthread_cond_timedwait.c: Likewise.
+       * pthread-errnos.sym: Add ENOSYS.
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
+       _POSIX_CLOCK_SELECTION.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Remove
+       invalid .size directive.
+
+2003-03-17  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/lowlevellock.c (__lll_lock_wait):
+       Formatting tweaks.
+
+2003-03-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/pthread_once.c: Use __builtin_expect.
+       Use __lll_add instead of spelling it out.  Use protected symbol names.
+       * sysdeps/unix/sysv/linux/ia64/sem_post.c: Use __builtin_expect.
+       Use __lll_add.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_compare_and_swap):
+       Renamed from lll_compare_and_swap.  Use new name where necessary.
+       (__lll_add): Defined.
+       (__lll_dec_if_positive): Defined.
+       (__lll_test_and_set): Defined.
+       * sysdeps/ia64/pthread_spin_init.c: Removed.
+       * sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c: Removed.
+       * sysdeps/unix/sysv/linux/ia64/sem_trywait.c: Removed.
+       * sysdeps/unix/sysv/linux/ia64/sem_wait.c: Removed.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.c: Removed.
+       * sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c: Removed.
+       * sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c: Removed.
+       * sysdeps/unix/sysv/linux/ia64/sem_timedwait.c: Removed.
+       * sysdeps/ia64/bits/atomic.h: Add __builtin_expect where appropriate.
+       * sysdeps/ia64/pthread_spin_unlock.c (pthread_spin_unlock): Use
+       __sync_lock_release_si.
+       Patch by Jakub Jelinek.
+
+       * sysdeps/unix/sysv/linux/lowlevellock.c (__lll_timedlock_wait):
+       Fix timeout handling.
+       (__lll_timedwait_tid): Likewise.
+       (lll_unlock_wake_cb): Wake up other waiters if necessary.
+       Patch by Jakub Jelinek.
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Pretty printing.
+
+2003-03-17  Roland McGrath  <roland@redhat.com>
+
+       PowerPC port contributed by Paul Mackerras <paulus@samba.org>.
+       * sysdeps/pthread/pthread_spin_init.c: New file.
+       * sysdeps/pthread/pthread_spin_unlock.c: New file.
+       * sysdeps/powerpc/Makefile: New file.
+       * sysdeps/powerpc/pthread_spin_lock.c: New file.
+       * sysdeps/powerpc/pthread_spin_trylock.c: New file.
+       * sysdeps/powerpc/pthreaddef.h: New file.
+       * sysdeps/powerpc/tcb-offsets.sym: New file.
+       * sysdeps/powerpc/td_ta_map_lwp2thr.c: New file.
+       * sysdeps/powerpc/tls.h: New file.
+       * sysdeps/powerpc/bits/atomic.h: New file.
+       * sysdeps/unix/sysv/linux/libc-lowlevelmutex.c: New file.
+       * sysdeps/unix/sysv/linux/libc-lowlevellock.c: New file.
+       * sysdeps/unix/sysv/linux/lowlevellock.c: New file.
+
+       * sysdeps/unix/sysv/linux/lowlevelmutex.c: New file.
+       * sysdeps/unix/sysv/linux/sem_post.c: New file.
+       * sysdeps/unix/sysv/linux/sem_timedwait.c: New file.
+       * sysdeps/unix/sysv/linux/sem_trywait.c: New file.
+       * sysdeps/unix/sysv/linux/sem_wait.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/Makefile: New file.
+       * sysdeps/unix/sysv/linux/powerpc/createthread.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/fork.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/powerpc/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/pthread_once.c: New file.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: New file.
+       * sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: New file.
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.c: Use __gettimeofday,
+       not gettimeofday.
+       * sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevelmutex.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c: Likewise.
+
+2003-03-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_wait.c: Correct exit criteria.
+       * sysdeps/pthread/pthread_cond_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+       Patch by Ewald Snel <ewald@rambo.its.tudelft.nl>.
+
+2003-03-16  Roland McGrath  <roland@redhat.com>
+
+       * tst-fork4.c: Include <string.h>.
+       * tst-signal2.c: Likewise.
+       * tst-mutex5.c (do_test): exit -> return.
+       * tst-mutex2.c: Include <stdlib.h>.
+
+2003-03-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S
+       (__lll_mutex_timedlock_wait): Correct expected value after
+       spurious wakeup.  Otherwise we would never wait again.
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Work around red
+       zone versus inline asm stupidity.  Use correct instructions.
+
+       * tst-rwlock6.c: Add some more status output.
+
+2003-03-15  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/pthread/configure.in: New file.
+       * sysdeps/pthread/configure: New file (generated).
+
+2003-03-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (allocate_stack): Store the exact stack size of
+       user allocated stacks.
+
+2003-03-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
+       (SINGLE_THREAD): Use `header' prefix instead of `header.data'.
+       * sysdeps/sh/tcb-offsets.sym (MULTIPLE_THREADS_OFFSET): Likewise.
+       * sysdeps/sh/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Define.
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (SINGLE_THREAD_P):
+       Use `header.' prefix.
+       * sysdeps/ia64/tcb-offsets.sym (MULTIPLE_THREADS_OFFSET): Likewise.
+
+2003-03-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/x86_64/pthreaddef.h (CURRENT_STACK_FRAME): Don't use
+       __builtin_frame_address, use stack pointer.
+
+       * sysdeps/unix/sysv/linux/jmp-unwind.c: Use CURRENT_STACK_FRAME
+       instead of __builtin_frame_pointer.
+
+2003-03-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-basic1.c (do_test): Add cast to avoid warning.
+       * tst-basic2.c (do_test): Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Use correct
+       amount of stack correction.
+
+       * tst-fork4.c: Use test-skeleton.c.
+
+2003-03-14  Roland McGrath  <roland@redhat.com>
+
+       * init.c: Fix typo "#eli" for "#else".
+
+2003-03-14  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * allocatestack.c (__stack_user): Use hidden_data_def.
+       * pthread_create.c (__pthread_keys): Likewise.
+
+       * init.c [__powerpc__] (__NR_set_tid_address): Define it.
+
+2003-03-14  Roland McGrath  <roland@redhat.com>
+
+       * tst-fork4.c: New file.
+       * Makefile (tests): Add it.
+
+       * descr.h (struct pthread): Move the union out of [!TLS_DTV_AT_TP], so
+       we always define the padding space.
+       [!TLS_DTV_AT_TP]: Give tcbhead_t field a name, `header', since GCC
+       stopped supporting its own extensions fully.
+       [TLS_MULTIPLE_THREADS_IN_TCB]: Put `multiple_threads' inside a wrapper
+       struct also called `header', so `header.multiple_threads' is the field
+       name to use on all machines.
+       * allocatestack.c (allocate_stack): Use `header.' prefix.
+       * sysdeps/pthread/createthread.c (create_thread): Likewise.
+       * pthread_create.c (__pthread_create_2_1): Likewise.
+       * sysdeps/i386/tls.h (INSTALL_NEW_DTV, THREAD_DTV): Likewise.
+       (THREAD_SELF): Likewise.
+       * sysdeps/x86_64/tls.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+
+       * sysdeps/s390/td_ta_map_lwp2thr.c (td_ta_map_lwp2thr): Use REGS[18]
+       value directly.
+
+2003-03-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_create.c (start_thread): Use CALL_THREAD_FCT if defined.
+       * sysdeps/i386/tls.h: Define CALL_THREAD_FCT.
+
+       * pthread_create.c (start_thread): setjmp is expected to return 0.
+
+       * sysdeps/x86_64/tls.h (THREAD_GETMEM): Mark asms volatile.
+       (THREAD_GETMEM_NC): Likewise.
+
+2003-03-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (allocate_stack): If MULTI_PAGE_ALIASING is defined
+       and the size of the stack which must be allocated is a multiple,
+       allocate one more page.
+       * sysdeps/i386/i686/Makefile: Don't define COLORING_INCREMENT, but
+       MULTI_PAGE_ALIASING.
+
+2003-03-13  Roland McGrath  <roland@redhat.com>
+
+       * pthread_create.c (start_thread): Set EXITING_BIT after the
+       event-reporting (and destructors), not before.
+
+2003-03-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (lll_futex_timed_wait,
+       lll_futex_wake): Declare register variables as long int instead of
+       unsigned long int.  Patch by Ian Wienand <ianw@gelato.unsw.edu.au>.
+       Make syscall arguments clobbered by the syscall.
+       (lll_futex_wait): Define using lll_futex_timed_wait.
+
+       * sysdeps/ia64/td_ta_map_lwp2thr.c (td_ta_map_lwp2thr): Cast regs[13]
+       to void *.
+
+       * sysdeps/unix/sysv/linux/fork.c (__libc_fork): Only declare and set
+       PPID if [! NDEBUG].
+
+       * allocatestack.c (nptl_ncreated): Only declare if
+       COLORING_INCREMENT != 0.
+
+       * pthreadP.h (__pthread_enable_asynccancel_2): New prototype.
+       (__libc_enable_asynccancel_2): Remove prototype.
+
+       * sysdeps/unix/sysv/linux/ia64/fork.c (ARCH_FORK): Swap ptid and
+       ctid to match kernel.
+
+2003-03-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add
+       libc_multiple_threads.
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c: Move definition of
+       __libc_multiple_threads to...
+       * sysdeps/unix/sysv/linux/libc_multiple_threads.c: ...here.  New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Remove unnecessary
+       versioning.
+       * sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S
+       (__pthread_once_internal): Define.
+
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Use shlib-compat.h
+       macros instead of .symver directly.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+
+       * sysdeps/x86_64/tls.h [__ASSEMBLER__]: Include tcb-offsets.h.
+       * sysdeps/x86_64/tcb-offsets.sym: New file.
+       * sysdeps/x86_64/Makefile: New file.
+
+       * sysdeps/i386/tcb-offsets.sym: Add SELF.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Use SELF
+       to access own pthread_t in TCB.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+
+2003-03-12  Roland McGrath  <roland@redhat.com>
+
+       * pthread-errnos.sym: New file.
+       * Makefile (gen-as-const-headers): New variable, list that file.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Include generated
+       header <pthread-errnos.h> instead of defining errno values here.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_trywait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: Likewise.
+       * sysdeps/i386/i486/pthread_spin_trylock.S: Likewise.
+       * sysdeps/x86_64/pthread_spin_trylock.S: Likewise.
+       * sysdeps/sh/pthread_spin_trylock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/fork.c: Add an assert to check that
+       CLONE_CHILD_SETTID worked.
+
+2003-03-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S: New
+       file.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S: New
+       file.
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+       (pthread_cond_t): Add padding.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
+       (__pthread_rwlock_timedwrlock): Add missing opcode suffix.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
+       (__pthread_rwlock_timedrdlock): Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
+       (__pthread_rwlock_wrlock): Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
+       (__pthread_rwlock_rdlock): Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Return
+       result of lock re-get if it fails.
+
+2003-03-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Fix asm syntax.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+
+       * sysdeps/x86_64/tls.h (THREAD_SELF, THREAD_GETMEM, THREAD_GETMEM_NC,
+       THREAD_SETMEM, THREAD_SETMEM_NC): Correct asm syntax.
+
+       * allocatestack.c [! TLS_MULTIPLE_THREADS_IN_TCB] (allocate_stack):
+       Initialize *__libc_multiple_threads_ptr not __libc_multiple_threads.
+       * sysdeps/pthread/createthread.c [! TLS_MULTIPLE_THREADS_IN_TCB]
+       (create_thread): Likewise.
+       Define __pthread_multiple_threads and __libc_multiple_threads_ptr.
+       * init.c (__pthread_initialize_minimal_internal): Initialize
+       __libc_multiple_threads_ptr if necessary.
+       * pthreadP.h: Adjust prototype for __libc_pthread_init.  Declare
+       __pthread_multiple_threads and __libc_multiple_threads_ptr.
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c: Define
+       __libc_multiple_threads.
+       (__libc_pthread_init): Return pointer to __libc_pthread_init if
+       necessary.
+
+       * sysdeps/i386/tls.h (THREAD_SETMEM): Fix one-byte variant.
+       (THREAD_SETMEM_NC): Likewise.
+
+       * sysdeps/x86_64/pthread_spin_trylock.c: Removed.
+       * sysdeps/x86_64/pthread_spin_trylock.S: New file.
+       * sysdeps/x86_64/pthread_spin_unlock.c: Removed.
+       * sysdeps/x86_64/pthread_spin_unlock.S: New file.
+
+       * sysdeps/i386/i486/pthread_spin_trylock.S (pthread_spin_trylock):
+       Eliminate one entire instruction.
+
+       * cancellation.c (__pthread_enable_asynccancel_2): New function.
+       * pthreadP.h: Declare __pthread_enable_asynccancel_2.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Use __pthread_enable_asynccancel_2
+       instead of __pthread_enable_asynccancel.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+       (__pthread_cond_wait): Likewise.
+       * sysdeps/pthread/pthread_cond_timedwait.c
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Likewise.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+       (__condvar_cleanup): Wake up all waiters in case we got signaled
+       after being woken up but before disabling asynchronous
+       cancellation.
+       * sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+       (__condvar_cleanup): Likewise.
+
+       * init.c (__NR_set_tid_address): If already defined, don't redefine.
+       Make it an error if architecture has no #if case.  Add x86-64.
+
+       * sysdeps/unix/sysv/linux/x86_64/Makefile: Add flags for
+       pt-initfini.s generation.
+
+       * sysdeps/x86_64/tls.h: Include <asm/prctl.h>.
+       (TLS_INIT_TP): Fix typo.
+
+2003-03-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/ia64/bits/atomic.h (atomic_exchange_and_add): Swap 2nd and
+       3rd argument of __arch_compare_and_exchange_{32,64}_val_acq.
+
+       * sysdeps/unix/sysv/linux/ia64/sem_post.c: Include semaphore.h.
+       * sysdeps/unix/sysv/linux/ia64/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/sem_trywait.c: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/sem_wait.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_post.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_trywait.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_wait.c: Likewise.
+
+2003-03-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread_cond_timedwait.c
+       (__pthread_cond_timedwait): Return the result of the final
+       locking.  If it succeeds, the regular function return value.
+
+       * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait):
+       Return result of the final locking.
+       * version.c (__nptl_main): Work around problems with the strange
+       INTERNAL_SYSCALL macro on ppc32.
+       * init.c (__pthread_initialize_minimal_internal): Unblock
+       SIGCANCEL in case the parent blocked it.
+       Reported by Paul Mackerras <paulus@samba.org>.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: New file.
+
+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.
+       * sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Fix error value in
+       unused code.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S: New file
+
+       * sysdeps/unix/sysv/linux/Makefile (gen-as-const-headers): Add
+       lowlevelbarrier.sym.
+       * sysdeps/unix/sysv/linux/lowlevelbarrier.sym: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S:
+       Include lowlevelbarrier.h and don't define offsets locally.
+       * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+       (__lll_mutex_lock_wait): Reverse order of first two parameters.
+       (__lll_mutex_timedlock_wait): Likewise.
+       (lll_mutex_lock): Adjust asm for that.
+       (lll_mutex_timedlock): Likewise.  Mark cx, cc, r10 as clobbered.
+       (lll_lock): Adjust asm for operand order change.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/libc-lowlevelmutex.S: New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (__lll_lock_wait):
+       Reverse order of parameters.
+       (__lll_timedwait_tid): Remove regparms attribute.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: New file.
+       * sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+       (__lll_timedwait_tid): Remove one unnecessary instruction.
+
+       * sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: Define
+       __lll_mutex_timedlock_wait only for NOT_IN_libc.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S: Include
+       lowlevelmutex.S.
+
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Define
+       lll_unlock_wake_cb, __lll_wait_tid, and __lll_timedwait_tid only
+       for NOT_IN_libc.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Include
+       lowlevellock.S.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S: Don't define
+       LOCK is already defined.  Don't define __lll_mutex_timedlock_wait
+       for libc.so.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S: Only
+       define LOCK here (if UP is not defined).  The actual code is in
+       lowlevelmutex.S.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Don't define
+       LOCK is already defined.  Don't define lll_unlock_wake_cb and
+       __lll_timedwait_tid for libc.so.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Only
+       define LOCK here (if UP is not defined).  The actual code is in
+       lowlevellock.S.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevelsem.h: Not needed anymore.
+       * sysdeps/unix/sysv/linux/s390/lowlevelsem.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_post.c: Include lowlevellock.h
+       instead of lowlevelsem.h.
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_trywait.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/sem_wait.c: Likewise.
+
+       * sysdeps/unix/sysv/linux/Makefile (gen-as-const-headers): Add
+       lowlevelrwlock.sym.
+       * sysdeps/unix/sysv/linux/lowlevelrwlock.sym: New file.
+       * sysdeps/unix/sysv/linux/i386/lowlevelrwlock.h: Removed.
+       * sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h: Removed.
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_trylock): Fix
+       register loading.
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_trylock): Undo
+       last changed.  D'oh.
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: New file.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Remove declaration
+       of __libc_locking_needed.
+       (lll_trylock): Initialize %eax to zero.
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Update
+       pthread_cond_t definition.
+
+2003-03-10  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/lowlevelcond.sym: New file.
+       * sysdeps/unix/sysv/linux/Makefile (gen-as-const-headers): Add it.
+       * sysdeps/unix/sysv/linux/sh/lowlevelcond.h: File removed.
+       * sysdeps/unix/sysv/linux/i386/lowlevelcond.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevelcond.h: Likewise.
+
+       * allocatestack.c (allocate_stack) [!TLS_MULTIPLE_THREADS_IN_TCB]:
+       Instead of setting PD->multiple_threads, set globals
+       __pthread_multiple_threads and __libc_multiple_threads.
+       * sysdeps/pthread/createthread.c (create_thread): Likewise.
+       * sysdeps/i386/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Define it.
+       * sysdeps/s390/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Likewise.
+
+       * descr.h (struct pthread): Conditionalize first member on
+       [!TLS_DTV_AT_TP].  Replace the `header' member with an anonymous union
+       containing an anonymous tcbhead_t.  Move `list' member out.
+       [TLS_MULTIPLE_THREADS_IN_TCB]: Define a `multiple_threads' member.
+       * allocatestack.c: Remove use of `header.data.' prefix.
+       * pthread_create.c: Likewise.
+       * init.c (__pthread_initialize_minimal_internal): Likewise.
+       * sysdeps/pthread/createthread.c (create_thread): Likewise.
+       * sysdeps/i386/tls.h (INSTALL_DTV): Add parens.
+       (THREAD_SELF, THREAD_DTV, INSTALL_NEW_DTV): No `header.data.' prefix.
+       * sysdeps/x86_64/tls.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/i386/tls.h (tcbhead_t): Remove `list' member.
+       * sysdeps/s390/tls.h (tcbhead_t): Likewise.
+
+2003-03-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/lowlevelcond.h: New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/x86_64/fork.c: New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Fix many
+       leftovers from the ia32 code.
+
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S: Remove unneccessary
+       memory load.
+       (clear_once_control): Don't load %esi.
+
+       * sysdeps/x86_64/tls.h: Remove all traces of segment descriptor
+       handling.
+
+       * sysdeps/unix/sysv/linux/x86_64/fork.c: New file.
+
+       * sysdeps/unix/sysv/linux/s390/createthread.c: Moved to...
+       * sysdeps/unix/sysv/linux/createthread.c: ...here.
+
+       * Makefile (tests): Add tst-cond10.
+       * tst-cond10.c: New file.
+
+2003-03-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-tls2.c (do_test): Add TEMP_FAILURE_RETRY around sem_wait call.
+       * tst-signal3.c (do_test): Likewise.
+       * tst-sem5.c (do_test): Likewise.
+       * tst-kill6.c (do_test): Likewise.
+       * tst-tls3.c (do_test): Likewise.  Include <errno.h>.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Use add/sub instead
+       of inc/dec.
+       * sysdeps/unix/sysv/linux/i386/lowlevelsem.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S: Likewise
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+
+       * allocatestack.c (allocate_stack): If mprotect() fails free the
+       TLS memory.
+
+2003-03-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/i486/bits/atomic.h: Fix a few unused definitions.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Remove all trace of
+       lll_wake_tid.  This was used only to work around kernel limits in
+       the early days.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise.
+
+       * init.c (__static_tls_align_m1): Renamed from __static_tls_align.
+       (__pthread_initialize_minimal_internal): Change initialization of
+       __static_tls_align_m1 appropriately.
+       * pthreadP.h (__static_tls_align_m1): Renamed from
+       __static_tls_align.
+       * allocatestack.c (allocate_stack): Use __static_tls_align_m1
+       instead of __static_tls_align-1.
+
+2003-03-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/Makefile: New file.
+
+       * pthread_create.c: Define __pthread_keys using nocommon
+       attribute, not by placing it explicitly in bss.
+       Remove DEFINE_DEALLOC definition.  Not needed anymore.
+
+       * allocatestack.c: Define ARCH_MAP_FLAGS if not already defined.
+       Use it in mmap call to allocate stacks.
+
+       * sysdeps/pthread/createthread.c (create_thread): Fix comment.
+
+       * pthread_create.c (start_thread): Use THREAD_SETMEM to store
+       result of the thread function.
+
+2003-03-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/s390/dl-sysdep.h: Removed.  The generic
+       version is just fine.
+
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c
+       (__pthread_child_handler): Renamed from pthread_child_handler,
+       exported, and marked hidden.  Change all users.
+       * sysdeps/unix/sysv/linux/register-atfork.c (free_mem): Do not
+       free __pthread_child_handler from child list.
+
+2003-03-03  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+       * atomic.h (atomic_exchange_and_add): Return newval, not oldval.
+
+       * sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
+       Fix handling of cancellation and failing pthread_mutex_unlock call.
+       * sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Likewise.
+       (__pthread_cond_wait): Likewise.
+
+       * sysdeps/pthread/pthread_rwlock_timedrdlock.c
+       (pthread_rwlock_timedrdlock): Fix clobber of result variable by
+       lll_futex_timed_wait call.
+       * sysdeps/pthread/pthread_rwlock_timedwrlock.c
+       (pthread_rwlock_timedwrlock): Likewise.
+
+       * sysdeps/unix/sysv/linux/s390/libc-lowlevellock.c (___lll_lock):
+       Don't define lll_unlock_wake_cb and ___lll_timedwait_tid in libc.so.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.c: Remove XXX comments.
+
+       * sysdeps/unix/sysv/linux/s390/sem_post.c (__new_sem_post): Fix
+       check of lll_futex_wake return value.
+
+2003-03-03  Roland McGrath  <roland@redhat.com>
+
+       * forward.c: Fix typo in __pthread_attr_init_2_0 compat_symbol decl.
+
+       * sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+       Argument to ptr___pthread_cleanup_upto is __jmp_buf, not jmp_buf.
+       * sysdeps/unix/sysv/linux/jmp-unwind.c: Likewise.
+
+2003-03-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/timer_create.c (timer_create): Return correct
+       error for CPU clocks.
+
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
+       _POSIX_MONOTONIC_CLOCK.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Likewise.
+
+       * tst-cancel4.c (tf_sleep): Lower sleep time a bit to not upset
+       recent kernels.
+
+2003-03-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h (struct pthread): Move cleanup field to the front.
+
+2003-03-01  Roland McGrath  <roland@redhat.com>
+
+       * sem_open.c (sem_open): Braino fix.
+
+2003-03-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/tcb-offsets.sym: Add CLEANUP and CLEANUP_PREV.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Inline
+       __pthread_cleanup_pop functionality.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+
+       * descr.h (struct pthread): Move tid field to the front now that
+       it is often used.
+
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S
+       (__lll_mutex_timedlock_wait): Remove.
+       (__lll_mutex_unlock_wake): Don't save, load, and restore %esi.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S
+       (__lll_mutex_unlock_wake): Don't save, load, and restore %esi.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+       (lll_unlock_wake_cb): Don't save and restore %esi.
+       (__lll_unlock_wake): Add alignment.  Don't save, load, and restore
+       %esi.
+       (__lll_timedwait_tid): Add alignment.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
+       (__lll_unlock_wake): Add alignment.  Don't save, load, and restore
+       %esi.
+       (__lll_timedwait_tid): Removed.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Don't save, load, and restore %esi.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
+       (pthread_barrier_wait): Don't save, load, and restore %esi for
+       last thread.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+       (__pthread_cond_signal): Don't save, load, and restore %esi.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
+       (__pthread_rwlock_unlock): Don't save, load, and restore %esi.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S (__new_sem_post):
+       Don't save, load, and restore %esi.
+
+2003-02-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S:
+       Release lock before waking up the waiters.
+
+       * tst-exit1.c (do_test): Don't start more than one thread in parallel.
+
+       * tst-rwlock9.c (writer_thread): Correct adding TIMEOUT.
+       (reader_thread): Likewise.
+
+       * sysdeps/pthread/pthread_rwlock_unlock.c
+       (__pthread_rwlock_unlock): Release internal lock early.  Don't try
+       to wake up readers if there are none.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S:
+       Release internal lock before wake threads.
+
+2003-02-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-rwlock10 and tst-rwlock11.
+       * tst-rwlock8.c: Initialize lock with INIT.  Allow INIT to be
+       predefined.
+       * tst-rwlock9.c: Likewise.
+       * tst-rwlock10.c: New file.
+       * tst-rwlock11.c: New file.
+
+       * Makefile (tests): Add tst-dlsym1.
+       * tst-dlsym1.c: New file.
+
+       * init.c (__pthread_initialize_minimal_internal): Set
+       GL(dl_error_catch_tsd) to __libc_dl_error_tsd.
+       * Versions (libc:GLIBC_PRIVATE): Export __libc_dl_error_tsd.
+
+2003-02-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * sem_open.c (sem_open): Fix handling of O_CREAT without O_EXCL.
+
+       * tst-cond2.c: Fix sychronization with child.
+
+       * tst-rwlock8.c (reader_thread): Remove unused variable.
+
+       * Makefile: Add rules to build and run tst-tls3.
+       * tst-tls3.c: New file.
+       * tst-tls3mod.c: New file.
+
+       * Makefile (tests): Add tst-rwlock8 and tst-rwlock9.
+       * tst-rwlock8.c: New file.
+       * tst-rwlock9.c: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Fix
+       complete broken rwlock implementation.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/pthread/pthread_rwlock_rdlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_timedrdlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_timedwrlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_unlock.c: Likewise.
+       * sysdeps/pthread/pthread_rwlock_wrlock.c: Likewise.
+
+2003-02-23  Roland McGrath  <roland@redhat.com>
+
+       * Makefile (nptl-version): Change regexp so case sensitivity is ok.
+
+2003-02-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-context1.
+       * tst-context1.c: New file.
+
+       * Makefile (tests): Add tst-tls1 and tst-tls2.
+       * tst-tls1.c: New file.
+       * tst-tls2.c: New file.
+
+       * libc-cancellation.c (__libc_enable_asynccancel): Correct test
+       for failed cmpxchg.
+
+       * pthread_create.c (start_thread): Set EXITING_BIT early.
+
+       * sysdeps/i386/tls.h (THREAD_GETMEM): Mark asm as volatile.
+       (THREAD_GETMEM_NC): Likewise.
+
+2003-02-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Shave
+       off 3 more bytes by using offset-less instructions when possible.
+
+       * Makefile: Add dependency for $(objpfx)version.d.
+
+       * eintr.c (eintr_source): Add unnecessary return but the compiler
+       insists.
+
+       * tst-kill3.c: Include <unistd.h>.
+
+2003-02-21  Roland McGrath  <roland@redhat.com>
+
+       * pthread_create.c (start_thread): Call __libc_thread_freeres.
+
+2003-02-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-eintr1.
+       (distribute): Add eintr.c.
+       * tst-eintr1.c: New file.
+       * eintr.c: New file.
+
+       * pthread_cancel.c (pthread_cancel): Use tkill directly.
+
+       * sysdeps/unix/sysv/linux/pthread_kill.c (__pthread_kill):
+       Disallow sending SIGCANCEL.
+
+       * Makefile (tests): Remove tst-basic7.  Add tst-kill1, tst-kill2,
+       tst-kill3, tst-kill4, tst-kill5, tst-kill6.
+       * tst-kill1.c: New file.
+       * tst-kill2.c: New file.
+       * tst-kill3.c: New file.
+       * tst-kill5.c: New file.
+       * tst-kill6.c: New file.
+       * tst-basic7.c: Renamed to...
+       * tst-kill4.c: ...this.
+
+2003-02-21  Roland McGrath  <roland@redhat.com>
+
+       * Makefile (install-lib-ldscripts): New variable.
+
+2003-02-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h: Define INVALID_TD_P and INVALID_NOT_TERMINATED_TD_P.
+       * pthread_cancel.c: Use INVALID_TD_P.
+       * pthread_detach.c: Likewise.
+       * pthread_getschedparam.c: Likewise.
+       * pthread_setschedparam.c: Likewise.
+       * sysdeps/pthread/pthread_getcpuclockid.c: Likewise.
+       * sysdeps/unix/sysv/linux/pthread_kill.c: Likewise.
+       * pthread_join.c: Use INVALID_NOT_TERMINATED_TD_P.
+       * pthread_timedjoin.c: Likewise.
+
+       * tst-basic7.c: Include <signal.h>.
+
+       * pthread_join.c (pthread_join): Limited checking for invalid
+       descriptors.
+       * pthread_timedjoin.c (pthread_timedjoin_np): Likewise.
+
+2003-02-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_create.c (deallocate_tsd): Reset found_nonzero at the
+       beginning of the loop.  Clear the entire first block of TSD.
+       * Makefile (tests): Add tst-key4.
+       * tst-key4.c: New file.
+
+2003-02-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-basic7.
+       * tst-basic7.c: New file.
+
+       * pthread_create.c (deallocate_tsd): Mark as internal_function.
+       Add some more __builtin_expect.
+
+       * pthreadP.h: Define dummy version of DEBUGGING_P.
+
+2003-02-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Remnove
+       _POSIX_THREAD_PRIORITY_SCHEDULING.
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Remove
+       _XOPEN_REALTIME_THREADS.
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Likewise.
+
+       * sysdeps/unix/sysv/linux/pthread_kill.c (__pthread_kill): The
+       kernel returns EINVAL for PID <= 0, work around it.
+
+       * Makefile (tests): Add tst-signal5.
+       * tst-signal5.c: New file.
+
+       * sysdeps/unix/sysv/linux/bits/local_lim.h: Define TTY_NAME_MAX
+       and LOGIN_NAME_MAX.
+
+       * tst-cancel1.c (tf): Block all signals.
+
+       * Makefile (tests): Add tst-basic6.
+       * tst-basic6.c: New file.
+
+       * tst-basic1.c: Add test for process ID.
+
+       * Makefile (tests): Add tst-cancel10.
+       * tst-cancel10.c: New file.
+
+       * Makefile (tests): Add tst-signal4.
+       * tst-signal4.c: New file.
+
+       * sysdeps/pthread/pthread_sigmask.c (pthread_sigmask): Use
+       __sigismember instead of sigismember.  Add __builtin_expect.
+
+2003-02-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-attr1.c (do_test): Add tests for pthread_setcanceltype,
+       pthread_setcancelstate, and pthread_rwlock_setpshared.
+
+       * tst-cancel7.c (do_test): Make sure the pid file exists before
+       canceling the thread.
+
+       * tst-rwlock6.c: More pthread_rwlock_timedwrlock and
+       pthread_rwlock_timedrdlock tests.
+       * tst-rwlock7.c: More pthread_rwlock_timedwrlock tests.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Check for invalid tv_nsec field.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+
+       * pthread_mutex_trylock.c (__pthread_mutex_trylock): Protect
+       recursive mutex of overflow.
+
+       * tst-attr1.c (do_test): Add test for pthread_mutexattr_setpshared.
+
+       * libc-cancellation.c (__libc_enable_asynccancel): Rewrite to avoid
+       going into an endless loop.
+       * Makefile (tests): Add tst-cancel9.
+       * tst-cancel9.c: New file.
+
+       * pthread_cancel.c (pthread_cancel): Use the result of __pthread_kill.
+
+2003-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-mutex5.c (do_test): Add more timedlock tests.
+
+       * tst-mutex2.c: Tests of trylock and unlock with ERROR mutexes.
+       * tst-mutex3.c (do_test): Add tests for trylock with RECURSIVE mutexes.
+
+       * sysdeps/unix/sysv/linux/pthread_kill.c (__pthread_kill): Don't
+       use INLINE_SYSCALL.  Error number is returned, not -1.
+
+       * pthreadP.h: Mark declarations of __find_in_stack_list, __free_tcb,
+       and __deallocate_stack with internal_function.
+       * pthread_create.c: Adjust definitions appropriately.
+       * allocatestack.c: Likewise.
+
+       * pthread_join.c: Add one more __builtin_expect.
+       * pthread_timedjoin.c: Likewise.
+
+       * pthread_getspecific.c (__pthread_getspecific): Clear data->data
+       not data of sequence number does not match.
+       Add one __builtin_expect.
+
+       * Makefile (tests): Add tst-clock1.
+       * tst-clock1.c: New file.
+
+       * pthread_setconcurrency.c (pthread_setconcurrency): Fail for
+       negative arguments.
+       * Makefile (tests): Add tst-basic5.
+       * tst-basic5.c: New file.
+
+2003-02-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-basic4.
+       * tst-basic4.c: New file.
+
+       * pthreadP.h: Add declaraction for __nptl_nthreads.
+       * pthread_create.c: Define __nptl_nthreads
+       (start_thread): Increment __nptl_nthreads at beginning.  Decrement
+       after thread is done.  If then zero, call exit(0).
+       * sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+       Add ptr_nthreads.  Define HAVE_PTR_NTHREADS.
+       * init.c (pthread_functions): Initialize ptr_nthreads.
+       * allocatestack.c (nptl_nthreads): Remove definition and all uses.
+       (__reclaim_stacks): Decrement __nptl_nthreads.
+       * sysdeps/pthread/Makefile [$(subdir)==csu] (CFLAGS-libc-start.c):
+       Define.
+       * Makefile (tests): Add tst-basic3.
+       * tst-basic3.c: New file.
+
+       * descr.h: Define CANCELING_BIT and CANCELING_BITMASK.  Introduce
+       after CANCELTYPE_BIT, move the other bits up.  Update CANCEL_RESTMASK.
+       * init.c (sigcancel_handler): Also set CANCELING_BITMASK bit in newval.
+       * pthread_cancel.c (pthread_cancel): Likewise.  Also set CANCELING_BIT
+       if asynchronous canceling is enabled.
+       * pthread_join.c (pthread_join): When recognizing circular joins,
+       take into account the other thread might be already canceled.
+       * Makefile (tests): Add tst-join5.
+       * tst-join5.c: New file.
+
+       * Makefile (tests): Add tst-join4.
+       * tst-join4.c: New file.
+
+2003-02-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cond4.c (main): Add test of pthread_attr_getpshared.
+
+2003-02-13  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+       * sysdeps/s390/tls.h (THREAD_GETMEM, THREAD_GETMEM_NC, THREAD_SETMEM,
+       THREAD_SETMEM_NC): Use passed descr instead of THREAD_SELF.
+       * sysdeps/unix/sysv/linux/s390/jmp-unwind.c (_longjmp_unwind): Avoid
+       warning.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.c: Include <sys/time.h>
+       to avoid warning.
+       * sysdeps/unix/sysv/linux/s390/sem_post.c (__new_sem_post): Return
+       error if lll_futex_wake failed.
+
+2003-02-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Fix
+       handling of cancellation and failung pthread_mutex_unlock call.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * Makefile (tests): Add tst-cond8 and tst-cond9.
+       * tst-cond8.c: New file.
+       * tst-cond9.c: New file.
+
+       * tst-cond7.c (do_test): Unlock the mutex before canceling the thread.
+
+       * sysdeps/pthread/pthread.h: Add missing initializers.  Protect
+       non-standard initializers with __USE_GNU.
+
+       * Makefile (tests): Add tst-cleanup3.
+       * tst-cleanup3.c: New file.
+
+2003-02-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-attr1 and tst-attr2.
+       * tst-attr1.c: New file.
+       * tst-attr2.c: New file.
+
+       * Makefile: Add rules to build and run tst-atfork2 test.
+       * tst-atfork2.c: New file.
+       * tst-atfork2mod.c: New file.
+
+       * sysdeps/unix/sysv/linux/unregister-atfork.c
+       (__unregister_atfork): Free the memory allocated for the handlers
+       after removing them from the lists.
+
+       * sysdeps/unix/sysv/linux/register-atfork.c: Define memeory
+       cleanup function.
+
+       * tst-atfork1.c (do_test): Wait for the child we forked.
+       Report error in child.
+
+       * sysdeps/unix/sysv/linux/fork.c (__libc_fork): Fix comment.
+
+       * sysdeps/pthread/Makefile: Define CFLAGS-confstr.c.
+
+2003-02-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-cancel8.
+       * tst-cancel8.c: New file.
+
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S (clear_once_control): Fix
+       clearing of control variable.
+       * Makefile (tests): Add tst-once3 and tst-once4.
+       * tst-once3.c: New file.
+       * tst-once4.c: New file.
+
+2003-02-08  kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/Makefile: New file.
+       * sysdeps/sh/bits/atomic.h: New file.
+       * sysdeps/sh/pthread_spin_init.c: New file.
+       * sysdeps/sh/pthread_spin_lock.c: New file.
+       * sysdeps/sh/pthread_spin_trylock.S: New file.
+       * sysdeps/sh/pthread_spin_unlock.S: New file.
+       * sysdeps/sh/pthreaddef.h: New file.
+       * sysdeps/sh/tcb-offsets.sym: New file.
+       * sysdeps/sh/td_ta_map_lwp2thr.c: New file.
+       * sysdeps/sh/tls.h: New file.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: New file.
+       * sysdeps/unix/sysv/linux/sh/bits/semaphore.h: New file.
+       * sysdeps/unix/sysv/linux/sh/createthread.c: New file.
+       * sysdeps/unix/sysv/linux/sh/fork.c: New file.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevelcond.h: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h: New file.
+       * sysdeps/unix/sysv/linux/sh/pt-initfini.c: New file.
+       * sysdeps/unix/sysv/linux/sh/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_once.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_post.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_trywait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: New file.
+
+2003-02-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cond2.c: Rearrange code to not rely on behavior undefined
+       according to POSIX.
+
+       * tst-basic2.c (do_test): Lock mutex before creating the thread.
+
+2003-02-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/x86_64/tls.h: Remove unnecessary macros, left over from x86.
+       (TLS_GET_FS): New #define.
+       (TLS_SET_FS): New #define.
+       Correct value of __NR_set_thread_area.
+
+       * sysdeps/x86_64/td_ta_map_lwp2thr.c: New file.
+
+2003-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-popen1.
+       * tst-popen1.c: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Remove wrong
+       but inactive generalization.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: Likewise.
+       Minor optimization, remove one instruction.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Likewise.
+
+2003-02-04  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+       * sysdeps/unix/sysv/linux/s390/fork.c: Correct order of parameters.
+
+2003-01-31  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+       * init.c (__NR_set_tid_address): Add #ifdef for s390.
+       * sysdeps/pthread/pthread_barrier_wait.c: New file.
+       * sysdeps/pthread/pthread_cond_broadcast.c: New file.
+       * sysdeps/pthread/pthread_cond_signal.c: New file.
+       * sysdeps/pthread/pthread_cond_timedwait.c: New file.
+       * sysdeps/pthread/pthread_cond_wait.c: New file.
+       * sysdeps/pthread/pthread_rwlock_rdlock.c: New file.
+       * sysdeps/pthread/pthread_rwlock_timedrdlock.c: New file.
+       * sysdeps/pthread/pthread_rwlock_timedwrlock.c: New file.
+       * sysdeps/pthread/pthread_rwlock_unlock.c: New file.
+       * sysdeps/pthread/pthread_rwlock_wrlock.c: New file.
+       * sysdeps/s390/Makefile: New file.
+       * sysdeps/s390/bits/atomic.h: New file.
+       * sysdeps/s390/pthread_spin_init.c: New file.
+       * sysdeps/s390/pthread_spin_lock.c: New file.
+       * sysdeps/s390/pthread_spin_trylock.c: New file.
+       * sysdeps/s390/pthread_spin_unlock.c: New file.
+       * sysdeps/s390/pthreaddef.h: New file.
+       * sysdeps/s390/tcb-offsets.sym: New file.
+       * sysdeps/s390/td_ta_map_lwp2thr.c: New file.
+       * sysdeps/s390/tls.h: New file.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: New file.
+       * sysdeps/unix/sysv/linux/s390/bits/semaphore.h: New file.
+       * sysdeps/unix/sysv/linux/s390/createthread.c: New file.
+       * sysdeps/unix/sysv/linux/s390/dl-sysdep.h: New file.
+       * sysdeps/unix/sysv/linux/s390/fork.c: New file.
+       * sysdeps/unix/sysv/linux/s390/jmp-unwind.c: New file.
+       * sysdeps/unix/sysv/linux/s390/libc-lowlevellock.c: New file.
+       * sysdeps/unix/sysv/linux/s390/libc-lowlevelmutex.c: New file.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.c: New file.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/s390/lowlevelmutex.c: New file.
+       * sysdeps/unix/sysv/linux/s390/lowlevelsem.h: New file.
+       * sysdeps/unix/sysv/linux/s390/pthread_once.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-32/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/s390/sem_post.c: New file.
+       * sysdeps/unix/sysv/linux/s390/sem_timedwait.c: New file.
+       * sysdeps/unix/sysv/linux/s390/libc-lowlevellock.c: New file.
+       * sysdeps/unix/sysv/linux/s390/sem_wait.c: New file.
+
+2003-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * atomic.h: Add a couple more default implementations.
+       (atomic_compare_and_exchange_acq): Use
+       __arch_compare_and_exchange_32_acq in return value definition.  It
+       always exists.
+       (atomic_bit_set): Renamed from atomic_set_bit.
+       Add missing atomic_ prefixes.
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_once): In case no
+       thread library is available, use correct value to mark initialized
+       once variable.
+
+2003-02-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (allocate_stack): Use __getpagesize instead of
+       __sysconf to determine pagesize.
+
+       * pthread_create.c: Include <atomic.h>.
+       * allocatestack.c (allocate_stack): Implement coloring of the
+       allocated stack memory.  Rename pagesize to pagesize_m1.  It's the
+       size minus one.  Adjust users.
+       * sysdeps/i386/i686/Makefile: New file.
+
+2003-02-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c: Improve comment throughout the file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+       (__lll_lock_wait): Add branch prediction.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
+       (__lll_lock_wait): Likewise.
+       (lll_unlock_wake_cb): Removed.
+
+2003-01-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Remove
+       _POSIX_THREAD_PRIORITY_SCHEDULING.
+
+2003-01-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+       Fix return type of ptr___pthread_getspecific.
+
+2003-01-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-umask1.
+       (tst-umask1-ARGS): Define.
+       * tst-umask1.c: New file.
+
+2003-01-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (libpthread-routines): Remove lowlevelrwlock.  Add
+       pthread_rwlock_rdlock, pthread_rwlock_timedrdlock,
+       pthread_rwlock_wrlock, pthread_rwlock_timedwrlock, and
+       pthread_rwlock_unlock.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i586/lowlevelrwlock.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i686/lowlevelrwlock.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S:
+       New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S:
+       New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S:
+       New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S:
+       New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S: New file.
+
+       * Makefile (libpthread-routines): Remove lowlevelcond and
+       lowlevelsem.  Add sem_wait, sem_trywait, sem_timedwait, sem_post,
+       pthread_cond_wait, pthread_cond_timedwait, pthread_cond_signal,
+       and pthread_cond_broadcast.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i586/lowlevelsem.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i586/lowlevelcond.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i686/lowlevelsem.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i686/lowlevelcond.S: Removed
+       * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/sem_wait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/sem_post.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/sem_wait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/sem_post.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S: New file.
+       * sysdeps/unix/sysv/linux/i386/lowlevelcond.h: New file.
+
+       * sysdeps/unix/sysv/linux/i386/createthread.c: Define
+       PREPARE_CREATE and TLS_VALUE with x86-specific bits.  All the rest
+       of the code is moved to ...
+       * sysdeps/pthread/createthread.c: ...here.  New file.
+
+2003-01-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S
+       (__new_sem_post): Clear %eax before returning.
+       Reported by MAEDA Naoaki <maeda.naoaki@jp.fujitsu.com>.
+
+       * Makefile (tests): Add tst-cleanup2.
+       * tst-cleanup2.c: New file.
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_cleanup_region_start):
+       Interpret first parameter correctly.
+
+2003-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (headers): Add bits/semaphore.h.
+
+2003-01-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/i386/tls.h (INIT_SYSINFO): Initialize _head->sysinfo even
+       if not SHARED.
+
+2003-01-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sem_open.c (sem_open): Return SEM_FAILED if existing semaphore
+       must be used and mapping failed.
+       Reported by Luke Elliott <luke.elliott@activfinancial.com>.
+
+       * Makefile (CFLAGS-pthread_self.os): Define this, not
+       CFLAGS-pthread_self.c.
+
+2003-01-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Don't export
+       lll_unlock_wake_cb.
+
+       * Makefile (libpthread-routines): Add version.  Add rules to build
+       version.os and banner.h.
+       * version.c: New file.
+
+2003-01-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthread_mutex_lock.c (__pthread_mutex_lock_internal): Make
+       the alias unconditional.
+       * pthread_mutex_unlock.c  (__pthread_mutex_unlock_internal): Likewise.
+
+2003-01-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (CFLAGS-pthread_self.c): New definition.
+
+2003-01-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/pthread_sigmask.c (pthread_sigmask): Add
+       INTERNAL_SYSCALL_DECL, add err argument to INTERNAL_SYSCALL* macros.
+       * sysdeps/unix/sysv/linux/raise.c (raise): Likewise.
+       * init.c (__pthread_initialize_minimal_internal): Likewise.
+
+2003-01-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthreadP.h (__pthread_cond_timedwait): Add prototype.
+
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h
+       (RTLD_CORRECT_DYNAMIC_WEAK): Remove.
+       (DL_SYSINFO_IMPLEMENTATION): Change into .text section and back.
+       * sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h
+       (RTLD_CORRECT_DYNAMIC_WEAK): Remove.
+       (DL_SYSINFO_IMPLEMENTATION): Change into .text section and back.
+
+2003-01-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthreadP.h (LIBC_CANCEL_HANDLED): Define.
+       * pt-system.c (LIBC_CANCEL_HANDLED): Add.
+       * tst-cancel-wrappers.sh: Remove all exceptions.
+
+2003-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-cancel-wrappers.sh: Invoke gawk not awk since we use GNU awk
+       features.  Reported by Marijn Ros <marijn@mad.scientist.com>.
+
+       * sysdeps/unix/sysv/linux/jmp-unwind.c: Include <pthread-functions.h>.
+       Use __libc_pthread_functions array if SHARED.
+
+       * pthreadP.h: Move pthread_cond_2_0_t definition to...
+       * sysdeps/unix/sysv/linux/internaltypes.h: ...here.
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_ptf_call): New #define.
+       (__libc_rwlock_rdlock, __libc_rwlock_wrlock, __libc_rwlock_unlock,
+       __libc_key_create, __libc_getspecific, __libc_setspecific): Use
+       __libc_ptf_call instead of __libc_maybe_call.
+       (PTF): New #define.
+       (__libc_cleanup_region_start): Wrap function name with PTF call.
+       (__libc_cleanup_region_end): Likewise.
+       (__libc_cleanup_end): Likewise.
+
+       * pthread_getspecific.c: Add __pthread_getspecific_internal alias.
+       * pthread_setspecific.c: Add __pthread_setspecific_internal alias.
+       * pthread_key_create.c: Add __pthread_key_create_internal alias.
+       * pthreadP.h: Add prototypes.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S: Add
+       __pthread_rwlock_rdlock, __pthread_rwlock_wrlock, and
+       __pthread_rwlock_unlock aliases.
+       * pthreadP.h: Add prototypes for new aliases.
+
+       * pthreadP.h (struct pthead_functions): Moved to...
+       * sysdeps/pthread/pthread-functions.h: ...here.  New file.
+       * init.c (pthread_functions): Add initializers for new elements.
+
+       * cleanup_defer.c: Add __pthread_cleanup_push_defer and
+       __pthread_cleanup_pop_restore aliases.
+       * pthreadP.h: Add prototypes.
+
+       * cleanup.c: Rename _GI_pthread_cleanup_push to __pthread_cleanup_push
+       and _GI_pthread_cleanup_pop to __pthread_cleanup_pop.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S: Adjust caller.
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Likewise.
+       * pthreadP.h: Adjust prototypes and callers.
+
+2003-01-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-cancel7.
+       (tst-cancel7-ARGS): New variable.
+       * tst-cancel7.c: New file.
+
+       * old_pthread_cond_broadcast.c: Optimize initialization a bit to work
+       around gcc defficiencies.
+       * old_pthread_cond_signal.c: Likewise.
+       * old_pthread_cond_timedwait.c: Likewise.
+       * old_pthread_cond_wait.c: Likewise.
+
+       * pthreadP.h (pthread_cond_2_0_t): Remove unneeded lock element.
+
+2003-01-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-cond7.
+       * tst-cond7.c: New file.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S
+       (condvar_cleanup): Get condvar address from the right place.
+
+       * atomic.h: Correct definitions of atomic_full_barrier,
+       atomic_read_barrier, atomic_write_barrier.
+
+       * old_pthread_cond_broadcast.c: Make memory allocate and initialization
+       race-free.
+       * old_pthread_cond_signal.c: Likewise.
+       * old_pthread_cond_timedwait.c: Likewise.
+       * old_pthread_cond_wait.c: Likewise.
+
+2003-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile ($(objpfx)libpthread.so): Depend on ld.so.
+
+2003-01-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h (pthread_cond_2_0_t): New type.
+       (struct pthread_functions): Use new type for 2.0 condvar callbacks.
+       Use new type for the 2.0 condvar function prototypes.
+       * forward.c: Use pthread_cond_2_0_t for 2.0 condvar functions.
+       * old_pthread_cond_init.c: Use pthread_cond_2_0_t for condvar
+       parameter.
+       * old_pthread_cond_destroy.c: Likewise.
+       * old_pthread_cond_broadcast.c: Likewise.  Lock appropriately.
+       * old_pthread_cond_signal.c: Likewise.
+       * old_pthread_cond_timedwait.c: Likewise.
+       * old_pthread_cond_wait.c: Likewise.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S
+       (__pthread_cond_wait): Don't save cancellation mode and seq value
+       in same location.
+
+       * herrno.c (__h_errno_location): Don't define as weak.
+
+2003-01-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * Versions [libc] (GLIBC_2.3.2): Export pthread_cond_broadcast,
+       pthread_cond_destroy, pthread_cond_init, pthread_cond_signal
+       and pthread_cond_wait.
+       * old_pthread_cond_broadcast.c (__old_pthread_cond_broadcast):
+       Renamed to...
+       (__pthread_cond_broadcast_2_0): ... this.
+       * old_pthread_cond_destroy.c (__old_pthread_cond_destroy):
+       Renamed to...
+       (__pthread_cond_destroy_2_0): ... this.
+       * old_pthread_cond_init.c (__old_pthread_cond_init):
+       Renamed to...
+       (__pthread_cond_init_2_0): ... this.
+       * old_pthread_cond_signal.c (__old_pthread_cond_signal):
+       Renamed to...
+       (__pthread_cond_signal_2_0): ... this.
+       * old_pthread_cond_wait.c (__old_pthread_cond_wait):
+       Renamed to...
+       (__pthread_cond_wait_2_0): ... this.
+       * pthread_cond_destroy.c: Include shlib-compat.h.
+       (pthread_cond_destroy): Change strong_alias into versioned_symbol.
+       * pthread_cond_init.c: Include shlib-compat.h.
+       (pthread_cond_init): Change strong_alias into versioned_symbol.
+       * pthreadP.h (struct pthread_functions): Rename ptr_pthread_cond_*
+       fields to ptr___pthread_cond_* and add ptr___pthread_cond_*_2_0
+       fields.
+       (__pthread_cond_broadcast_2_0, __pthread_cond_destroy_2_0,
+       __pthread_cond_init_2_0, __pthread_cond_signal_2_0,
+       __pthread_cond_wait_2_0): New prototypes.
+       (__old_pthread_cond_broadcast, __old_pthread_cond_destroy,
+       __old_pthread_cond_init, __old_pthread_cond_signal,
+       __old_pthread_cond_wait): Removed.
+       * init.c: Include shlib-compat.h.
+       (pthread_functions): Guard ptr___pthread_attr_init_2_0
+       initialization with SHLIB_COMPAT (GLIBC_2_0, GLIBC_2_1).
+       Rename ptr_pthread_cond_* to ptr___pthread_cond_*, initialize
+       ptr___pthread_cond_*_2_0 fields.
+       * forward.c: Export both pthread_cond_*@@GLIBC_2.3.2 and
+       pthread_cond_*@GLIBC_2.0 compatibility symbols.
+
+       * sysdeps/pthread/sigaction.c (SIGCANCEL): Only define if
+       LIBC_SIGACTION was not yet defined.
+       [!defined LIBC_SIGACTION]: Define LIBC_SIGACTION, #include self.
+       [!defined LIBC_SIGACTION] (__sigaction): New function and
+       libc_hidden_weak.
+       [!defined LIBC_SIGACTION] (sigaction): New weak_alias.
+       [defined LIBC_SIGACTION]: #include_next <sigaction.c>.
+
+2003-01-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (CFLAGS-pthread_atfork.c): Add -DNOT_IN_libc.
+
+2003-01-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_cond_t):
+       New, larger type definition.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S: New condvar
+       implementation.
+       * Versions [libpthread]: Add definitions for new pthread_cond_*
+       interfaces for version GLIBC_2.3.2.
+       * pthread_cond_init.c: Update initialization for new type definition.
+       * Makefile (libpthread-routines): Remove pthread_cond_wait,
+       pthread_cond_timedwait, pthread_cond_signal, and
+       pthread_cond_broadcast.  Add old_pthread_cond_init,
+       old_pthread_cond_destroy, old_pthread_cond_wait,
+       old_pthread_cond_timedwait, old_pthread_cond_signal, and
+       old_pthread_cond_broadcast.
+       * old_pthread_cond_broadcast.c: New file.
+       * old_pthread_cond_destroy.c: New file.
+       * old_pthread_cond_init.c: New file.
+       * old_pthread_cond_signal.c: New file.
+       * old_pthread_cond_timedwait.c: New file.
+       * old_pthread_cond_wait.c: New file.
+       * pthreadP.h: Add prototypes for the compatibility interfaces.
+
+       * pthread_cond_destroy.c: Don't include <errno.h>.
+
+2003-01-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S: Avoid
+       unnecessary zero offset when addressing MUTEX.
+
+2002-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/fork.h: Add libc_hidden_proto for
+       __register_atfork.
+       * sysdeps/unix/sysv/linux/register-atfork.c: Add libc_hidden_def
+       for __register_atfork.
+
+2002-12-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Use __ASSEMBLER__
+       instead of ASSEMBLER test macro.
+
+       * sysdeps/unix/sysv/linux/allocrtsig.c (__libc_current_sigrtmin,
+       __libc_current_sigrtmax): Add libc_hidden_def.
+
+       * sysdeps/pthread/list.h: Remove assert.h include.
+
+2002-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pt-initfini.c (call_initialize_minimal): Use
+       __pthread_initialize_minimal_internal not
+       __pthread_initialize_minimal.
+
+2002-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pt-initfini.c (call_initialize_minimal): Mark
+       __pthread_initialize_minimal as hidden.
+
+       * init.c (__pthread_initialize_minimal_internal): Don't mark as
+       constructor.
+
+2002-12-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile ($(inst_libdir)/libpthread.so): Depend on
+       $(common-objpfx)format.lds, include that into the output script.
+       Fix comment.
+       (extra-B-pthread.so): Change linuxthreads/ into nptl/.
+
+2002-12-28  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/xstatconv.c (xstat_conv): Adjust for
+       nsec resolution changes.
+       (xstat64_conv): Likewise.
+       (xstat32_conv): Likewise.
+       * sysdeps/unix/sysv/linux/kernel_stat.h: Add nsec resolution for
+       struct kernel_stat.
+       * sysdeps/unix/sysv/linux/bits/stat.h: Add nsec resolution for
+       structs stat and stat64.
+       * time/time.h (__timespec_defined): Define for __USE_MISC.
+       * io/sys/stat.h [__USE_MISC]: Define __need_timespec for struct stat.
+
+2002-12-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * forward.c (FORWARD2): Renamed from FORWARD3.  Remove unused export
+       argument.
+       (pthread_attr_init_2_0, pthread_attr_init_2_1): Use FORWARD macro.
+       (pthread_exit): Use strong_alias to avoid warnings.
+       * pthreadP.h (struct pthread_functions): Rename ptr_pthread_exit
+       and ptr_pthread_attr_init_2_* to ptr___pthread_exit and
+       ptr___pthread_attr_init_2_*.
+       * init.c (pthread_functions): Adjust.
+
+2002-12-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * forward.c: Make all functions available by default again.  It
+       caused too much trouble.
+
+       * pt-siglongjmp.c: Removed.
+
+2002-12-28  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/i386/tls.h: Include tcb-offsets.h in assembler.
+       (SYSINFO_OFFSET, MULTIPLE_THREADS_OFFSET): Remove.
+       * sysdeps/i386/Makefile: New file.
+       * sysdeps/i386/tcb-offsets.sym: New file.
+       * sysdeps/pthread/tcb-offsets.h: New file.
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+       Remove MULTIPLE_THREADS_OFFSET and SYSINFO_OFFSET checks.
+
+       * sysdeps/unix/sysv/linux/Versions [libc] (GLIBC_PRIVATE): Move
+       __register_atfork...
+       (GLIBC_2.3.2): ...here.
+
+2002-12-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h: Mark pthread_attr_getstackaddr and
+       pthread_attr_setstackaddr with __attribute_deprecated__.
+
+2002-12-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * pt-system.c (system): Remove cancellation handling.
+       * tst-cancel-wrappers.sh: Allow pt-system.o* to not use the
+       cancellation routines.
+
+2002-12-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h: Include <dl-sysdep.h>.
+       (struct pthread): Move header.data.list to the back of the struct.
+       * sysdeps/i386/tls.h (tcbhead_t): Move list to the back of the struct.
+       (MULTIPLE_THREADS_OFFSET): Adjust offset.
+       (SYSINFO_OFFSEET): Likewise.
+
+2002-12-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h (USE_DL_SYSINFO):
+       Define.
+       (DL_SYSINFO_DEFAULT): Cast to uintptr_t to avoid warnings.
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h (NEED_DL_SYSINFO,
+       DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): Define.
+       (USE_DL_SYSINFO): Undef.
+
+2002-12-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests-reverse): Use $(objpfx)../libc.so instead of
+       $(common-objpfx)libc.so.
+       * tst-cancel4.c (tf_write, tf_writev): Increase buf sizes so that
+       it is bigger than pipe buffer size even on arches with bigger
+       page size.
+       (tf_usleep): Cast usleep argument to useconds_t to avoid warnings.
+
+2002-12-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S: Implement
+       correct errno access for case that USE___THREAD is not defined.
+
+2002-12-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Add missing #endif.
+       Patch by Marijn Ros <marijn@mad.scientist.com>.
+
+2002-12-22  Roland McGrath  <roland@redhat.com>
+
+       * Makefile (omit-deps): Add $(unix-syscalls:%=ptw-%).
+
+2002-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/bits/stdio-lock.h (_IO_lock_inexpensive): Define.
+
+2002-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Don't define
+       NEED_DL_SYSINFO since no processor < i686 had the sysenter opcode.
+       * sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h: New file.
+
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S: Use ENTER_KERNEL instead
+       of int $0x80.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Add support for using
+       sysenter.
+       * sysdeps/unix/sysv/linux/i386/lowlevelsem.h: Likewise.
+
+       * sysdeps/i386/tls.h: Unconditionally include <dl-sysdep.h>.
+
+       * allocatestack.c (allocate_stack) [NEED_DL_SYSINFO]: Set sysinfo
+       in new TCB.
+       * sysdeps/unix/sysv/linux/i386/createthread.c (create_thread): Check
+       that sysinfo is properly initialized.
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Define RTLD_PRIVATE_ERRNO
+       to 1 only for ld.so.
+
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Define
+       RTLD_CORRECT_DYNAMIC_WEAK.
+
+2002-12-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * forward.c (pthread_attr_init_2_0, pthread_attr_init_2_1):
+       Use return 0 as 6th argument to FORWARD4.
+       * pthread_equal.c: Include pthreadP.h instead of pthread.h.
+
+2002-12-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h (struct pthread) [NEED_DL_SYSINFO]: Add sysinfo member.
+       * sysdeps/i386/tls.h (tcbhead_t): Add sysinfo member.
+       Define SYSINFO_OFFSEET if NEED_DL_SYSINFO is defined.
+       (INIT_SYSINFO): New #define.
+       (TLS_TP_INIT): Use INIT_SYSINFO.
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+       At test to make sure SYSINFO_OFFSET value is correct.
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: New file.
+
+2002-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/flockfile.c (flockfile): Change into weak alias.
+       * sysdeps/unix/sysv/linux/raise.c (gsignal): Add weak alias to raise.
+       * Versions [libc: GLIBC_2.0]: Add pthread_attr_init.
+       [libpthread: GLIBC_2.1]: Remove __pthread_rwlock_init,
+       __pthread_rwlock_destroy, __pthread_rwlock_rdlock,
+       __pthread_rwlock_wrlock, __pthread_rwlock_unlock,
+       __pthread_rwlock_tryrdlock and __pthread_rwlock_trywrlock.
+
+2002-12-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Use ENTER_KERNEL
+       macro instead of using int $0x80 directly.
+
+       * sysdeps/pthread/bits/stdio-lock.h: New file.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S: New file.
+       * Makefile (routines): Add libc-lowlevelmutex.
+
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Remove
+       __i686.get_pc_thunk.dx.
+
+2002-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (libpthread-shared-only-routines): Add pt-allocrtsig.
+       (tests): Depend on $(objpfx)tst-cancel-wrappers.out.
+       ($(objpfx)tst-cancel-wrappers.out): New rule.
+       * tst-cancel-wrappers.sh: New test.
+       * tst-locale1.c: Include signal.h.
+       (uselocale): Test static linking of __libc_current_sigrt*.
+
+2002-12-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-cancel6.
+       * tst-cancel6.c: New file
+
+2002-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (SINGLE_THREAD_P):
+       Define meaningfully for assembler as well.
+       * pthreadP.h (struct pthread_functions): Remove
+       ptr_pthread_attr_init field.  Add ptr_pthread_attr_init_2_0
+       and ptr_pthread_attr_init_2_1 fields.
+       * init.c (pthread_functions): Initialize ptr_pthread_attr_init_2_0
+       and ptr_pthread_attr_init_2_1 instead of ptr_pthread_attr_init.
+       * forward.c (FORWARD4): Renamed from FORWARD3. Add export argument.
+       (FORWARD3): Define using FORWARD4.
+       (pthread_attr_init): Provide both @GLIBC_2.0 and @@GLIBC_2.1
+       versions.
+       * pt-system.c: Remove duplicate stdlib.h include.
+
+2002-12-16  Ulrich Drepper  <drepper@redhat.com>
+
+       * sem_init.c: Define sem_init@GLIBC_2.0.
+       * sem_destroy.c: Define sem_destroy@GLIBC_2.0.
+       * sem_getvalue.c: Define sem_getvalue@GLIBC_2.0.
+
+       * flockfile.c: Moved to...
+       * sysdeps/pthread/flockfile.c: ...here.  New file.
+       * funlockfile.c: Moved to...
+       * sysdeps/pthread/funlockfile.c: ...here.  New file.
+       * ftrylockfile.c: Moved to...
+       * sysdeps/pthread/ftrylockfile.c: ...here.  New file.
+
+2002-12-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * libc-cancellation.c: Guard both function with
+       #if !defined NOT_IN_libc.
+       * Makefile (libpthread-routines): Use ptw-, not pt- prefix for the
+       automatically provided pthread wrappers.
+       * pthreadP.h (LIBC_CANCEL_ASYNC, LIBC_CANCEL_RESET): Define to
+       CANCEL_* if IS_IN_libpthread and to dummy versions if not in libc
+       nor in libpthread.
+       * pt-open.c: Removed.
+       * pt-fcntl.c: Removed.
+       * pt-fsync.c: Removed.
+       * pt-lseek.c: Removed.
+       * pt-msgrcv.c: Removed.
+       * pt-msgsnd.c: Removed.
+       * pt-msync.c: Removed.
+       * pt-nanosleep.c: Removed.
+       * pt-open64.c: Removed.
+       * pt-pause.c: Removed.
+       * pt-pread.c: Removed.
+       * pt-pread64.c: Removed.
+       * pt-pwrite.c: Removed.
+       * pt-pwrite64.c: Removed.
+       * pt-read.c: Removed.
+       * pt-recv.c: Removed.
+       * pt-recvfrom.c: Removed.
+       * pt-recvmsg.c: Removed.
+       * pt-send.c: Removed.
+       * pt-sendto.c: Removed.
+       * pt-sigtimedwait.c: Removed.
+       * pt-sigwait.c: Removed.
+       * pt-wait.c: Removed.
+       * pt-waitpid.c: Removed.
+       * pt-write.c: Removed.
+       * pt-accept.c: Removed.
+       * pt-close.c: Removed.
+       * pt-connect.c: Removed.
+       * pt-lseek64.c: Removed.
+       * pt-sendmsg.c: Removed.
+       * pt-tcdrain.c: Removed.
+
+2002-12-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (__pthread_initialize_minimal_internal): Renamed from
+       __pthread_initialize_minimal.  Make old name an alias.  This
+       converts a normal relocation into a relative relocation.
+
+       * pt-fcntl.c (__fcntl): Use fcntl64 syscall, not fcntl.
+
+       * Versions [libpthread: GLIBC_2.3.2]: Remove creat, poll, pselect,
+       readv, select, sigpause, sigsuspend, sigwaitinfo, waitid, writev.
+       * Makefile (libpthread-routines): Remove pt-creat, pt-poll,
+       pt-pselect, pt-readv, pt-select, pt-sigpause, pt-sigsuspend,
+       pt-sigwaitinfo, pt-waitid, and pt-writev.
+       * pt-creat.c: Removed.
+       * pt-poll.c: Removed.
+       * pt-pselect.c: Removed.
+       * pt-readv.c: Removed.
+       * pt-select.c: Removed.
+       * pt-sigpause.c: Removed.
+       * pt-sigsuspend.c: Removed.
+       * pt-sigwaitinfo.c: Removed.
+       * pt-waitid.c: Removed.
+       * pt-writev.c: Removed.
+
+       * init.c (pthread_functions): New variable.
+       (__pthread_initialize_minimal): Pass pointer to pthread_functions
+       (or NULL) to __libc_pthread_init.
+       * forward.c: Rewrite to use __libc:pthread_functions array to get
+       function addresses.
+       * sysdeps/unix/sysv/linux/fork.h: Remove __libc_pthread_init
+       prototype.
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+       Take new parameter.  Copy content of variable pointed to by it
+       to __libc_pthread_init.
+
+       * pthreadP.h (struct pthread_functions): New type.
+       (__libc_pthread_init): Declare.
+
+       * pthread_attr_destroy.c: Add namespace protected alias.
+       * pthread_attr_getdetachstate.c: Likewise.
+       * pthread_attr_getinheritsched.c: Likewise.
+       * pthread_attr_getschedparam.c: Likewise.
+       * pthread_attr_getschedpolicy.c: Likewise.
+       * pthread_attr_getscope.c: Likewise.
+       * pthread_attr_setdetachstate.c: Likewise.
+       * pthread_attr_setinheritsched.c: Likewise.
+       * pthread_attr_setschedparam.c: Likewise.
+       * pthread_attr_setschedpolicy.c: Likewise.
+       * pthread_attr_setscope.c: Likewise.
+       * pthread_cond_broadcast.c: Likewise.
+       * pthread_cond_destroy.c: Likewise.
+       * pthread_cond_init.c: Likewise.
+       * pthread_cond_signal.c: Likewise.
+       * pthread_cond_wait.c: Likewise.
+       * pthread_condattr_destroy.c: Likewise.
+       * pthread_condattr_init.c: Likewise.
+       * pthread_equal.c: Likewise.
+       * pthread_exit.c: Likewise.
+       * pthread_getschedparam.c: Likewise.
+       * pthread_self.c: Likewise.
+       * pthread_setcancelstate.c: Likewise.
+       * pthread_setschedparam.c: Likewise.
+       * pthread_mutex_destroy.c: Likewise.
+       * pthread_mutex_init.c: Likewise.
+       * pthreadP.h: Add prototypes for the aliases.
+
+       * sysdeps/unix/sysv/linux/i386/createthread.c (create_thread): Set
+       multiple_threads member in correct TCB to 1.
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Define
+       SINGLE_THREAD_P.  If in libc or libpthread examine multiple_thread
+       member of thread decriptor, otherwise return unconditionally 1.
+
+2002-12-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/pt-socket.S: Changes folded into the
+       regular Linux version.  Remove file.
+       * sysdeps/unix/sysv/linux/connect.S: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/llseek.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/msgrcv.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/msgsnd.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/open64.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/poll.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/pread.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/pread64.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/pselect.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/pwrite.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/pwrite64.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/readv.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/recv.S: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/recvfrom.S: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/recvmsg.S: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/send.S: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/sendmsg.S: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/sendto.S: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/sigpause.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/sigsuspend.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/sigtimedwait.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/sigwait.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/system.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/tcdrain.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/wait.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/waitid.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/waitpid.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/writev.c: Likewise.  Remove file.
+       * sysdeps/unix/sysv/linux/i386/fcntl.c: Likewise.  Remove file.
+
+2002-12-14  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: New file.
+       * sysdeps/unix/sysv/linux/open.c: Removed.
+       * sysdeps/unix/sysv/linux/fsync.c: Removed.
+       * sysdeps/unix/sysv/linux/lseek.c: Removed.
+       * sysdeps/unix/sysv/linux/msync.c: Removed.
+       * sysdeps/unix/sysv/linux/read.c: Removed.
+       * sysdeps/unix/sysv/linux/close.c: Removed.
+       * sysdeps/unix/sysv/linux/creat.c: Removed.
+       * sysdeps/unix/sysv/linux/nanosleep.c: Removed.
+       * sysdeps/unix/sysv/linux/pause.c: Removed.
+       * sysdeps/unix/sysv/linux/select.c: Removed.
+       * sysdeps/unix/sysv/linux/write.c: Removed.
+
+2002-12-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/pt-socket.S: Check multiple_threads
+       element in TCB to see whether locking is needed.
+
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c: Check that
+       MULTIPLE_THREADS_OFFSET value is correct.
+
+       * sysdeps/unix/sysv/linux/close.c: New file.
+       * sysdeps/unix/sysv/linux/connect.S: New file.
+       * sysdeps/unix/sysv/linux/creat.c: New file.
+       * sysdeps/unix/sysv/linux/fsync.c: New file.
+       * sysdeps/unix/sysv/linux/llseek.c: New file.
+       * sysdeps/unix/sysv/linux/lseek.c: New file.
+       * sysdeps/unix/sysv/linux/msgrcv.c: New file.
+       * sysdeps/unix/sysv/linux/msgsnd.c: New file.
+       * sysdeps/unix/sysv/linux/msync.c: New file.
+       * sysdeps/unix/sysv/linux/nanosleep.c: New file.
+       * sysdeps/unix/sysv/linux/open.c: New file.
+       * sysdeps/unix/sysv/linux/open64.c: New file.
+       * sysdeps/unix/sysv/linux/pause.c: New file.
+       * sysdeps/unix/sysv/linux/poll.c: New file.
+       * sysdeps/unix/sysv/linux/pread.c: New file.
+       * sysdeps/unix/sysv/linux/pread64.c: New file.
+       * sysdeps/unix/sysv/linux/pselect.c: New file.
+       * sysdeps/unix/sysv/linux/pwrite.c: New file.
+       * sysdeps/unix/sysv/linux/pwrite64.c: New file.
+       * sysdeps/unix/sysv/linux/readv.c: New file.
+       * sysdeps/unix/sysv/linux/recv.S: New file.
+       * sysdeps/unix/sysv/linux/recvfrom.S: New file.
+       * sysdeps/unix/sysv/linux/recvmsg.S: New file.
+       * sysdeps/unix/sysv/linux/select.c: New file.
+       * sysdeps/unix/sysv/linux/send.S: New file.
+       * sysdeps/unix/sysv/linux/sendmsg.S: New file.
+       * sysdeps/unix/sysv/linux/sendto.S: New file.
+       * sysdeps/unix/sysv/linux/sigpause.c: New file.
+       * sysdeps/unix/sysv/linux/sigsuspend.c: New file.
+       * sysdeps/unix/sysv/linux/sigtimedwait.c: New file.
+       * sysdeps/unix/sysv/linux/sigwait.c: New file.
+       * sysdeps/unix/sysv/linux/sigwaitinfo.c: New file.
+       * sysdeps/unix/sysv/linux/system.c: New file.
+       * sysdeps/unix/sysv/linux/tcdrain.c: New file.
+       * sysdeps/unix/sysv/linux/wait.c: New file.
+       * sysdeps/unix/sysv/linux/waitid.c: New file.
+       * sysdeps/unix/sysv/linux/waitpid.c: New file.
+       * sysdeps/unix/sysv/linux/writev.c: New file.
+       * sysdeps/unix/sysv/linux/i386/fcntl.c: New file.
+
+       * pt-readv.c: Fix comment.
+
+2002-12-14  Jakub Jelinek  <jakub@redhat.com>
+
+       * tst-cleanup1.c: Include stdlib.h.
+
+       * tst-cancel5.c: New test.
+       * Makefile (tests): Add tst-cancel5.
+       (tst-cancel5): Link against libc.so libpthread.so in that order.
+
+2002-12-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * forward.c (test_loaded): Prevent recursive calls.
+
+       * Makefile (routines): Add libc-cancellation.
+       * libc-cancellation.c: New file.
+       * descr.h (struct pthread): Add multiple_threads field.
+       * allocatestack.c (allocate_stack): Initialize multiple_header field of
+       new thread descriptor to 1.
+       * sysdeps/unix/sysv/linux/i386/createthread.c (create_thread):
+       Initialize multiple_thread field after successful thread creation.
+       * cancellation.c (__do_cancel): Move to pthreadP.h.
+       (__pthread_enable_asynccancel): Remove parameter from __do_cancel call.
+       (__pthread_disable_asynccancel): Add internal_function attribute.
+       * init.c (sigcancel_handler): Remove parameter from __do_cancel call.
+       * pthread_setcancelstate.c: Likewise.
+       * pthread_setcanceltype.c: Likewise.
+       * pthread_exit.c: Likewise.
+       * pthreadP.h (CANCELLATION_P): Likewise.
+       (__do_cancel): Define as static inline.
+       (LIBC_CANCEL_ASYNC, LIBC_CANCEL_RESET): New #defines.
+       (__libc_enable_asynccancel, __libc_disable_asynccancel): New
+       declarations.
+       * sysdeps/i386/tls.h (tcbhead_t): Add list and multiple_threads
+       fields.  Define MULTIPLE_THREADS_OFFSET.
+       * sysdeps/pthread/bits/libc-lock.h: Remove __libc_locking_needed
+       declaration.
+       * sysdeps/unix/sysv/linux/accept.S: New file.
+       * sysdeps/unix/sysv/linux/read.c: New file.
+       * sysdeps/unix/sysv/linux/write.c: New file.
+       * sysdeps/unix/sysv/linux/i386/pt-socket.S: New file.
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c: Remove definition and
+       initialization of __libc_locking_needed.
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Don't use
+       __libc_locking_needed, use multiple_threads field in TCB.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
+
+2002-12-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S: Use i486
+       version.
+       * sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S: Likewise.
+
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Correct
+       access to __libc_locking_needed for PIC.
+
+2002-12-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_locking_needed): Only
+       declare for libc.so.
+       (__libc_lock_init, __libc_lock_init_recursive): Change into comma
+       expression.
+       (__libc_lock_lock): Put into statement expression.
+       (__libc_lock_unlock): Remove trailing semicolon.
+       * sysdeps/unix/sysv/linux/fork.h (__libc_pthread_init): Fix typo.
+
+2002-12-12  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Use asm operand with
+       "m" constraint to refer to __libc_locking_needed.  Declare it here.
+
+2002-12-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/fork-gen.c: Renamed to...
+       * sysdeps/unix/sysv/linux/libc_pthread_init.c: ...this.
+       Initialize __libc_locking_needed.
+       * init.c (__pthread_initialize_minimal): Call __libc_pthread_init
+       instead of __register_pthread_fork_handler.
+       * sysdeps/pthread/bits/libc-lock.h: Declare __libc_locking_needed.
+       * sysdeps/unix/sysv/linux/Makefile (sysdep_routimes): Replace
+       fork-gen with libc_pthread_init.
+       * sysdeps/unix/sysv/linux/Versions: Use __libc_pthread_init instead
+       of __register_pthread_fork_handler.
+       * sysdeps/unix/sysv/linux/fork.h: Declare __libc_pthread_init instead
+       of __register_pthread_fork_handler.
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Use
+       __libc_locking_needed to determine whether lock prefix can be avoided.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
+
+2002-12-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-cleanup1.
+       * tst-cleanup1.c: New file.
+       * cancellation.c (__cleanup_thread): Removed.
+       (__do_cancel): Remove call to __cleanup_thread.
+       * pthreadP.h: Remove __cleanup_thread prorotype.
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_cleanup_region_start):
+       Remember function and argument even if cancellation handler
+       function is not available.
+       (__libc_cleanup_region_end): Execute registered function directly if
+       pthread functions are not available.
+       (__libc_cleanup_end): Likewise.
+
+       * init.c (__pthread_initialize_minimal): Fix initialization in
+       static lib by preventing gcc from being too clever.
+
+2002-12-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * init.c (__pthread_initialize_minimal): Remove unneccesary
+       sigaddset call.
+
+       * Makefile (tests): We can run tst-locale2 now.
+
+2002-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * Versions: Remove duplicated sigwait entry.
+
+2002-12-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h: Enable pthread_cleanup_{push,pop} optimizations only
+       inside libpthread.
+
+       * pt-fcntl.c (__fcntl): Initialize oldtype to avoid warning.
+
+       * pthreadP.h: Declare __pthread_enable_asynccancel and
+       __pthread_disable_asynccancel.
+       (CANCEL_ASYNC): Use __pthread_enable_asynccancel.
+       (CANCEL_RESET): Use __pthread_disable_asynccancel.
+       * cancellation.c (__pthread_enable_asynccancel): New function.
+       (__pthread_disable_asynccancel): New function.
+       * pt-accept.c: Adjust for CANCEL_ASYNC and CANCEL_RESET change.
+       * pt-close.c: Likewise.
+       * pt-connect.c: Likewise.
+       * pt-creat.c: Likewise.
+       * pt-fcntl.c: Likewise.
+       * pt-fsync.c: Likewise.
+       * pt-lseek.c: Likewise.
+       * pt-lseek64.c: Likewise.
+       * pt-msgrcv.c: Likewise.
+       * pt-msgsnd.c: Likewise.
+       * pt-msync.c: Likewise.
+       * pt-nanosleep.c: Likewise.
+       * pt-open.c: Likewise.
+       * pt-open64.c: Likewise.
+       * pt-pause.c: Likewise.
+       * pt-poll.c: Likewise.
+       * pt-pread.c: Likewise.
+       * pt-pread64.c: Likewise.
+       * pt-pselect.c: Likewise.
+       * pt-pwrite.c: Likewise.
+       * pt-pwrite64.c: Likewise.
+       * pt-read.c: Likewise.
+       * pt-readv.c: Likewise.
+       * pt-recv.c: Likewise.
+       * pt-recvfrom.c: Likewise.
+       * pt-recvmsg.c: Likewise.
+       * pt-select.c: Likewise.
+       * pt-send.c: Likewise.
+       * pt-sendmsg.c: Likewise.
+       * pt-sendto.c: Likewise.
+       * pt-sigpause.c: Likewise.
+       * pt-sigsuspend.c: Likewise.
+       * pt-sigtimedwait.c: Likewise.
+       * pt-sigwait.c: Likewise.
+       * pt-sigwaitinfo.c: Likewise.
+       * pt-system.c: Likewise.
+       * pt-tcdrain.c: Likewise.
+       * pt-wait.c: Likewise.
+       * pt-waitid.c: Likewise.
+       * pt-waitpid.c: Likewise.
+       * pt-write.c: Likewise.
+       * pt-writev.c: Likewise.
+       * pthread_join.c: Likewise.
+       * pthread_timedjoin.c: Likewise.
+
+       * pt-sigpause.c (sigsuspend): Call __sigsuspend.
+       (__xpg_sigpause): New function.
+       * Versions (libpthread:GLIBC_2.3.2): Add __xpg_sigpause.
+
+2002-12-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (CFLAGS-ftrylockfile.c): Add -D_IO_MTSAFE_IO.
+
+       * cleanup.c: Move declarations of _GI_pthread_cleanup_push and
+       _GI_pthread_cleanup_pop to pthreadP.h.
+
+       * ftrylockfile.c: Use _IO_lock_trylock instead of
+       pthread_mutex_trylock.
+
+       * pthreadP.h (CANCEL_ASYNC): Use __pthread_setcanceltype.
+       (CANCEL_RESET): Likewise.
+       (__pthread_setcanceltype_): Declare.
+       (__pthread_mutex_lock_internal): Declare.
+       (__pthread_mutex_unlock_internal): Declare.
+       (__pthread_once_internal): Declare.
+       (pthread_cleanup_push): Redefine using _GI_pthread_cleanup_push.
+       (pthread_cleanup_pop): Redefine using _GI_pthread_cleanup_pop.
+
+       * pthread_cond_timedwait.c: Use INTUSE is calls to pthread_mutex_lock
+       and pthread_mutex_unlock.
+       * pthread_cond_wait.c: Likewise.
+       * pthread_mutex_lock.c: Use INTDEF to define alias if needed.
+       * pthread_mutex_unlock.c: Likewise.
+
+       * pthread_setcanceltype.c: Add additional alias
+       __pthread_setcanceltype.
+
+       * sem_unlink.c (sem_unlink): Use __pthread_once with INTDEF.
+       * sem_open.c (sem_open): Likewise.
+       Use __libc_open, __libc_write, and __libc_close instead of
+       open, write, and close respectively.
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_lock_trylock_internal):
+       Rewrite as statement expression since it must return a value.
+
+       * pthread_cancel.c: Use __pthread_kill instead of pthread_kill.
+       * sysdeps/unix/sysv/linux/pthread_kill.c: Define additional alias
+       __pthread_kill.
+
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S: Define additional
+       alias __pthread_once_internal.
+
+       * sysdeps/unix/sysv/linux/raise.c: Use libc_hidden_def for raise.
+
+2002-12-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-stdio1 and tst-stdio2.
+       * tst-stdio1.c: New file.
+       * tst-stdio2.c: New file.
+
+       * init.c (__pthread_initialize_minimal): Correct INIT_LIST_HEAD use.
+
+       * Makefile (tests): Comment out tst-locale2 for now.
+       (CFLAGS-flockfile.c, CFLAGS-funlockfile.c): Define to -D_IO_MTSAFE_IO.
+
+       * sysdeps/unix/sysv/linux/Makefile: Define CFLAGS-fork.c to
+       -D_IO_MTSAFE_IO.
+       * sysdeps/unix/sysv/linux/fork.c: Include <bits/stdio-lock.h>.
+       Use _IO_lock_init instead of explicit assignment.
+
+       * sysdeps/pthread/bits/libc-lock.h: Define __rtld_lock_* macros.
+       Define __libc_lock_* and __libc_lock_recursive macros with
+       lowlevellock macros, not pthread mutexes.
+
+       * flockfile.c: Include <bits/stdio-lock.h>.  Use _IO_lock_lock instead
+       of pthread_mutex_lock.
+       * funlockfile.c: Include <bits/stdio-lock.h>.  Use _IO_lock_unlock
+       instead of pthread_mutex_unlock.
+
+2002-12-06  Roland McGrath  <roland@redhat.com>
+
+       * allocatestack.c (__stack_user): Use uninitialized defn.
+       * init.c (__pthread_initialize_minimal): Initialize it here.
+
+2002-12-05  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/i386/tls.h (TLS_INIT_TP): Make it return zero or an error
+       string.
+       * sysdeps/x86_64/tls.h (TLS_INIT_TP): Likewise.
+
+       * sysdeps/unix/sysv/linux/i386/createthread.c (create_thread): Add
+       missing & here too.
+
+2002-12-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Remove
+       lowlevellock.
+       * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S: New file.
+       * sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S: New file.
+       * sysdeps/pthread/bits/libc-lock.h: Use lowlevellock implementation
+       for __libc_lock_* macros.
+       * Makefile (routines): Add libc-lowlevellock.
+
+2002-10-09  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/pthread/bits/libc-lock.h (__libc_maybe_call): New macro.
+       Under [__PIC__], call the function via the pointer fetched for
+       comparison rather than a call by name that uses the PLT.
+       (__libc_lock_init, __libc_rwlock_init, __libc_lock_fini)
+       (__libc_rwlock_fini, __libc_lock_lock, __libc_rwlock_rdlock)
+       (__libc_rwlock_wrlock, __libc_lock_trylock, __libc_rwlock_tryrdlock)
+       (__libc_rwlock_trywrlock, __libc_lock_unlock, __libc_rwlock_unlock)
+       (__libc_key_create, __libc_getspecific, __libc_setspecific): Use it.
+
+2002-12-04  Roland McGrath  <roland@redhat.com>
+
+       * forward.c (pthread_self): Use FORWARD3 macro to correct return type.
+
+       * sysdeps/i386/td_ta_map_lwp2thr.c: Moved from ../nptl_db.
+       * sysdeps/generic/td_ta_map_lwp2thr.c: New file.
+
+       * pthread_create.c (start_thread): Add missing & on __nptl_last_event.
+
+2002-12-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Make pthread_t
+       a completely opaque, non-integer type.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+
+2002-12-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/i386/tls.h: Include stdlib.h.
+       * sysdeps/x86_64/tls.h: Likewise.
+
+2002-12-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-locale2.
+       (tests-static): Likewise.
+       * tst-locale2.c: New file.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Mark asms as
+       volatile and add memory clobbers to lock operations.
+
+2002-12-03  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/i686/bits/atomic.h: Use i486 version.
+       * sysdeps/i386/i486/bits/atomic.h: New file.
+       * sysdeps/i386/i586/bits/atomic.h: New file.
+       * sysdeps/i386/i686/pthread_spin_trylock.S: Define HAVE_CMOV and
+       include i486 version.
+       * sysdeps/i386/i486/pthread_spin_trylock.S: New file.
+       * sysdeps/i386/i586/pthread_spin_trylock.S: New file.
+       Patch by Marijn Ros <marijn@mad.scientist.com>.
+
+       * allocatestack.c (get_cached_stack): Don't crash if we first
+       found a stack with a larger size then needed.
+       Reported by Hui Huang <hui.huang@sun.com>.
+
+       * Makefile (tests): Add tst-sysconf.
+       * tst-sysconf.c: New file.
+
+       * sysdeps/unix/sysv/linux/bits/local_lim.h: Undefine
+       PTHREAD_THREADS_MAX.
+
+2002-12-02  Roland McGrath  <roland@redhat.com>
+
+       * pthreadP.h (__stack_user, __nptl_create_event, __nptl_death_event):
+       Declare using hidden_proto instead of attribute_hidden, so there are
+       non-.hidden static symbols for gdb to find.
+       (__pthread_keys): Likewise.
+       * events.c (__nptl_create_event, __nptl_death_event): Add hidden_def.
+       * allocatestack.c (__stack_user): Likewise.
+       * pthread_create.c (__pthread_keys): Likewise.
+       (__nptl_threads_events, __nptl_last_event): Make these static instead
+       of hidden.
+       * pthread_key_create.c (__pthread_pthread_keys_max,
+       __pthread_pthread_key_2ndlevel_size): Renamed from __linuxthreads_*.
+
+2002-12-02  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-locale1.  If buid-static is yes link
+       statically.
+       * tst-locale1.c: New file.
+
+       * pthread_cond_timedwait.c: Include <stdlib.h>.
+
+       * Makefile (tests): Add tst-fork2 and tst-fork3.
+       * tst-fork2.c: New file.
+       * tst-fork3.c: New file.
+
+2002-11-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: New file.
+
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define macros which
+       require it to 200112L.
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S: Use cmov
+       instruction only if HAVE_CMOV is defined.
+       * sysdeps/unix/sysv/linux/i386/i686/lowlevelrwlock.S: Define HAVE_CMOV.
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h: New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: New file.
+
+       * sysdeps/unix/sysv/linux/x86_64/pt-vfork.S: New file.
+
+2002-11-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/x86_64/bits/atomic.h: New file.
+
+       * sysdeps/i386/i686/bits/atomic.h: Fix asm syntax for 8- and
+       16-bit operations.
+
+       * sysdeps/unix/sysv/linux/raise.c (raise): Use INTERNAL_SYSCALL if
+       possible since gettid cannot fail.
+
+       * sysdeps/x86_64/pthreaddef.h: New file.
+
+       * sysdeps/i386/pthreaddef.h (gettid): Removed.
+
+       * sysdeps/x86_64/pthread_spin_init.c: New file.
+       * sysdeps/x86_64/pthread_spin_lock.c: New file.
+       * sysdeps/x86_64/pthread_spin_trylock.c: New file.
+       * sysdeps/x86_64/pthread_spin_unlock.c: New file.
+
+       * sysdeps/i386/i686/pthread_spin_trylock.S (pthread_spin_trylock):
+       Add missing lock prefix.  Minute optimization.
+
+       * tst-spin2.c (main): Also check successful trylock call.
+
+       * sysdeps/pthread/pthread_sigmask.c (pthread_sigmask): Use correct
+       syscall.  Fix typo in case INTERNAL_SYSCALL is not used.
+
+       * sysdeps/i386/pthread_spin_destroy.c: Moved to...
+       * sysdeps/pthread/pthread_spin_destroy.c: ...here.  New file.
+
+       * sysdeps/i386/pthread_sigmask.c: Removed.  Use the generic code.
+       * sysdeps/pthread/pthread_sigmask.c (pthread_sigmask): Return correct
+       value in case of an error.  Add support for INTERNAL_SYSCALL.
+
+       * sysdeps/i386/pthread_sigmask.c (pthread_sigmask): Return correct
+       value in case of an error.
+
+       * sysdeps/x86_64/tls.h: New file.
+
+2002-11-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/tls.h (THREAD_GETMEM_NC): Change interface.  It now
+       takes the array member name and the index as parameters.
+       (THREAD_SETMEM_NC): Likewise.
+       * pthread_getspecific.c: Use new THREAD_GETMEM_NC interface.
+       * pthread_setspecific.c: Use new THREAD_GETMEM_NC and THREAD_SETMEM_NC
+       interfaces.
+
+       * sysdeps/i386/tls.h (THREAD_SETMEM): Use size of member element
+       to decide which code to use.
+       (THREAD_SETMEM_NC): Likewise.
+
+       * allocatestack.c (queue_stack): Don't remove stack from list here.
+       Do it in the caller.  Correct condition to prematurely terminate
+       loop to free stacks.
+       (__deallocate_stack): Remove stack from list here.
+
+2002-11-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-stack1.
+       * tst-stack1.c: New file.
+
+       * allocatestack.c (allocate_stack): Initialize the TCB on a user
+       provided stack.
+
+       * pthread_attr_getstack.c: Return bottom of the thread area.
+
+2002-11-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (libpthread-routines): Add pt-allocrtsig and
+       pthread_kill_other_threads.
+       * pt-allocrtsig.c: New file.
+       * pthread_kill_other_threads.c: New file.
+       * sysdeps/unix/sysv/linux/allocrtsig.c: Add additional aliases for
+       all three functions.
+       * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Remove
+       allocrtsig.
+       * sysdeps/unix/sysv/linux/Versions (libc:GLIBC_PRIVATE): Export
+       __libc_current_sigrtmin_private, __libc_current_sigrtmax_private,
+       and __libc_allocate_rtsig_private.
+       * Versions (libpthread): Export pthread_kill_other_threads_np,
+       __libc_current_sigrtmin, and __libc_current_sigrtmax.
+
+2002-11-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * allocatestack.c (allocate_stack): stackaddr in attribute points to
+       the end of the stack.  Adjust computations.
+       When mprotect call fails dequeue stack and free it.
+       * pthread_attr_setstack.c: Store top of the stack in stackaddr
+       attribute.
+       * pthread_getattr_np.c: Likewise.
+
+       * descr.h (IS_DETACHED): Add some more parenthesis to prevent
+       surprises.
+
+2002-11-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/pthread/pthread.h (pthread_self): __THROW must come before
+       attribute definitions.  Patch by Luca Barbieri <ldb@ldb.ods.org>.
+
+2002-11-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_getspecific.c: Optimize access to first 2nd-level array.
+       * pthread_setspecific.c: Likewise.
+
+2002-11-21  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/createthread.c: Remove CLONE_ flags
+       definitions.  Get them from the official place.
+       * sysdeps/unix/sysv/linux/i386/fork.c: Likewise.
+
+       * sysdeps/unix/sysv/linux/i386/createthread.c: Update CLONE_* flags.
+       Use new CLONE_ flags in clone() calls.
+
+       * sysdeps/unix/sysv/linux/fork.c: Use ARCH_FORK to actually fork.
+       * sysdeps/unix/sysv/linux/i386/fork.c: New file.
+
+       * Versions: Add pthread_* functions for libc.
+       * forward.c: New file.
+
+       * sysdeps/pthread/Makefile (libpthread-sysdeps_routines): Add
+       errno-loc.
+       * herrno.c: New file.
+       * res.c: New file.
+
+       * Makefile (libpthread-routines): Remove sem_post, sem_wait,
+       sem_trywait, and sem_timedwait.  Add herrno and res.
+       * sem_init.c: Don't initialize lock and waiters members.
+       * sem_open.c: Likewise.
+       * sem_post.c: Removed.
+       * sem_wait.c: Removed.
+       * sem_trywait.c: Removed.
+       * sem_timedwait.c: Removed.
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S: Complete rewrite.
+       Includes full implementations of sem_post, sem_wait, sem_trywait,
+       and sem_timedwait.
+       * sysdeps/unix/sysv/linux/i386/lowlevelsem.h (lll_sem_post): Adjust
+       for new implementation.
+       * sysdeps/unix/sysv/linux/internaltypes.h (struct sem): Remove lock
+       and waiters fields.
+
+       * tst-sem3.c: Improve error message.
+       * tst-signal3.c: Likewise.
+
+       * init.c (__pthread_initialize_minimal): Use set_tid_address syscall
+       to tell the kernel about the termination futex and to initialize tid
+       member.  Don't initialize main_thread.
+       * descr.h (struct pthread): Remove main_thread member.
+       * cancelllation.c (__do_cancel): Remove code handling main thread.
+       The main thread is not special anymore.
+
+       * allocatestack.c (__reclaim_stacks): Mark stacks as unused.  Add
+       size of the stacks to stack_cache_actsize.
+
+       * pt-readv.c: Add missing "defined".
+       * pt-sigwait.c: Likewise.
+       * pt-writev.c: Likewise.
+
+2002-11-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * Versions: Export __connect from libpthread.
+       Patch by Luca Barbieri <ldb@ldb.ods.org>.
+
+       * Makefile (libpthread-routines): Add pt-raise.
+       * sysdeps/unix/sysv/linux/raise.c: New file.
+       * sysdeps/unix/sysv/linux/pt-raise.c: New file.
+       * sysdeps/generic/pt-raise.c: New file.
+
+       * pthread_cond_init.c: Initialize all data elements of the condvar
+       structure.  Patch by Luca Barbieri <ldb@ldb.ods.org>.
+
+       * pthread_attr_init.c: Actually implement 2.0 compatibility version.
+       * pthread_create.c: Likewise.
+
+       * Makefile (tests): Add tst-key1, tst-key2, tst-key3.
+       * tst-key1.c: New file.
+       * tst-key2.c: New file.
+       * tst-key3.c: New file.
+
+       * Versions: Export pthread_detach for version GLIBC_2.0.
+       Reported by Saurabh Desai <sdesai@austin.ibm.com>.
+
+2002-11-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_key_create.c: Terminate search after an unused key was found.
+       Patch by Luca Barbieri <ldb@ldb.ods.org>.
+
+       * sysdeps/unix/sysv/linux/i386/pthread_once.S: Return zero.
+       Patch by Luca Barbieri <ldb@ldb.ods.org>.
+
+2002-10-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S: Use slow generic
+       dynamic lookup for errno in PIC.
+
+       * allocatestack.c (get_cached_stack): Rearrange code slightly to
+       release the stack lock as soon as possible.
+       Call _dl_allocate_tls_init for TCB from the cache to re-initialize
+       the static TLS block.
+       (allocate_stack): Call _dl_allocate_tls_init for user-provided stack.
+
+       * cancellation.c: Renamed from cancelation.c.
+       * Makefile: Adjust accordingly.
+       * pthreadP.h (CANCELLATION_P): Renamed from CANCELATION_P.
+       * cleanup_defer.c: Use CANCELLATION_P.
+       * pthread_testcancel.c: Likewise.
+       * descr.h: Fix spelling in comments.
+       * init.c: Likewise.
+       * pthread_getattr_np.c: Likewise.
+       * pthread_getschedparam.c: Likewise.
+       * pthread_setschedparam.c: Likewise.
+       * Versions: Likewise.
+
+       * pt-pselect.c: New file.
+       * Makefile (libpthread-routines): Add pt-pselect.
+       * Versions: Add pselect.
+
+       * tst-cancel4.c: New file.
+       * Makefile (tests): Add tst-cancel4.
+
+2002-10-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_mutex_lock.c: Always record lock ownership.
+       * pthread_mutex_timedlock.c: Likewise.
+       * pthread_mutex_trylock.c: Likewise.
+
+       * pt-readv.c: New file.
+       * pt-writev.c: New file.
+       * pt-creat.c: New file.
+       * pt-msgrcv.c: New file.
+       * pt-msgsnd.c: New file.
+       * pt-poll.c: New file.
+       * pt-select.c: New file.
+       * pt-sigpause.c: New file.
+       * pt-sigsuspend.c: New file.
+       * pt-sigwait.c: New file.
+       * pt-sigwaitinfo.c: New file.
+       * pt-waitid.c: New file.
+       * Makefile (libpthread-routines): Add pt-readv, pt-writev, pt-creat,
+       pt-msgrcv, pt-msgsnd, pt-poll, pt-select, pt-sigpause, pt-sigsuspend,
+       pt-sigwait, pt-sigwaitinfo, and pt-waitid.
+       * Versions: Add all the new functions.
+
+       * tst-exit1.c: New file.
+       * Makefile (tests): Add tst-exit1.
+
+       * sem_timedwait.c: Minor optimization for more optimal fastpath.
+
+2002-10-08  Ulrich Drepper  <drepper@redhat.com>
+
+       * pt-fcntl.c: Only enable asynchronous cancellation for F_SETLKW.
+
+       * pthread_join.c: Enable asynchronous cancellation around lll_wait_tid
+       call.  pthread_join is an official cancellation point.
+       * pthread_timedjoin.c: Likewise.
+
+       * pthread_cond_wait.c: Revert order in which internal lock are dropped
+       and the condvar's mutex are retrieved.
+       * pthread_cond_timedwait.c: Likewise.
+       Reported by dice@saros.East.Sun.COM.
+
+2002-10-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h: Cut out all type definitions and move them...
+       * sysdeps/unix/sysv/linux/internaltypes.h: ...here.  New file.
+       * pthreadP.h: Include <internaltypes.h>.
+
+       * sysdeps/unix/sysv/linux/i386/lowlevelsem.h (lll_sem_post): Little
+       performance tweaks.
+
+       * sem_trywait.c: Shuffle #includes around to get right order.
+       * sem_timedwait.c: Likewise.
+       * sem_post.c: Likewise.
+       * sem_wait.c: Likewise.
+
+       * nptl 0.3 released.
+
+       * Makefile (tests): Add tst-signal3.
+       * tst-signal3.c: New file.
+
+2002-10-05  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/lowlevelsem.h: Tell the compiler that
+       the asms modify the sem object.
+       (__lll_sem_timedwait): Now takes struct sem* as first parameter.
+
+       * sysdeps/unix/sysv/linux/i386/bits/semaphore.h (sem_t): Don't expose
+       the actual members.
+       * pthreadP.h (struct sem): New type.  Actual semaphore type.
+       * semaphoreP.h: Include pthreadP.h.
+       * sem_getvalue.c: Adjust to sem_t change.
+       * sem_init.c: Likewise.
+       * sem_open.c: Likewise.
+       * sem_post.c: Likewise.
+       * sem_timedwait.c: Likewise.
+       * sem_trywait.c: Likewise.
+       * sem_wait.c: Likewise.
+
+2002-10-04  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile (tests): Add tst-basic2, tst-exec1, tst-exec3, tst-exec3.
+       * tst-basic2.c: New file.
+       * tst-exec1.c: New file.
+       * tst-exec2.c: New file.
+       * tst-exec3.c: New file.
+
+       * tst-fork1.c: Remove extra */.
+
+       * nptl 0.2 released.  The API for IA-32 is complete.
diff --git a/libpthread/nptl/DESIGN-barrier.txt b/libpthread/nptl/DESIGN-barrier.txt
new file mode 100644 (file)
index 0000000..23463c6
--- /dev/null
@@ -0,0 +1,44 @@
+Barriers pseudocode
+===================
+
+    int pthread_barrier_wait(barrier_t *barrier);
+
+struct barrier_t {
+
+   unsigned int lock:
+         - internal mutex
+
+   unsigned int left;
+         - current barrier count, # of threads still needed.
+
+   unsigned int init_count;
+         - number of threads needed for the barrier to continue.
+
+   unsigned int curr_event;
+         - generation count
+}
+
+pthread_barrier_wait(barrier_t *barrier)
+{
+  unsigned int event;
+  result = 0;
+
+  lll_lock(barrier->lock);
+  if (!--barrier->left) {
+    barrier->curr_event++;
+    futex_wake(&barrier->curr_event, INT_MAX)
+
+    result = BARRIER_SERIAL_THREAD;
+  } else {
+    event = barrier->curr_event;
+    lll_unlock(barrier->lock);
+    do {
+      futex_wait(&barrier->curr_event, event)
+    } while (event == barrier->curr_event);
+  }
+
+  if (atomic_increment_val (barrier->left) == barrier->init_count)
+    lll_unlock(barrier->lock);
+
+  return result;
+}
diff --git a/libpthread/nptl/DESIGN-condvar.txt b/libpthread/nptl/DESIGN-condvar.txt
new file mode 100644 (file)
index 0000000..4845251
--- /dev/null
@@ -0,0 +1,134 @@
+Conditional Variable pseudocode.
+================================
+
+       int pthread_cond_timedwait (pthread_cond_t *cv, pthread_mutex_t *mutex);
+       int pthread_cond_signal    (pthread_cond_t *cv);
+       int pthread_cond_broadcast (pthread_cond_t *cv);
+
+struct pthread_cond_t {
+
+   unsigned int cond_lock;
+
+         internal mutex
+
+   uint64_t total_seq;
+
+     Total number of threads using the conditional variable.
+
+   uint64_t wakeup_seq;
+
+     sequence number for next wakeup.
+
+   uint64_t woken_seq;
+
+     sequence number of last woken thread.
+
+   uint32_t broadcast_seq;
+
+}
+
+
+struct cv_data {
+
+   pthread_cond_t *cv;
+
+   uint32_t bc_seq
+
+}
+
+
+
+cleanup_handler(cv_data)
+{
+  cv = cv_data->cv;
+  lll_lock(cv->lock);
+
+  if (cv_data->bc_seq == cv->broadcast_seq) {
+    ++cv->wakeup_seq;
+    ++cv->woken_seq;
+  }
+
+  /* make sure no signal gets lost.  */
+  FUTEX_WAKE(cv->wakeup_seq, ALL);
+
+  lll_unlock(cv->lock);
+}
+
+
+cond_timedwait(cv, mutex, timeout):
+{
+   lll_lock(cv->lock);
+   mutex_unlock(mutex);
+
+   cleanup_push
+
+   ++cv->total_seq;
+   val = seq =  cv->wakeup_seq;
+   cv_data.bc = cv->broadcast_seq;
+   cv_data.cv = cv;
+
+   while (1) {
+
+     lll_unlock(cv->lock);
+
+     enable_async(&cv_data);
+
+     ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);
+
+     restore_async
+
+     lll_lock(cv->lock);
+
+     if (bc != cv->broadcast_seq)
+       goto bc_out;
+
+     val = cv->wakeup_seq;
+
+     if (val != seq && cv->woken_seq != val) {
+       ret = 0;
+       break;
+     }
+
+     if (ret == TIMEDOUT) {
+       ++cv->wakeup_seq;
+       break;
+     }
+   }
+
+   ++cv->woken_seq;
+
+ bc_out:
+   lll_unlock(cv->lock);
+
+   cleanup_pop
+
+   mutex_lock(mutex);
+
+   return ret;
+}
+
+cond_signal(cv)
+{
+   lll_lock(cv->lock);
+
+   if (cv->total_seq > cv->wakeup_seq) {
+     ++cv->wakeup_seq;
+     FUTEX_WAKE(cv->wakeup_seq, 1);
+   }
+
+   lll_unlock(cv->lock);
+}
+
+cond_broadcast(cv)
+{
+   lll_lock(cv->lock);
+
+   if (cv->total_seq > cv->wakeup_seq) {
+     cv->wakeup_seq = cv->total_seq;
+     cv->woken_seq = cv->total_seq;
+     ++cv->broadcast_seq;
+     FUTEX_WAKE(cv->wakeup_seq, ALL);
+   }
+
+   lll_unlock(cv->lock);
+}
diff --git a/libpthread/nptl/DESIGN-rwlock.txt b/libpthread/nptl/DESIGN-rwlock.txt
new file mode 100644 (file)
index 0000000..810d1b8
--- /dev/null
@@ -0,0 +1,113 @@
+Reader Writer Locks pseudocode
+==============================
+
+       pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
+       pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
+       pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
+
+struct pthread_rwlock_t {
+
+   unsigned int lock:
+         - internal mutex
+
+   unsigned int writers_preferred;
+         - locking mode: 0 recursive, readers preferred
+                         1 nonrecursive, writers preferred
+
+   unsigned int readers;
+         - number of read-only references various threads have
+
+   pthread_t writer;
+         - descriptor of the writer or 0
+
+   unsigned int readers_wakeup;
+         - 'all readers should wake up' futex.
+
+   unsigned int writer_wakeup;
+         - 'one writer should wake up' futex.
+
+   unsigned int nr_readers_queued;
+         - number of readers queued up.
+
+   unsigned int nr_writers_queued;
+         - number of writers queued up.
+}
+
+pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+{
+  lll_lock(rwlock->lock);
+  for (;;) {
+    if (!rwlock->writer && (!rwlock->nr_writers_queued ||
+                                       !rwlock->writers_preferred))
+        break;
+
+    rwlock->nr_readers_queued++;
+    val = rwlock->readers_wakeup;
+    lll_unlock(rwlock->lock);
+
+    futex_wait(&rwlock->readers_wakeup, val)
+
+    lll_lock(rwlock->lock);
+    rwlock->nr_readers_queued--;
+  }
+  rwlock->readers++;
+  lll_unlock(rwlock->lock);
+}
+
+pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+{
+  int result = EBUSY;
+  lll_lock(rwlock->lock);
+  if (!rwlock->writer && (!rwlock->nr_writers_queued ||
+                                       !rwlock->writers_preferred))
+    rwlock->readers++;
+  lll_unlock(rwlock->lock);
+  return result;
+}
+
+pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+{
+  lll_lock(rwlock->lock);
+  for (;;) {
+    if (!rwlock->writer && !rwlock->readers)
+       break;
+
+    rwlock->nr_writers_queued++;
+    val = rwlock->writer_wakeup;
+    lll_unlock(rwlock->lock);
+
+    futex_wait(&rwlock->writer_wakeup, val);
+
+    lll_lock(rwlock->lock);
+    rwlock->nr_writers_queued--;
+  }
+  rwlock->writer = pthread_self();
+  lll_unlock(rwlock->lock);
+}
+
+pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+{
+  lll_lock(rwlock->lock);
+
+  if (rwlock->writer)
+    rwlock->writer = 0;
+  else
+    rwlock->readers--;
+
+  if (!rwlock->readers) {
+    if (rwlock->nr_writers_queued) {
+      ++rwlock->writer_wakeup;
+      lll_unlock(rwlock->lock);
+      futex_wake(&rwlock->writer_wakeup, 1);
+      return;
+    } else
+      if (rwlock->nr_readers_queued) {
+        ++rwlock->readers_wakeup;
+        lll_unlock(rwlock->lock);
+        futex_wake(&rwlock->readers_wakeup, MAX_INT);
+        return;
+      }
+  }
+
+  lll_unlock(rwlock->lock);
+}
diff --git a/libpthread/nptl/DESIGN-sem.txt b/libpthread/nptl/DESIGN-sem.txt
new file mode 100644 (file)
index 0000000..17eb0c1
--- /dev/null
@@ -0,0 +1,46 @@
+Semaphores pseudocode
+==============================
+
+       int sem_wait(sem_t * sem);
+       int sem_trywait(sem_t * sem);
+       int sem_post(sem_t * sem);
+       int sem_getvalue(sem_t * sem, int * sval);
+
+struct sem_t {
+
+   unsigned int count;
+         - current semaphore count, also used as a futex
+}
+
+sem_wait(sem_t *sem)
+{
+  for (;;) {
+
+    if (atomic_decrement_if_positive(sem->count))
+      break;
+
+    futex_wait(&sem->count, 0)
+  }
+}
+
+sem_post(sem_t *sem)
+{
+  n = atomic_increment(sem->count);
+  // Pass the new value of sem->count
+  futex_wake(&sem->count, n + 1);
+}
+
+sem_trywait(sem_t *sem)
+{
+  if (atomic_decrement_if_positive(sem->count)) {
+    return 0;
+  } else {
+    return EAGAIN;
+  }
+}
+
+sem_getvalue(sem_t *sem, int *sval)
+{
+  *sval = sem->count;
+  read_barrier();
+}
diff --git a/libpthread/nptl/Makefile b/libpthread/nptl/Makefile
new file mode 100644 (file)
index 0000000..4c3cf94
--- /dev/null
@@ -0,0 +1,592 @@
+# Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+#
+#      Sub-makefile for NPTL portion of the library.
+#
+subdir := nptl
+
+headers := pthread.h semaphore.h bits/semaphore.h
+
+extra-libs := libpthread
+extra-libs-others := $(extra-libs)
+install-lib-ldscripts := libpthread.so
+
+routines = alloca_cutoff forward libc-lowlevellock libc-cancellation
+shared-only-routines = forward
+
+libpthread-routines = init vars events version \
+                     pthread_create pthread_exit pthread_detach \
+                     pthread_join pthread_tryjoin pthread_timedjoin \
+                     pthread_self pthread_equal pthread_yield \
+                     pthread_getconcurrency pthread_setconcurrency \
+                     pthread_getschedparam pthread_setschedparam \
+                     pthread_setschedprio \
+                     pthread_attr_init pthread_attr_destroy \
+                     pthread_attr_getdetachstate pthread_attr_setdetachstate \
+                     pthread_attr_getguardsize pthread_attr_setguardsize \
+                     pthread_attr_getschedparam pthread_attr_setschedparam \
+                     pthread_attr_getschedpolicy pthread_attr_setschedpolicy \
+                     pthread_attr_getinheritsched \
+                     pthread_attr_setinheritsched \
+                     pthread_attr_getscope pthread_attr_setscope \
+                     pthread_attr_getstackaddr pthread_attr_setstackaddr \
+                     pthread_attr_getstacksize pthread_attr_setstacksize \
+                     pthread_attr_getstack pthread_attr_setstack \
+                     pthread_getattr_np \
+                     pthread_mutex_init pthread_mutex_destroy \
+                     pthread_mutex_lock pthread_mutex_trylock \
+                     pthread_mutex_timedlock pthread_mutex_unlock \
+                     pthread_mutexattr_init pthread_mutexattr_destroy \
+                     pthread_mutexattr_getpshared \
+                     pthread_mutexattr_setpshared \
+                     pthread_mutexattr_gettype pthread_mutexattr_settype \
+                     pthread_rwlock_init pthread_rwlock_destroy \
+                     pthread_rwlock_rdlock pthread_rwlock_timedrdlock \
+                     pthread_rwlock_wrlock pthread_rwlock_timedwrlock \
+                     pthread_rwlock_tryrdlock pthread_rwlock_trywrlock \
+                     pthread_rwlock_unlock \
+                     pthread_rwlockattr_init pthread_rwlockattr_destroy \
+                     pthread_rwlockattr_getpshared \
+                     pthread_rwlockattr_setpshared \
+                     pthread_rwlockattr_getkind_np \
+                     pthread_rwlockattr_setkind_np \
+                     pthread_cond_init pthread_cond_destroy \
+                     pthread_cond_wait pthread_cond_timedwait \
+                     pthread_cond_signal pthread_cond_broadcast \
+                     old_pthread_cond_init old_pthread_cond_destroy \
+                     old_pthread_cond_wait old_pthread_cond_timedwait \
+                     old_pthread_cond_signal old_pthread_cond_broadcast \
+                     pthread_condattr_init pthread_condattr_destroy \
+                     pthread_condattr_getpshared pthread_condattr_setpshared \
+                     pthread_condattr_getclock pthread_condattr_setclock \
+                     pthread_spin_init pthread_spin_destroy \
+                     pthread_spin_lock pthread_spin_trylock \
+                     pthread_spin_unlock \
+                     pthread_barrier_init pthread_barrier_destroy \
+                     pthread_barrier_wait \
+                     pthread_barrierattr_init pthread_barrierattr_destroy \
+                     pthread_barrierattr_getpshared \
+                     pthread_barrierattr_setpshared \
+                     pthread_key_create pthread_key_delete \
+                     pthread_getspecific pthread_setspecific \
+                     pthread_sigmask pthread_kill \
+                     pthread_cancel pthread_testcancel \
+                     pthread_setcancelstate pthread_setcanceltype \
+                     pthread_once \
+                     old_pthread_atfork pthread_atfork \
+                     pthread_getcpuclockid \
+                     pthread_clock_gettime pthread_clock_settime \
+                     sem_init sem_destroy \
+                     sem_open sem_close sem_unlink \
+                     sem_getvalue \
+                     sem_wait sem_trywait sem_timedwait sem_post \
+                     cleanup cleanup_defer cleanup_compat \
+                     cleanup_defer_compat unwind \
+                     pt-longjmp pt-cleanup\
+                     cancellation \
+                     lowlevellock \
+                     pt-vfork \
+                     ptw-write ptw-read ptw-close ptw-fcntl ptw-accept \
+                     ptw-connect ptw-recv ptw-recvfrom ptw-recvmsg ptw-send \
+                     ptw-sendmsg ptw-sendto ptw-fsync ptw-lseek ptw-llseek \
+                     ptw-msync ptw-nanosleep ptw-open ptw-open64 ptw-pause \
+                     ptw-pread ptw-pread64 ptw-pwrite ptw-pwrite64 \
+                     ptw-tcdrain ptw-wait ptw-waitpid ptw-msgrcv ptw-msgsnd \
+                     ptw-sigwait \
+                     pt-raise pt-system \
+                     flockfile ftrylockfile funlockfile \
+                     sigaction \
+                     herrno res pt-allocrtsig \
+                     pthread_kill_other_threads \
+                     pthread_getaffinity pthread_setaffinity \
+                     pthread_attr_getaffinity pthread_attr_setaffinity \
+                     cleanup_routine unwind-forcedunwind
+#                    pthread_setuid pthread_seteuid pthread_setreuid \
+#                    pthread_setresuid \
+#                    pthread_setgid pthread_setegid pthread_setregid \
+#                    pthread_setresgid
+
+libpthread-shared-only-routines = version pt-allocrtsig unwind-forcedunwind
+libpthread-static-only-routines = pthread_atfork
+
+CFLAGS-pthread_atfork.c = -DNOT_IN_libc
+
+# Since cancellation handling is in large parts handled using exceptions
+# we have to compile some files with exception handling enabled, some
+# even with asynchronous unwind tables.
+
+# init.c contains sigcancel_handler().
+CFLAGS-init.c = -fexceptions -fasynchronous-unwind-tables
+# The unwind code itself,
+CFLAGS-unwind.c = -fexceptions
+CFLAGS-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables
+
+# The following three functions must be async-cancel safe.
+CFLAGS-pthread_cancel.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pthread_setcancelstate.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pthread_setcanceltype.c = -fexceptions -fasynchronous-unwind-tables
+
+# These are internal functions which similar functionality as setcancelstate
+# and setcanceltype.
+CFLAGS-cancellation.c = -fasynchronous-unwind-tables
+CFLAGS-libc-cancellation.c = -fasynchronous-unwind-tables
+
+# Calling pthread_exit() must cause the registered cancel handlers to
+# be executed.  Therefore exceptions have to be thrown through this
+# function.
+CFLAGS-pthread_exit.c = -fexceptions
+
+# Among others, __pthread_unwind is forwarded.  This function must handle
+# exceptions.
+CFLAGS-forward.c = -fexceptions
+
+# The following are cancellation points.  Some of the functions can
+# block and therefore temporarily enable asynchronous cancellation.
+# Those must be compiled asynchronous unwind tables.
+CFLAGS-pthread_testcancel.c = -fexceptions
+CFLAGS-pthread_join.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pthread_timedjoin.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pthread_once.c = $(uses-callbacks) -fexceptions \
+                       -fasynchronous-unwind-tables
+CFLAGS-pthread_cond_wait.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pthread_cond_timedwait.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-sem_wait.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-sem_timedwait.c = -fexceptions -fasynchronous-unwind-tables
+
+# These are the function wrappers we have to duplicate here.
+CFLAGS-fcntl.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-lockf.c = -fexceptions
+CFLAGS-pread.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pread64.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pwrite.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pwrite64.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-wait.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-waitpid.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-sigwait.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-msgrcv.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-msgsnd.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-tcdrain.c = -fexceptions -fasynchronous-unwind-tables
+
+CFLAGS-pt-system.c = -fexceptions
+
+# Don't generate deps for calls with no sources.  See sysdeps/unix/Makefile.
+omit-deps = $(unix-syscalls:%=ptw-%)
+
+
+tests = tst-attr1 tst-attr2 tst-attr3 \
+       tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
+       tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \
+       tst-spin1 tst-spin2 tst-spin3 \
+       tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
+       tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
+       tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
+       tst-cond20 tst-cond21 \
+       tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
+       tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
+       tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
+       tst-once1 tst-once2 tst-once3 tst-once4 \
+       tst-key1 tst-key2 tst-key3 tst-key4 \
+       tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
+       tst-sem8 tst-sem9 \
+       tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
+       tst-align tst-align2 \
+       tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
+       tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
+       tst-raise1 \
+       tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 \
+       tst-detach1 \
+       tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \
+       tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 \
+       tst-tls1 tst-tls2 \
+       tst-fork1 tst-fork2 tst-fork3 tst-fork4 \
+       tst-atfork1 \
+       tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \
+       tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
+       tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
+       tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
+       tst-cancel21 tst-cancel22 tst-cancel23 \
+       tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
+       tst-flock1 tst-flock2 \
+       tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
+       tst-signal6 \
+       tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
+       tst-exit1 tst-exit2 tst-exit3 \
+       tst-stdio1 tst-stdio2 \
+       tst-stack1 tst-stack2 tst-stack3 \
+       tst-unload \
+       tst-dlsym1 \
+       tst-sysconf \
+       tst-locale1 tst-locale2 \
+       tst-umask1 \
+       tst-popen1 \
+       tst-clock1 \
+       tst-context1 \
+       tst-sched1 \
+       tst-backtrace1 \
+       tst-oddstacklimit \
+       tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
+       tst-getpid1 tst-getpid2
+xtests = tst-setuid1 tst-setuid1-static
+
+# Files which must not be linked with libpthread.
+tests-nolibpthread = tst-unload
+
+# This sets the stack resource limit to 1023kb, which is not a multiple
+# of the page size since every architecture's page size is > 1k.
+tst-oddstacklimit-ENV = ; ulimit -s 1023;
+
+distribute = eintr.c tst-cleanup4aux.c
+
+gen-as-const-headers = pthread-errnos.sym
+
+LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
+
+
+include ../Makeconfig
+
+ifeq ($(have-forced-unwind),yes)
+tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
+        tst-cancelx6 tst-cancelx7 tst-cancelx8 tst-cancelx9 tst-cancelx10 \
+        tst-cancelx11 tst-cancelx12 tst-cancelx13 tst-cancelx14 tst-cancelx15 \
+        tst-cancelx16 tst-cancelx17 tst-cancelx18 tst-cancelx20 tst-cancelx21 \
+        tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \
+        tst-oncex3 tst-oncex4
+endif
+ifeq ($(build-shared),yes)
+tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1 tst-fini1
+tests-nolibpthread += tst-fini1
+ifeq ($(have-z-execstack),yes)
+tests += tst-execstack
+endif
+endif
+
+modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
+               tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
+               tst-tls5modd tst-tls5mode tst-tls5modf \
+               tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod
+extra-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
+test-extras += $(modules-names)
+test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
+
+tst-atfork2mod.so-no-z-defs = yes
+tst-tls3mod.so-no-z-defs = yes
+tst-tls5mod.so-no-z-defs = yes
+tst-tls5moda.so-no-z-defs = yes
+tst-tls5modb.so-no-z-defs = yes
+tst-tls5modc.so-no-z-defs = yes
+tst-tls5modd.so-no-z-defs = yes
+tst-tls5mode.so-no-z-defs = yes
+tst-tls5modf.so-no-z-defs = yes
+
+$(test-modules): $(objpfx)%.so: $(objpfx)%.os $(common-objpfx)shlib.lds
+       $(build-module)
+
+ifeq ($(build-shared),yes)
+# Build all the modules even when not actually running test programs.
+tests: $(test-modules)
+endif
+
+ifeq ($(build-shared),yes)
+
+# Set the `multidir' variable by grabbing the variable from the compiler.
+# We do it once and save the result in a generated makefile.
+-include $(objpfx)multidir.mk
+$(objpfx)multidir.mk: $(common-objpfx)config.make
+       $(make-target-directory)
+       dir=`$(CC) $(CFLAGS) $(CPPFLAGS) -print-multi-directory`; \
+       echo "multidir := $$dir" > $@T
+       mv -f $@T $@
+
+crti-objs := crti.o
+crtn-objs := crtn.o
+ifneq (,$(patsubst .,,$(multidir)))
+generated-dirs := $(firstword $(subst /, , $(multidir)))
+crti-objs += $(multidir)/crti.o
+crtn-objs += $(multidir)/crtn.o
+omit-deps += $(multidir)/crti $(multidir)/crtn
+$(objpfx)$(multidir):
+       mkdir $@
+endif
+extra-objs += $(crti-objs) $(crtn-objs)
+omit-deps += crti crtn
+
+CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions $(fno-unit-at-a-time)
+endif
+
+CFLAGS-flockfile.c = -D_IO_MTSAFE_IO
+CFLAGS-ftrylockfile.c = -D_IO_MTSAFE_IO
+CFLAGS-funlockfile.c = -D_IO_MTSAFE_IO
+
+link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
+                   $(common-objpfx)libc.a
+
+ifeq ($(build-static),yes)
+tests-static += tst-locale1 tst-locale2
+xtests-static += tst-setuid1-static
+endif
+# These tests are linked with libc before libpthread
+tests-reverse += tst-cancel5 tst-cancel23 tst-vfork1x tst-vfork2x
+
+include ../Rules
+
+ifeq (yes,$(build-shared))
+# Make sure these things are built in the `make lib' pass so they can be used
+# to run programs during the `make others' pass.
+lib-noranlib: $(addprefix $(objpfx),$(extra-objs))
+
+# What we install as libpthread.so for programs to link against is in fact a
+# link script.  It contains references for the various libraries we need.
+# The libpthread.so object is not complete since some functions are only
+# defined in libpthread_nonshared.a.
+# We need to use absolute paths since otherwise local copies (if they exist)
+# of the files are taken by the linker.
+install: $(inst_libdir)/libpthread.so
+
+$(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
+                             $(objpfx)libpthread.so$(libpthread.so-version) \
+                             $(inst_libdir)/$(patsubst %,$(libtype.oS),\
+                                                       $(libprefix)pthread) \
+                             $(+force)
+       (echo '/* GNU ld script';\
+        echo '   Use the shared library, but some functions are only in';\
+        echo '   the static library, so try that secondarily.  */';\
+        cat $<; \
+        echo 'GROUP ( $(slibdir)/libpthread.so$(libpthread.so-version)' \
+             '$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)pthread)'\
+             ')' \
+       ) > $@.new
+       mv -f $@.new $@
+endif
+
+
+# 'pthread_self' is a simple memory or register load.  Setting up the
+# stack frame is more work than the actual operation.  Disable the
+# frame creation entirely.  This will help applications which call the
+# function frequently to get a thread-specific handle.
+CFLAGS-pthread_self.os += -fomit-frame-pointer
+
+# Run the cancellation and cleanup tests also for the modern, exception-based
+# implementation.  For this we have to pass the -fexceptions parameter.
+CFLAGS-tst-cancelx2.c += -fexceptions
+CFLAGS-tst-cancelx3.c += -fexceptions
+CFLAGS-tst-cancelx4.c += -fexceptions
+CFLAGS-tst-cancelx5.c += -fexceptions
+CFLAGS-tst-cancelx6.c += -fexceptions
+CFLAGS-tst-cancelx7.c += -fexceptions
+CFLAGS-tst-cancelx8.c += -fexceptions
+CFLAGS-tst-cancelx9.c += -fexceptions
+CFLAGS-tst-cancelx10.c += -fexceptions
+CFLAGS-tst-cancelx11.c += -fexceptions
+CFLAGS-tst-cancelx12.c += -fexceptions
+CFLAGS-tst-cancelx13.c += -fexceptions
+CFLAGS-tst-cancelx14.c += -fexceptions
+CFLAGS-tst-cancelx15.c += -fexceptions
+CFLAGS-tst-cancelx16.c += -fexceptions
+CFLAGS-tst-cancelx17.c += -fexceptions
+CFLAGS-tst-cancelx18.c += -fexceptions
+CFLAGS-tst-cancelx20.c += -fexceptions -fasynchronous-unwind-tables
+CFLAGS-tst-cancelx21.c += -fexceptions -fasynchronous-unwind-tables
+CFLAGS-tst-cleanupx0.c += -fexceptions -fasynchronous-unwind-tables
+CFLAGS-tst-cleanupx1.c += -fexceptions -fasynchronous-unwind-tables
+CFLAGS-tst-cleanupx2.c += -fexceptions
+CFLAGS-tst-cleanupx3.c += -fexceptions
+CFLAGS-tst-cleanupx4.c += -fexceptions
+CFLAGS-tst-oncex3.c += -fexceptions
+CFLAGS-tst-oncex4.c += -fexceptions
+CFLAGS-tst-align.c += $(stack-align-test-flags)
+
+tst-cancel7-ARGS = --command "$(built-program-cmd)"
+tst-cancelx7-ARGS = $(tst-cancel7-ARGS)
+tst-umask1-ARGS = $(objpfx)tst-umask1.temp
+
+$(objpfx)tst-atfork2: $(libdl) $(shared-thread-library)
+LDFLAGS-tst-atfork2 = -rdynamic
+tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
+$(objpfx)tst-atfork2mod.so: $(shared-thread-library)
+
+tests: $(objpfx)tst-stack3-mem
+tst-stack3-ENV = MALLOC_TRACE=$(objpfx)tst-stack3.mtrace
+$(objpfx)tst-stack3-mem: $(objpfx)tst-stack3.out
+       $(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@
+generated += tst-stack3-mem tst-stack3.mtrace
+
+$(objpfx)tst-cleanup4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
+$(objpfx)tst-cleanupx4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
+
+$(objpfx)tst-tls3: $(libdl) $(shared-thread-library)
+LDFLAGS-tst-tls3 = -rdynamic
+$(objpfx)tst-tls3.out: $(objpfx)tst-tls3mod.so
+$(objpfx)tst-tls3mod.so: $(shared-thread-library)
+
+$(objpfx)tst-tls4: $(libdl) $(shared-thread-library)
+$(objpfx)tst-tls4.out: $(objpfx)tst-tls4moda.so $(objpfx)tst-tls4modb.so
+
+$(objpfx)tst-tls5: $(objpfx)tst-tls5mod.so $(shared-thread-library)
+LDFLAGS-tst-tls5mod.so = -Wl,-soname,tst-tls5mod.so
+
+ifeq ($(build-shared),yes)
+tests: $(objpfx)tst-tls6.out
+$(objpfx)tst-tls6.out: tst-tls6.sh $(objpfx)tst-tls5 \
+                      $(objpfx)tst-tls5moda.so $(objpfx)tst-tls5modb.so \
+                      $(objpfx)tst-tls5modc.so $(objpfx)tst-tls5modd.so \
+                      $(objpfx)tst-tls5mode.so $(objpfx)tst-tls5modf.so
+       $(SHELL) -e tst-tls6.sh $(common-objpfx) $(elf-objpfx) \
+                   $(rtld-installed-name)
+endif
+
+$(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library)
+
+$(objpfx)tst-fini1: $(shared-thread-library) $(objpfx)tst-fini1mod.so
+
+ifeq (yes,$(build-shared))
+$(objpfx)tst-cond11: $(common-objpfx)rt/librt.so
+$(objpfx)tst-cond19: $(common-objpfx)rt/librt.so
+$(objpfx)tst-cancel17: $(common-objpfx)rt/librt.so
+$(objpfx)tst-cancelx17: $(common-objpfx)rt/librt.so
+$(objpfx)tst-cancel18: $(common-objpfx)rt/librt.so
+$(objpfx)tst-cancelx18: $(common-objpfx)rt/librt.so
+$(objpfx)tst-clock2: $(common-objpfx)rt/librt.so
+$(objpfx)tst-rwlock14: $(common-objpfx)rt/librt.so
+$(objpfx)tst-_res1mod2.so: $(objpfx)tst-_res1mod1.so
+LDFLAGS-tst-_res1mod1.so = -Wl,-soname,tst-_res1mod1.so
+LDFLAGS-tst-_res1mod2.so = -Wl,-soname,tst-_res1mod2.so
+$(objpfx)tst-_res1: $(objpfx)tst-_res1mod2.so $(shared-thread-library)
+else
+$(objpfx)tst-cond11: $(common-objpfx)rt/librt.a
+$(objpfx)tst-cond19: $(common-objpfx)rt/librt.a
+$(objpfx)tst-cancel17: $(common-objpfx)rt/librt.a
+$(objpfx)tst-cancelx17: $(common-objpfx)rt/librt.a
+$(objpfx)tst-cancel18: $(common-objpfx)rt/librt.a
+$(objpfx)tst-cancelx18: $(common-objpfx)rt/librt.a
+$(objpfx)tst-clock2: $(common-objpfx)rt/librt.a
+$(objpfx)tst-rwlock14: $(common-objpfx)rt/librt.a
+endif
+
+extra-B-pthread.so = -B$(common-objpfx)nptl/
+$(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs))
+$(objpfx)libpthread.so: +preinit += $(addprefix $(objpfx),$(crti-objs))
+$(objpfx)libpthread.so: +postinit += $(addprefix $(objpfx),$(crtn-objs))
+
+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
+# This ensures they will load libc.so for needed symbols if loaded by
+# a statically-linked program that hasn't already loaded it.
+# Depend on ld.so too to get proper versions of ld.so symbols.
+$(objpfx)libpthread.so: $(common-objpfx)libc.so \
+                       $(common-objpfx)libc_nonshared.a \
+                       $(if $(filter yes,$(elf)), $(elfobjdir)/ld.so)
+
+# Make sure we link with the thread library.
+ifeq ($(build-shared),yes)
+$(addprefix $(objpfx), \
+  $(filter-out $(tests-static) $(xtests-static) $(tests-reverse) \
+    $(tests-nolibpthread), \
+    $(tests) $(xtests) $(test-srcs))): $(objpfx)libpthread.so \
+                                      $(objpfx)libpthread_nonshared.a
+$(objpfx)tst-unload: $(common-objpfx)dlfcn/libdl.so
+# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
+# since otherwise libpthread.so comes before libc.so when linking.
+$(addprefix $(objpfx), $(tests-reverse)): \
+  $(objpfx)../libc.so $(objpfx)libpthread.so \
+  $(objpfx)libpthread_nonshared.a
+$(objpfx)../libc.so: $(common-objpfx)libc.so ;
+$(addprefix $(objpfx),$(tests-static) $(xtests-static)): $(objpfx)libpthread.a
+
+$(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so
+else
+$(addprefix $(objpfx),$(tests) $(test-srcs)): $(objpfx)libpthread.a
+endif
+
+ifeq ($(build-shared),yes)
+vpath pt-initfini.c $(full_config_sysdirs)
+
+$(objpfx)pt-initfini.s: pt-initfini.c
+       $(compile.c) -S $(CFLAGS-pt-initfini.s) -finhibit-size-directive \
+               $(patsubst -f%,-fno-%,$(exceptions)) -o $@
+
+$(objpfx)tst-cleanup0.out: /dev/null $(objpfx)tst-cleanup0
+       $(make-test-out) 2>&1 | cmp - tst-cleanup0.expect >& $@
+
+# We only have one kind of startup code files.  Static binaries and
+# shared libraries are build using the PIC version.
+$(objpfx)crti.S: $(objpfx)pt-initfini.s
+       sed -n -e '1,/@HEADER_ENDS/p' \
+              -e '/@_.*_PROLOG_BEGINS/,/@_.*_PROLOG_ENDS/p' \
+              -e '/@TRAILER_BEGINS/,$$p' $< > $@
+$(objpfx)crtn.S: $(objpfx)pt-initfini.s
+       sed -n -e '1,/@HEADER_ENDS/p' \
+              -e '/@_.*_EPILOG_BEGINS/,/@_.*_EPILOG_ENDS/p' \
+              -e '/@TRAILER_BEGINS/,$$p' $< > $@
+
+$(objpfx)defs.h: $(objpfx)pt-initfini.s
+       sed -n -e '/@TESTS_BEGIN/,/@TESTS_END/p' $< | \
+               $(AWK) -f ../csu/defs.awk > $@
+
+$(objpfx)crti.o: $(objpfx)crti.S $(objpfx)defs.h
+       $(compile.S) -g0 $(ASFLAGS-.os) -o $@
+
+$(objpfx)crtn.o: $(objpfx)crtn.S $(objpfx)defs.h
+       $(compile.S) -g0 $(ASFLAGS-.os) -o $@
+
+ifneq ($(multidir),.)
+$(objpfx)$(multidir)/crti.o: $(objpfx)crti.o $(objpfx)$(multidir)/
+       ln -f $< $@
+
+$(objpfx)$(multidir)/crtn.o: $(objpfx)crtn.o $(objpfx)$(multidir)/
+       ln -f $< $@
+endif
+
+generated += crti.S crtn.S defs.h pt-initfini.s  libpthread_nonshared.a \
+            multidir.mk tst-atfork2.mtrace tst-cancel-wrappers.out \
+            tst-tls6.out
+
+generated += $(objpfx)tst-atfork2.mtrace \
+            $(addsuffix .so,$(strip $(modules-names)))
+
+$(objpfx)version.d: $(objpfx)banner.h
+$(objpfx)version.os: $(objpfx)banner.h
+$(objpfx)banner.h: Banner
+       sed 's/\(.*\)/"\1\\n"/' $< > $@
+generated += banner.h
+# Give libpthread.so an entry point and make it directly runnable itself.
+LDFLAGS-pthread.so += -e __nptl_main
+endif
+
+ifeq (no,$(cross-compiling))
+ifeq (yes,$(build-shared))
+tests: $(objpfx)tst-cancel-wrappers.out
+$(objpfx)tst-cancel-wrappers.out: tst-cancel-wrappers.sh
+       $(SHELL) $< $(common-objpfx)libc_pic.a \
+                   $(common-objpfx)libc.a \
+                   $(objpfx)libpthread_pic.a \
+                   $(objpfx)libpthread.a > $@
+endif
+endif
+
+tst-exec4-ARGS = $(built-program-cmd)
+
+$(objpfx)tst-execstack: $(libdl)
+$(objpfx)tst-execstack.out: $(objpfx)tst-execstack-mod.so
+LDFLAGS-tst-execstack = -Wl,-z,noexecstack
+
+$(objpfx)tst-fini1mod.so: $(shared-thread-library)
+
+# The tests here better do not run in parallel
+ifneq ($(filter %tests,$(MAKECMDGOALS)),)
+.NOTPARALLEL:
+endif
diff --git a/libpthread/nptl/TODO b/libpthread/nptl/TODO
new file mode 100644 (file)
index 0000000..a4a1055
--- /dev/null
@@ -0,0 +1,12 @@
+- we should probably extend pthread_mutexattr_t with a field to create a
+  single linked list of all instances.  This requires changing the
+  pthread_mutexattr_* functions.
+
+
+- a new attribute for mutexes: number of times we spin before calling
+sys_futex
+
+
+
+- test with threaded process terminating and semadj (?) being applied
+  only after all threads are gone
diff --git a/libpthread/nptl/TODO-kernel b/libpthread/nptl/TODO-kernel
new file mode 100644 (file)
index 0000000..ad6d2a4
--- /dev/null
@@ -0,0 +1,20 @@
+- setuid/setgid must effect process
+  + test syscalls (getuid) afterwards
+  + test core file content
+
+  + use UID/GID in access(2), chmod(2), chown(2), link(2)
+
+- nice level is process property
+
+- rlimit should be process-wide and SIGXCPU should be sent if all threads
+  together exceed the limit
+
+- getrusage() must return resource utilization for the process
+
+
+
+The following are possible optimizations and in no way required:
+
+
+- the scheduler should be thread group-aware, i.e., it has to give time to
+  the thread group not proportional to the number of threads.
diff --git a/libpthread/nptl/TODO-testing b/libpthread/nptl/TODO-testing
new file mode 100644 (file)
index 0000000..e076e56
--- /dev/null
@@ -0,0 +1,20 @@
+pthread_attr_setguardsize
+
+  test effectiveness
+
+pthread_attr_[sg]etschedparam
+
+  what to test?
+
+pthread_attr_[sg]etstack
+
+  some more tests needed
+
+pthread_getcpuclockid
+
+  check that value is reset -> rt subdir
+
+pthread_getschedparam
+pthread_setschedparam
+
+  what to test?
diff --git a/libpthread/nptl/Versions b/libpthread/nptl/Versions
new file mode 100644 (file)
index 0000000..79bf190
--- /dev/null
@@ -0,0 +1,240 @@
+libc {
+  GLIBC_2.0 {
+    pthread_attr_destroy; pthread_attr_init;
+    pthread_attr_getdetachstate; pthread_attr_setdetachstate;
+    pthread_attr_getinheritsched; pthread_attr_setinheritsched;
+    pthread_attr_getschedparam; pthread_attr_setschedparam;
+    pthread_attr_getschedpolicy;  pthread_attr_setschedpolicy;
+    pthread_attr_getscope; pthread_attr_setscope;
+    pthread_condattr_destroy; pthread_condattr_init;
+    pthread_cond_broadcast; pthread_cond_destroy;
+    pthread_cond_init; pthread_cond_signal; pthread_cond_wait;
+    pthread_cond_timedwait;
+    pthread_equal; pthread_exit;
+    pthread_getschedparam; pthread_setschedparam;
+    pthread_mutex_destroy; pthread_mutex_init;
+    pthread_mutex_lock; pthread_mutex_unlock;
+    pthread_self;
+    pthread_setcancelstate; pthread_setcanceltype;
+  }
+  GLIBC_2.1 {
+    pthread_attr_init;
+  }
+  GLIBC_2.3.2 {
+    # Changed pthread_cond_t.
+    pthread_cond_init; pthread_cond_destroy;
+    pthread_cond_wait; pthread_cond_signal;
+    pthread_cond_broadcast; pthread_cond_timedwait;
+  }
+  GLIBC_PRIVATE {
+    # Internal libc interface to libpthread
+    __libc_dl_error_tsd;
+  }
+}
+
+libpthread {
+  GLIBC_2.0 {
+    pthread_create; pthread_join; pthread_self; pthread_equal;
+    pthread_exit; pthread_detach;
+
+    pthread_getschedparam; pthread_setschedparam;
+
+    pthread_attr_init; pthread_attr_destroy;
+    pthread_attr_getdetachstate; pthread_attr_setdetachstate;
+    pthread_attr_getschedparam; pthread_attr_setschedparam;
+    pthread_attr_getschedpolicy; pthread_attr_setschedpolicy;
+    pthread_attr_getinheritsched; pthread_attr_setinheritsched;
+    pthread_attr_getscope; pthread_attr_setscope;
+
+    pthread_mutex_init; pthread_mutex_destroy;
+    pthread_mutex_lock; pthread_mutex_trylock; pthread_mutex_unlock;
+
+    pthread_mutexattr_init; pthread_mutexattr_destroy;
+
+    pthread_cond_init; pthread_cond_destroy;
+    pthread_cond_wait; pthread_cond_timedwait;
+    pthread_cond_signal; pthread_cond_broadcast;
+
+    pthread_condattr_destroy; pthread_condattr_init;
+
+    pthread_cancel; pthread_testcancel;
+    pthread_setcancelstate; pthread_setcanceltype;
+
+    pthread_sigmask; pthread_kill;
+
+    pthread_key_create; pthread_key_delete;
+    pthread_getspecific; pthread_setspecific;
+
+    pthread_once;
+
+    pthread_atfork;
+
+    flockfile; funlockfile; ftrylockfile;
+
+    # Non-standard POSIX1.x functions.
+    pthread_mutexattr_getkind_np; pthread_mutexattr_setkind_np;
+
+    # Protected names for functions used in other shared objects.
+    __pthread_mutex_init; __pthread_mutex_destroy;
+    __pthread_mutex_lock; __pthread_mutex_trylock; __pthread_mutex_unlock;
+    __pthread_mutexattr_init; __pthread_mutexattr_destroy;
+    __pthread_mutexattr_settype;
+    __pthread_key_create; __pthread_getspecific; __pthread_setspecific;
+    __pthread_once; __pthread_atfork;
+    _IO_flockfile; _IO_ftrylockfile; _IO_funlockfile;
+
+    # Hidden entry point (through macros).
+    #_pthread_cleanup_pop; _pthread_cleanup_pop_restore; _pthread_cleanup_push;
+    #_pthread_cleanup_push_defer;
+
+    # Semaphores.
+    sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait;
+
+    # Special fork handling.
+    fork; __fork; vfork;
+
+    # Cancellation points.
+    close; __close; fcntl; __fcntl; read; __read; write; __write; accept;
+    connect; __connect; recv; recvfrom; recvmsg; send; __send; sendmsg; sendto;
+    fsync; lseek; __lseek; msync; nanosleep; open; __open; pause; tcdrain;
+    system; wait; __wait; waitpid;
+
+    # Hidden entry point (through macros).
+    _pthread_cleanup_push; _pthread_cleanup_pop;
+    _pthread_cleanup_push_defer; _pthread_cleanup_pop_restore;
+
+    pthread_kill_other_threads_np;
+
+    # The error functions.
+    __errno_location; __h_errno_location;
+
+    # Functions which previously have been overwritten.
+    sigwait; sigaction; __sigaction; _exit; _Exit; longjmp; siglongjmp;
+    raise;
+  }
+
+  GLIBC_2.1 {
+    pthread_create;
+    pthread_attr_init;
+
+    pthread_attr_getguardsize; pthread_attr_setguardsize;
+    pthread_attr_getstackaddr; pthread_attr_setstackaddr;
+    pthread_attr_getstacksize; pthread_attr_setstacksize;
+
+    pthread_mutexattr_gettype; pthread_mutexattr_settype;
+
+    pthread_rwlock_init; pthread_rwlock_destroy;
+    pthread_rwlock_rdlock; pthread_rwlock_wrlock; pthread_rwlock_unlock;
+    pthread_rwlock_tryrdlock; pthread_rwlock_trywrlock;
+
+    pthread_rwlockattr_init; pthread_rwlockattr_destroy;
+    pthread_rwlockattr_getpshared; pthread_rwlockattr_setpshared;
+    pthread_rwlockattr_getkind_np; pthread_rwlockattr_setkind_np;
+
+    pthread_getconcurrency; pthread_setconcurrency;
+
+    # Semaphores.
+    sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait;
+
+    __libc_current_sigrtmin; __libc_current_sigrtmax;
+    __libc_allocate_rtsig;
+  }
+
+  GLIBC_2.1.1 {
+    sem_close; sem_open; sem_unlink;
+  }
+
+  GLIBC_2.1.2 {
+    __vfork;
+  }
+
+  GLIBC_2.2 {
+    pthread_mutexattr_getpshared; pthread_mutexattr_setpshared;
+
+    pthread_condattr_getpshared; pthread_condattr_setpshared;
+
+    # New functions from IEEE Std. 1003.1-2001.
+    pthread_mutex_timedlock;
+
+    pthread_rwlock_timedrdlock; pthread_rwlock_timedwrlock;
+
+    pthread_attr_getstack; pthread_attr_setstack;
+
+    pthread_spin_destroy; pthread_spin_init; pthread_spin_lock;
+    pthread_spin_trylock; pthread_spin_unlock;
+
+    pthread_barrier_init; pthread_barrier_destroy; pthread_barrier_wait;
+    pthread_barrierattr_destroy; pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+
+    sem_timedwait;
+
+    pthread_yield;
+
+    pthread_getcpuclockid;
+
+    # Cancellation points.
+    lseek64; open64; __open64; pread; pread64; __pread64; pwrite; pwrite64;
+    __pwrite64;
+
+    # Names used internally.
+    __pthread_rwlock_init; __pthread_rwlock_destroy;
+    __pthread_rwlock_rdlock; __pthread_rwlock_tryrdlock;
+    __pthread_rwlock_wrlock; __pthread_rwlock_trywrlock;
+    __pthread_rwlock_unlock;
+
+    __res_state;
+  }
+
+  GLIBC_2.2.3 {
+    # Extensions.
+    pthread_getattr_np;
+  }
+
+  GLIBC_2.2.6 {
+    # Cancellation wrapper
+    __nanosleep;
+  }
+
+  GLIBC_2.3.2 {
+    # Changed pthread_cond_t.
+    pthread_cond_init; pthread_cond_destroy;
+    pthread_cond_wait; pthread_cond_timedwait;
+    pthread_cond_signal; pthread_cond_broadcast;
+  }
+
+  GLIBC_2.3.3 {
+    # 1003.1-2001 function accidentally left out in 2.2.
+    pthread_barrierattr_getpshared;
+
+    # Unix CS option.
+    pthread_condattr_getclock; pthread_condattr_setclock;
+
+    # Proposed API extensions.
+    pthread_tryjoin_np; pthread_timedjoin_np;
+
+    # New cancellation cleanup handling.
+    __pthread_register_cancel; __pthread_unregister_cancel;
+    __pthread_register_cancel_defer; __pthread_unregister_cancel_restore;
+    __pthread_unwind_next;
+    __pthread_cleanup_routine;
+
+    # affinity interfaces without size parameter
+    pthread_getaffinity_np; pthread_setaffinity_np;
+    pthread_attr_getaffinity_np; pthread_attr_setaffinity_np;
+  }
+
+  GLIBC_2.3.4 {
+    # New affinity interfaces.
+    pthread_getaffinity_np; pthread_setaffinity_np;
+    pthread_attr_getaffinity_np; pthread_attr_setaffinity_np;
+
+    pthread_setschedprio;
+  }
+
+  GLIBC_PRIVATE {
+    __pthread_initialize_minimal;
+    __pthread_clock_gettime; __pthread_clock_settime;
+    __pthread_unwind;
+  }
+}
diff --git a/libpthread/nptl/alloca_cutoff.c b/libpthread/nptl/alloca_cutoff.c
new file mode 100644 (file)
index 0000000..ba26ceb
--- /dev/null
@@ -0,0 +1,36 @@
+/* Determine whether block of given size can be allocated on the stack or not.
+   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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <alloca.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <pthreadP.h>
+
+
+int
+__libc_alloca_cutoff (size_t size)
+{
+  return size <= (MIN (__MAX_ALLOCA_CUTOFF,
+                      THREAD_GETMEM (THREAD_SELF, stackblock_size) / 4
+                      /* The main thread, before the thread library is
+                         initialized, has zero in the stackblock_size
+                         element.  Since it is the main thread we can
+                         assume the maximum available stack space.  */
+                      ?: __MAX_ALLOCA_CUTOFF * 4));
+}
diff --git a/libpthread/nptl/allocatestack.c b/libpthread/nptl/allocatestack.c
new file mode 100644 (file)
index 0000000..fcb6c6e
--- /dev/null
@@ -0,0 +1,947 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <dl-sysdep.h>
+#include <tls.h>
+#include <lowlevellock.h>
+
+
+#ifndef NEED_SEPARATE_REGISTER_STACK
+
+/* Most architectures have exactly one stack pointer.  Some have more.  */
+# define STACK_VARIABLES void *stackaddr
+
+/* How to pass the values to the 'create_thread' function.  */
+# define STACK_VARIABLES_ARGS stackaddr
+
+/* How to declare function which gets there parameters.  */
+# define STACK_VARIABLES_PARMS void *stackaddr
+
+/* How to declare allocate_stack.  */
+# define ALLOCATE_STACK_PARMS void **stack
+
+/* This is how the function is called.  We do it this way to allow
+   other variants of the function to have more parameters.  */
+# define ALLOCATE_STACK(attr, pd) allocate_stack (attr, pd, &stackaddr)
+
+#else
+
+/* We need two stacks.  The kernel will place them but we have to tell
+   the kernel about the size of the reserved address space.  */
+# define STACK_VARIABLES void *stackaddr; size_t stacksize
+
+/* How to pass the values to the 'create_thread' function.  */
+# define STACK_VARIABLES_ARGS stackaddr, stacksize
+
+/* How to declare function which gets there parameters.  */
+# define STACK_VARIABLES_PARMS void *stackaddr, size_t stacksize
+
+/* How to declare allocate_stack.  */
+# define ALLOCATE_STACK_PARMS void **stack, size_t *stacksize
+
+/* This is how the function is called.  We do it this way to allow
+   other variants of the function to have more parameters.  */
+# define ALLOCATE_STACK(attr, pd) \
+  allocate_stack (attr, pd, &stackaddr, &stacksize)
+
+#endif
+
+
+/* Default alignment of stack.  */
+#ifndef STACK_ALIGN
+# define STACK_ALIGN __alignof__ (long double)
+#endif
+
+/* Default value for minimal stack size after allocating thread
+   descriptor and guard.  */
+#ifndef MINIMAL_REST_STACK
+# define MINIMAL_REST_STACK    4096
+#endif
+
+
+/* Let the architecture add some flags to the mmap() call used to
+   allocate stacks.  */
+#ifndef ARCH_MAP_FLAGS
+# define ARCH_MAP_FLAGS 0
+#endif
+
+/* This yields the pointer that TLS support code calls the thread pointer.  */
+#if TLS_TCB_AT_TP
+# define TLS_TPADJ(pd) (pd)
+#elif TLS_DTV_AT_TP
+# define TLS_TPADJ(pd) ((struct pthread *)((char *) (pd) + TLS_PRE_TCB_SIZE))
+#endif
+
+/* Cache handling for not-yet free stacks.  */
+
+/* Maximum size in kB of cache.  */
+static size_t stack_cache_maxsize = 40 * 1024 * 1024; /* 40MiBi by default.  */
+static size_t stack_cache_actsize;
+
+/* Mutex protecting this variable.  */
+static lll_lock_t stack_cache_lock = LLL_LOCK_INITIALIZER;
+
+/* List of queued stack frames.  */
+static LIST_HEAD (stack_cache);
+
+/* List of the stacks in use.  */
+static LIST_HEAD (stack_used);
+
+/* List of the threads with user provided stacks in use.  No need to
+   initialize this, since it's done in __pthread_initialize_minimal.  */
+list_t __stack_user __attribute__ ((nocommon));
+hidden_data_def (__stack_user)
+
+#if COLORING_INCREMENT != 0
+/* Number of threads created.  */
+static unsigned int nptl_ncreated;
+#endif
+
+
+/* Check whether the stack is still used or not.  */
+#define FREE_P(descr) ((descr)->tid <= 0)
+
+
+/* We create a double linked list of all cache entries.  Double linked
+   because this allows removing entries from the end.  */
+
+
+/* Get a stack frame from the cache.  We have to match by size since
+   some blocks might be too small or far too large.  */
+static struct pthread *
+get_cached_stack (size_t *sizep, void **memp)
+{
+  size_t size = *sizep;
+  struct pthread *result = NULL;
+  list_t *entry;
+
+  lll_lock (stack_cache_lock);
+
+  /* Search the cache for a matching entry.  We search for the
+     smallest stack which has at least the required size.  Note that
+     in normal situations the size of all allocated stacks is the
+     same.  As the very least there are only a few different sizes.
+     Therefore this loop will exit early most of the time with an
+     exact match.  */
+  list_for_each (entry, &stack_cache)
+    {
+      struct pthread *curr;
+
+      curr = list_entry (entry, struct pthread, list);
+      if (FREE_P (curr) && curr->stackblock_size >= size)
+       {
+         if (curr->stackblock_size == size)
+           {
+             result = curr;
+             break;
+           }
+
+         if (result == NULL
+             || result->stackblock_size > curr->stackblock_size)
+           result = curr;
+       }
+    }
+
+  if (__builtin_expect (result == NULL, 0)
+      /* Make sure the size difference is not too excessive.  In that
+        case we do not use the block.  */
+      || __builtin_expect (result->stackblock_size > 4 * size, 0))
+    {
+      /* Release the lock.  */
+      lll_unlock (stack_cache_lock);
+
+      return NULL;
+    }
+
+  /* Dequeue the entry.  */
+  list_del (&result->list);
+
+  /* And add to the list of stacks in use.  */
+  list_add (&result->list, &stack_used);
+
+  /* And decrease the cache size.  */
+  stack_cache_actsize -= result->stackblock_size;
+
+  /* Release the lock early.  */
+  lll_unlock (stack_cache_lock);
+
+  /* Report size and location of the stack to the caller.  */
+  *sizep = result->stackblock_size;
+  *memp = result->stackblock;
+
+  /* Cancellation handling is back to the default.  */
+  result->cancelhandling = 0;
+  result->cleanup = NULL;
+
+  /* No pending event.  */
+  result->nextevent = NULL;
+
+  /* Clear the DTV.  */
+  dtv_t *dtv = GET_DTV (TLS_TPADJ (result));
+  memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
+
+  /* Re-initialize the TLS.  */
+  _dl_allocate_tls_init (TLS_TPADJ (result));
+
+  return result;
+}
+
+
+/* Add a stack frame which is not used anymore to the stack.  Must be
+   called with the cache lock held.  */
+static inline void
+__attribute ((always_inline))
+queue_stack (struct pthread *stack)
+{
+  /* We unconditionally add the stack to the list.  The memory may
+     still be in use but it will not be reused until the kernel marks
+     the stack as not used anymore.  */
+  list_add (&stack->list, &stack_cache);
+
+  stack_cache_actsize += stack->stackblock_size;
+  if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0))
+    {
+      /* We reduce the size of the cache.  Remove the last entries
+        until the size is below the limit.  */
+      list_t *entry;
+      list_t *prev;
+
+      /* Search from the end of the list.  */
+      list_for_each_prev_safe (entry, prev, &stack_cache)
+       {
+         struct pthread *curr;
+
+         curr = list_entry (entry, struct pthread, list);
+         if (FREE_P (curr))
+           {
+             /* Unlink the block.  */
+             list_del (entry);
+
+             /* Account for the freed memory.  */
+             stack_cache_actsize -= curr->stackblock_size;
+
+             /* Free the memory associated with the ELF TLS.  */
+             _dl_deallocate_tls (TLS_TPADJ (curr), false);
+
+             /* Remove this block.  This should never fail.  If it
+                does something is really wrong.  */
+             if (munmap (curr->stackblock, curr->stackblock_size) != 0)
+               abort ();
+
+             /* Maybe we have freed enough.  */
+             if (stack_cache_actsize <= stack_cache_maxsize)
+               break;
+           }
+       }
+    }
+}
+
+
+static int
+internal_function
+change_stack_perm (struct pthread *pd
+#ifdef NEED_SEPARATE_REGISTER_STACK
+                  , size_t pagemask
+#endif
+                  )
+{
+#ifdef NEED_SEPARATE_REGISTER_STACK
+  void *stack = (pd->stackblock
+                + (((((pd->stackblock_size - pd->guardsize) / 2)
+                     & pagemask) + pd->guardsize) & pagemask));
+  size_t len = pd->stackblock + pd->stackblock_size - stack;
+#else
+  void *stack = pd->stackblock + pd->guardsize;
+  size_t len = pd->stackblock_size - pd->guardsize;
+#endif
+  if (mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
+    return errno;
+
+  return 0;
+}
+
+
+static int
+allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
+               ALLOCATE_STACK_PARMS)
+{
+  struct pthread *pd;
+  size_t size;
+  size_t pagesize_m1 = __getpagesize () - 1;
+  void *stacktop;
+
+  assert (attr != NULL);
+  assert (powerof2 (pagesize_m1 + 1));
+  assert (TCB_ALIGNMENT >= STACK_ALIGN);
+
+  /* Get the stack size from the attribute if it is set.  Otherwise we
+     use the default we determined at start time.  */
+  size = attr->stacksize ?: __default_stacksize;
+
+  /* Get memory for the stack.  */
+  if (__builtin_expect (attr->flags & ATTR_FLAG_STACKADDR, 0))
+    {
+      uintptr_t adj;
+
+      /* If the user also specified the size of the stack make sure it
+        is large enough.  */
+      if (attr->stacksize != 0
+         && attr->stacksize < (__static_tls_size + MINIMAL_REST_STACK))
+       return EINVAL;
+
+      /* Adjust stack size for alignment of the TLS block.  */
+#if TLS_TCB_AT_TP
+      adj = ((uintptr_t) attr->stackaddr - TLS_TCB_SIZE)
+           & __static_tls_align_m1;
+      assert (size > adj + TLS_TCB_SIZE);
+#elif TLS_DTV_AT_TP
+      adj = ((uintptr_t) attr->stackaddr - __static_tls_size)
+           & __static_tls_align_m1;
+      assert (size > adj);
+#endif
+
+      /* The user provided some memory.  Let's hope it matches the
+        size...  We do not allocate guard pages if the user provided
+        the stack.  It is the user's responsibility to do this if it
+        is wanted.  */
+#if TLS_TCB_AT_TP
+      pd = (struct pthread *) ((uintptr_t) attr->stackaddr
+                              - TLS_TCB_SIZE - adj);
+#elif TLS_DTV_AT_TP
+      pd = (struct pthread *) (((uintptr_t) attr->stackaddr
+                               - __static_tls_size - adj)
+                              - TLS_PRE_TCB_SIZE);
+#endif
+
+      /* The user provided stack memory needs to be cleared.  */
+      memset (pd, '\0', sizeof (struct pthread));
+
+      /* The first TSD block is included in the TCB.  */
+      pd->specific[0] = pd->specific_1stblock;
+
+      /* Remember the stack-related values.  */
+      pd->stackblock = (char *) attr->stackaddr - size;
+      pd->stackblock_size = size;
+
+      /* This is a user-provided stack.  It will not be queued in the
+        stack cache nor will the memory (except the TLS memory) be freed.  */
+      pd->user_stack = true;
+
+      /* This is at least the second thread.  */
+      pd->header.multiple_threads = 1;
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+      __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
+#endif
+
+#ifdef NEED_DL_SYSINFO
+      /* Copy the sysinfo value from the parent.  */
+      THREAD_SYSINFO(pd) = THREAD_SELF_SYSINFO;
+#endif
+
+      /* The process ID is also the same as that of the caller.  */
+      pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
+
+      /* Allocate the DTV for this thread.  */
+      if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
+       {
+         /* Something went wrong.  */
+         assert (errno == ENOMEM);
+         return EAGAIN;
+       }
+
+
+      /* Prepare to modify global data.  */
+      lll_lock (stack_cache_lock);
+
+      /* And add to the list of stacks in use.  */
+      list_add (&pd->list, &__stack_user);
+
+      lll_unlock (stack_cache_lock);
+    }
+  else
+    {
+      /* Allocate some anonymous memory.  If possible use the cache.  */
+      size_t guardsize;
+      size_t reqsize;
+      void *mem;
+      const int prot = (PROT_READ | PROT_WRITE
+                       | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
+
+#if COLORING_INCREMENT != 0
+      /* Add one more page for stack coloring.  Don't do it for stacks
+        with 16 times pagesize or larger.  This might just cause
+        unnecessary misalignment.  */
+      if (size <= 16 * pagesize_m1)
+       size += pagesize_m1 + 1;
+#endif
+
+      /* Adjust the stack size for alignment.  */
+      size &= ~__static_tls_align_m1;
+      assert (size != 0);
+
+      /* Make sure the size of the stack is enough for the guard and
+        eventually the thread descriptor.  */
+      guardsize = (attr->guardsize + pagesize_m1) & ~pagesize_m1;
+      if (__builtin_expect (size < (guardsize + __static_tls_size
+                                   + MINIMAL_REST_STACK + pagesize_m1 + 1),
+                           0))
+       /* The stack is too small (or the guard too large).  */
+       return EINVAL;
+
+      /* Try to get a stack from the cache.  */
+      reqsize = size;
+      pd = get_cached_stack (&size, &mem);
+      if (pd == NULL)
+       {
+         /* To avoid aliasing effects on a larger scale than pages we
+            adjust the allocated stack size if necessary.  This way
+            allocations directly following each other will not have
+            aliasing problems.  */
+#if MULTI_PAGE_ALIASING != 0
+         if ((size % MULTI_PAGE_ALIASING) == 0)
+           size += pagesize_m1 + 1;
+#endif
+
+         mem = mmap (NULL, size, prot,
+                     MAP_PRIVATE | MAP_ANONYMOUS | ARCH_MAP_FLAGS, -1, 0);
+
+         if (__builtin_expect (mem == MAP_FAILED, 0))
+           {
+#ifdef ARCH_RETRY_MMAP
+             mem = ARCH_RETRY_MMAP (size);
+             if (__builtin_expect (mem == MAP_FAILED, 0))
+#endif
+               return errno;
+           }
+
+         /* SIZE is guaranteed to be greater than zero.
+            So we can never get a null pointer back from mmap.  */
+         assert (mem != NULL);
+
+#if COLORING_INCREMENT != 0
+         /* Atomically increment NCREATED.  */
+         unsigned int ncreated = atomic_increment_val (&nptl_ncreated);
+
+         /* We chose the offset for coloring by incrementing it for
+            every new thread by a fixed amount.  The offset used
+            module the page size.  Even if coloring would be better
+            relative to higher alignment values it makes no sense to
+            do it since the mmap() interface does not allow us to
+            specify any alignment for the returned memory block.  */
+         size_t coloring = (ncreated * COLORING_INCREMENT) & pagesize_m1;
+
+         /* Make sure the coloring offsets does not disturb the alignment
+            of the TCB and static TLS block.  */
+         if (__builtin_expect ((coloring & __static_tls_align_m1) != 0, 0))
+           coloring = (((coloring + __static_tls_align_m1)
+                        & ~(__static_tls_align_m1))
+                       & ~pagesize_m1);
+#else
+         /* Unless specified we do not make any adjustments.  */
+# define coloring 0
+#endif
+
+         /* Place the thread descriptor at the end of the stack.  */
+#if TLS_TCB_AT_TP
+         pd = (struct pthread *) ((char *) mem + size - coloring) - 1;
+#elif TLS_DTV_AT_TP
+         pd = (struct pthread *) ((((uintptr_t) mem + size - coloring
+                                   - __static_tls_size)
+                                   & ~__static_tls_align_m1)
+                                  - TLS_PRE_TCB_SIZE);
+#endif
+
+         /* Remember the stack-related values.  */
+         pd->stackblock = mem;
+         pd->stackblock_size = size;
+
+         /* We allocated the first block thread-specific data array.
+            This address will not change for the lifetime of this
+            descriptor.  */
+         pd->specific[0] = pd->specific_1stblock;
+
+         /* This is at least the second thread.  */
+         pd->header.multiple_threads = 1;
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+         __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
+#endif
+
+#ifdef NEED_DL_SYSINFO
+         /* Copy the sysinfo value from the parent.  */
+         THREAD_SYSINFO(pd) = THREAD_SELF_SYSINFO;
+#endif
+
+         /* The process ID is also the same as that of the caller.  */
+         pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
+
+         /* Allocate the DTV for this thread.  */
+         if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
+           {
+             /* Something went wrong.  */
+             assert (errno == ENOMEM);
+
+             /* Free the stack memory we just allocated.  */
+             (void) munmap (mem, size);
+
+             return EAGAIN;
+           }
+
+
+         /* Prepare to modify global data.  */
+         lll_lock (stack_cache_lock);
+
+         /* And add to the list of stacks in use.  */
+         list_add (&pd->list, &stack_used);
+
+         lll_unlock (stack_cache_lock);
+
+
+         /* There might have been a race.  Another thread might have
+            caused the stacks to get exec permission while this new
+            stack was prepared.  Detect if this was possible and
+            change the permission if necessary.  */
+         if (__builtin_expect ((GL(dl_stack_flags) & PF_X) != 0
+                               && (prot & PROT_EXEC) == 0, 0))
+           {
+             int err = change_stack_perm (pd
+#ifdef NEED_SEPARATE_REGISTER_STACK
+                                          , ~pagesize_m1
+#endif
+                                          );
+             if (err != 0)
+               {
+                 /* Free the stack memory we just allocated.  */
+                 (void) munmap (mem, size);
+
+                 return err;
+               }
+           }
+
+
+         /* Note that all of the stack and the thread descriptor is
+            zeroed.  This means we do not have to initialize fields
+            with initial value zero.  This is specifically true for
+            the 'tid' field which is always set back to zero once the
+            stack is not used anymore and for the 'guardsize' field
+            which will be read next.  */
+       }
+
+      /* Create or resize the guard area if necessary.  */
+      if (__builtin_expect (guardsize > pd->guardsize, 0))
+       {
+#ifdef NEED_SEPARATE_REGISTER_STACK
+         char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1);
+#else
+         char *guard = mem;
+#endif
+         if (mprotect (guard, guardsize, PROT_NONE) != 0)
+           {
+             int err;
+           mprot_error:
+             err = errno;
+
+             lll_lock (stack_cache_lock);
+
+             /* Remove the thread from the list.  */
+             list_del (&pd->list);
+
+             lll_unlock (stack_cache_lock);
+
+             /* Get rid of the TLS block we allocated.  */
+             _dl_deallocate_tls (TLS_TPADJ (pd), false);
+
+             /* Free the stack memory regardless of whether the size
+                of the cache is over the limit or not.  If this piece
+                of memory caused problems we better do not use it
+                anymore.  Uh, and we ignore possible errors.  There
+                is nothing we could do.  */
+             (void) munmap (mem, size);
+
+             return err;
+           }
+
+         pd->guardsize = guardsize;
+       }
+      else if (__builtin_expect (pd->guardsize - guardsize > size - reqsize,
+                                0))
+       {
+         /* The old guard area is too large.  */
+
+#ifdef NEED_SEPARATE_REGISTER_STACK
+         char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1);
+         char *oldguard = mem + (((size - pd->guardsize) / 2) & ~pagesize_m1);
+
+         if (oldguard < guard
+             && mprotect (oldguard, guard - oldguard, prot) != 0)
+           goto mprot_error;
+
+         if (mprotect (guard + guardsize,
+                       oldguard + pd->guardsize - guard - guardsize,
+                       prot) != 0)
+           goto mprot_error;
+#else
+         if (mprotect ((char *) mem + guardsize, pd->guardsize - guardsize,
+                       prot) != 0)
+           goto mprot_error;
+#endif
+
+         pd->guardsize = guardsize;
+       }
+      /* The pthread_getattr_np() calls need to get passed the size
+        requested in the attribute, regardless of how large the
+        actually used guardsize is.  */
+      pd->reported_guardsize = guardsize;
+    }
+
+  /* Initialize the lock.  We have to do this unconditionally since the
+     stillborn thread could be canceled while the lock is taken.  */
+  pd->lock = LLL_LOCK_INITIALIZER;
+
+  /* We place the thread descriptor at the end of the stack.  */
+  *pdp = pd;
+
+#if TLS_TCB_AT_TP
+  /* The stack begins before the TCB and the static TLS block.  */
+  stacktop = ((char *) (pd + 1) - __static_tls_size);
+#elif TLS_DTV_AT_TP
+  stacktop = (char *) (pd - 1);
+#endif
+
+#ifdef NEED_SEPARATE_REGISTER_STACK
+  *stack = pd->stackblock;
+  *stacksize = stacktop - *stack;
+#else
+  *stack = stacktop;
+#endif
+
+  return 0;
+}
+
+
+void
+internal_function
+__deallocate_stack (struct pthread *pd)
+{
+  lll_lock (stack_cache_lock);
+
+  /* Remove the thread from the list of threads with user defined
+     stacks.  */
+  list_del (&pd->list);
+
+  /* Not much to do.  Just free the mmap()ed memory.  Note that we do
+     not reset the 'used' flag in the 'tid' field.  This is done by
+     the kernel.  If no thread has been created yet this field is
+     still zero.  */
+  if (__builtin_expect (! pd->user_stack, 1))
+    (void) queue_stack (pd);
+  else
+    /* Free the memory associated with the ELF TLS.  */
+    _dl_deallocate_tls (TLS_TPADJ (pd), false);
+
+  lll_unlock (stack_cache_lock);
+}
+
+
+int
+internal_function
+__make_stacks_executable (void **stack_endp)
+{
+  /* First the main thread's stack.  */
+  int err = _dl_make_stack_executable (stack_endp);
+  if (err != 0)
+    return err;
+
+#ifdef NEED_SEPARATE_REGISTER_STACK
+  const size_t pagemask = ~(__getpagesize () - 1);
+#endif
+
+  lll_lock (stack_cache_lock);
+
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    {
+      err = change_stack_perm (list_entry (runp, struct pthread, list)
+#ifdef NEED_SEPARATE_REGISTER_STACK
+                              , pagemask
+#endif
+                              );
+      if (err != 0)
+       break;
+    }
+
+  /* Also change the permission for the currently unused stacks.  This
+     might be wasted time but better spend it here than adding a check
+     in the fast path.  */
+  if (err == 0)
+    list_for_each (runp, &stack_cache)
+      {
+       err = change_stack_perm (list_entry (runp, struct pthread, list)
+#ifdef NEED_SEPARATE_REGISTER_STACK
+                                , pagemask
+#endif
+                                );
+       if (err != 0)
+         break;
+      }
+
+  lll_unlock (stack_cache_lock);
+
+  return err;
+}
+
+
+/* In case of a fork() call the memory allocation in the child will be
+   the same but only one thread is running.  All stacks except that of
+   the one running thread are not used anymore.  We have to recycle
+   them.  */
+void
+__reclaim_stacks (void)
+{
+  struct pthread *self = (struct pthread *) THREAD_SELF;
+
+  /* No locking necessary.  The caller is the only stack in use.  */
+
+  /* Mark all stacks except the still running one as free.  */
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    {
+      struct pthread *curp;
+
+      curp = list_entry (runp, struct pthread, list);
+      if (curp != self)
+       {
+         /* This marks the stack as free.  */
+         curp->tid = 0;
+
+         /* The PID field must be initialized for the new process.  */
+         curp->pid = self->pid;
+
+         /* Account for the size of the stack.  */
+         stack_cache_actsize += curp->stackblock_size;
+       }
+    }
+
+  /* Add the stack of all running threads to the cache.  */
+  list_splice (&stack_used, &stack_cache);
+
+  /* Remove the entry for the current thread to from the cache list
+     and add it to the list of running threads.  Which of the two
+     lists is decided by the user_stack flag.  */
+  list_del (&self->list);
+
+  /* Re-initialize the lists for all the threads.  */
+  INIT_LIST_HEAD (&stack_used);
+  INIT_LIST_HEAD (&__stack_user);
+
+  if (__builtin_expect (THREAD_GETMEM (self, user_stack), 0))
+    list_add (&self->list, &__stack_user);
+  else
+    list_add (&self->list, &stack_used);
+
+  /* There is one thread running.  */
+  __nptl_nthreads = 1;
+
+  /* Initialize the lock.  */
+  stack_cache_lock = LLL_LOCK_INITIALIZER;
+}
+
+
+#if HP_TIMING_AVAIL
+# undef __find_thread_by_id
+/* Find a thread given the thread ID.  */
+attribute_hidden
+struct pthread *
+__find_thread_by_id (pid_t tid)
+{
+  struct pthread *result = NULL;
+
+  lll_lock (stack_cache_lock);
+
+  /* Iterate over the list with system-allocated threads first.  */
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    {
+      struct pthread *curp;
+
+      curp = list_entry (runp, struct pthread, list);
+
+      if (curp->tid == tid)
+       {
+         result = curp;
+         goto out;
+       }
+    }
+
+  /* Now the list with threads using user-allocated stacks.  */
+  list_for_each (runp, &__stack_user)
+    {
+      struct pthread *curp;
+
+      curp = list_entry (runp, struct pthread, list);
+
+      if (curp->tid == tid)
+       {
+         result = curp;
+         goto out;
+       }
+    }
+
+ out:
+  lll_unlock (stack_cache_lock);
+
+  return result;
+}
+#endif
+
+int
+attribute_hidden
+__nptl_setxid (struct xid_command *cmdp)
+{
+  int result;
+  lll_lock (stack_cache_lock);
+
+  __xidcmd = cmdp;
+  cmdp->cntr = 0;
+
+  INTERNAL_SYSCALL_DECL (err);
+
+  struct pthread *self = THREAD_SELF;
+
+  /* Iterate over the list with system-allocated threads first.  */
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    {
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t != self)
+       {
+         int val;
+#if __ASSUME_TGKILL
+         val = INTERNAL_SYSCALL (tgkill, err, 3,
+                                 THREAD_GETMEM (THREAD_SELF, pid),
+                                 t->tid, SIGSETXID);
+#else
+# ifdef __NR_tgkill
+         val = INTERNAL_SYSCALL (tgkill, err, 3,
+                                 THREAD_GETMEM (THREAD_SELF, pid),
+                                 t->tid, SIGSETXID);
+         if (INTERNAL_SYSCALL_ERROR_P (val, err)
+             && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
+# endif
+           val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
+#endif
+
+         if (!INTERNAL_SYSCALL_ERROR_P (val, err))
+           atomic_increment (&cmdp->cntr);
+       }
+    }
+
+  /* Now the list with threads using user-allocated stacks.  */
+  list_for_each (runp, &__stack_user)
+    {
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t != self)
+       {
+         int val;
+#if __ASSUME_TGKILL
+         val = INTERNAL_SYSCALL (tgkill, err, 3,
+                                 THREAD_GETMEM (THREAD_SELF, pid),
+                                 t->tid, SIGSETXID);
+#else
+# ifdef __NR_tgkill
+         val = INTERNAL_SYSCALL (tgkill, err, 3,
+                                 THREAD_GETMEM (THREAD_SELF, pid),
+                                 t->tid, SIGSETXID);
+         if (INTERNAL_SYSCALL_ERROR_P (val, err)
+             && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
+# endif
+           val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
+#endif
+
+         if (!INTERNAL_SYSCALL_ERROR_P (val, err))
+           atomic_increment (&cmdp->cntr);
+       }
+    }
+
+  int cur = cmdp->cntr;
+  while (cur != 0)
+    {
+      lll_futex_wait (&cmdp->cntr, cur);
+      cur = cmdp->cntr;
+    }
+
+  /* This must be last, otherwise the current thread might not have
+     permissions to send SIGSETXID syscall to the other threads.  */
+  result = INTERNAL_SYSCALL_NCS (cmdp->syscall_no, err, 3,
+                                cmdp->id[0], cmdp->id[1], cmdp->id[2]);
+  if (INTERNAL_SYSCALL_ERROR_P (result, err))
+    {
+      __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
+      result = -1;
+    }
+
+  lll_unlock (stack_cache_lock);
+  return result;
+}
+
+static inline void __attribute__((always_inline))
+init_one_static_tls (struct pthread *curp, struct link_map *map)
+{
+  dtv_t *dtv = GET_DTV (TLS_TPADJ (curp));
+# if TLS_TCB_AT_TP
+  void *dest = (char *) curp - map->l_tls_offset;
+# elif TLS_DTV_AT_TP
+  void *dest = (char *) curp + map->l_tls_offset + TLS_PRE_TCB_SIZE;
+# else
+#  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+# endif
+
+  /* Fill in the DTV slot so that a later LD/GD access will find it.  */
+  dtv[map->l_tls_modid].pointer.val = dest;
+  dtv[map->l_tls_modid].pointer.is_static = true;
+
+  /* Initialize the memory.  */
+  memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
+         '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
+}
+
+void
+attribute_hidden
+__pthread_init_static_tls (struct link_map *map)
+{
+  lll_lock (stack_cache_lock);
+
+  /* Iterate over the list with system-allocated threads first.  */
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    init_one_static_tls (list_entry (runp, struct pthread, list), map);
+
+  /* Now the list with threads using user-allocated stacks.  */
+  list_for_each (runp, &__stack_user)
+    init_one_static_tls (list_entry (runp, struct pthread, list), map);
+
+  lll_unlock (stack_cache_lock);
+}
diff --git a/libpthread/nptl/cancellation.c b/libpthread/nptl/cancellation.c
new file mode 100644 (file)
index 0000000..1d28d38
--- /dev/null
@@ -0,0 +1,90 @@
+/* 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.  */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+/* The next two functions are similar to pthread_setcanceltype() but
+   more specialized for the use in the cancelable functions like write().
+   They do not need to check parameters etc.  */
+int
+attribute_hidden
+__pthread_enable_asynccancel (void)
+{
+  struct pthread *self = THREAD_SELF;
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+
+  while (1)
+    {
+      int newval = oldval | CANCELTYPE_BITMASK;
+
+      if (newval == oldval)
+       break;
+
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+                                             oldval);
+      if (__builtin_expect (curval == oldval, 1))
+       {
+         if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
+           {
+             THREAD_SETMEM (self, result, PTHREAD_CANCELED);
+             __do_cancel ();
+           }
+
+         break;
+       }
+
+      /* Prepare the next round.  */
+      oldval = curval;
+    }
+
+  return oldval;
+}
+
+
+void
+internal_function attribute_hidden
+__pthread_disable_asynccancel (int oldtype)
+{
+  /* If asynchronous cancellation was enabled before we do not have
+     anything to do.  */
+  if (oldtype & CANCELTYPE_BITMASK)
+    return;
+
+  struct pthread *self = THREAD_SELF;
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+
+  while (1)
+    {
+      int newval = oldval & ~CANCELTYPE_BITMASK;
+
+      if (newval == oldval)
+       break;
+
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+                                             oldval);
+      if (__builtin_expect (curval == oldval, 1))
+       break;
+
+      /* Prepare the next round.  */
+      oldval = curval;
+    }
+}
diff --git a/libpthread/nptl/cleanup.c b/libpthread/nptl/cleanup.c
new file mode 100644 (file)
index 0000000..af828c4
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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.  */
+
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+void
+__cleanup_fct_attribute
+__pthread_register_cancel (__pthread_unwind_buf_t *buf)
+{
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+  struct pthread *self = THREAD_SELF;
+
+  /* Store old info.  */
+  ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
+  ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);
+
+  /* Store the new cleanup handler info.  */
+  THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
+}
+hidden_def (__pthread_register_cancel)
+
+
+void
+__cleanup_fct_attribute
+__pthread_unregister_cancel (__pthread_unwind_buf_t *buf)
+{
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+
+  THREAD_SETMEM (THREAD_SELF, cleanup_jmp_buf, ibuf->priv.data.prev);
+}
+hidden_def (__pthread_unregister_cancel)
diff --git a/libpthread/nptl/cleanup_compat.c b/libpthread/nptl/cleanup_compat.c
new file mode 100644 (file)
index 0000000..a25b397
--- /dev/null
@@ -0,0 +1,55 @@
+/* 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.  */
+
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+void
+_pthread_cleanup_push (buffer, routine, arg)
+     struct _pthread_cleanup_buffer *buffer;
+     void (*routine) (void *);
+     void *arg;
+{
+  struct pthread *self = THREAD_SELF;
+
+  buffer->__routine = routine;
+  buffer->__arg = arg;
+  buffer->__prev = THREAD_GETMEM (self, cleanup);
+
+  THREAD_SETMEM (self, cleanup, buffer);
+}
+strong_alias (_pthread_cleanup_push, __pthread_cleanup_push)
+
+
+void
+_pthread_cleanup_pop (buffer, execute)
+     struct _pthread_cleanup_buffer *buffer;
+     int execute;
+{
+  struct pthread *self __attribute ((unused)) = THREAD_SELF;
+
+  THREAD_SETMEM (self, cleanup, buffer->__prev);
+
+  /* If necessary call the cleanup routine after we removed the
+     current cleanup block from the list.  */
+  if (execute)
+    buffer->__routine (buffer->__arg);
+}
+strong_alias (_pthread_cleanup_pop, __pthread_cleanup_pop)
diff --git a/libpthread/nptl/cleanup_defer.c b/libpthread/nptl/cleanup_defer.c
new file mode 100644 (file)
index 0000000..498d955
--- /dev/null
@@ -0,0 +1,92 @@
+/* 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.  */
+
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+void
+__cleanup_fct_attribute
+__pthread_register_cancel_defer (__pthread_unwind_buf_t *buf)
+{
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+  struct pthread *self = THREAD_SELF;
+
+  /* Store old info.  */
+  ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
+  ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);
+
+  int cancelhandling = THREAD_GETMEM (self, cancelhandling);
+
+  /* Disable asynchronous cancellation for now.  */
+  if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0))
+    while (1)
+      {
+       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+                                               cancelhandling
+                                               & ~CANCELTYPE_BITMASK,
+                                               cancelhandling);
+       if (__builtin_expect (curval == cancelhandling, 1))
+         /* Successfully replaced the value.  */
+         break;
+
+       /* Prepare for the next round.  */
+       cancelhandling = curval;
+      }
+
+  ibuf->priv.data.canceltype = (cancelhandling & CANCELTYPE_BITMASK
+                               ? PTHREAD_CANCEL_ASYNCHRONOUS
+                               : PTHREAD_CANCEL_DEFERRED);
+
+  /* Store the new cleanup handler info.  */
+  THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
+}
+
+
+void
+__cleanup_fct_attribute
+__pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf)
+{
+  struct pthread *self = THREAD_SELF;
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+
+  THREAD_SETMEM (self, cleanup_jmp_buf, ibuf->priv.data.prev);
+
+  int cancelhandling;
+  if (ibuf->priv.data.canceltype != PTHREAD_CANCEL_DEFERRED
+      && ((cancelhandling = THREAD_GETMEM (self, cancelhandling))
+         & CANCELTYPE_BITMASK) == 0)
+    {
+      while (1)
+       {
+         int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+                                                 cancelhandling
+                                                 | CANCELTYPE_BITMASK,
+                                                 cancelhandling);
+         if (__builtin_expect (curval == cancelhandling, 1))
+           /* Successfully replaced the value.  */
+           break;
+
+         /* Prepare for the next round.  */
+         cancelhandling = curval;
+       }
+
+      CANCELLATION_P (self);
+    }
+}
diff --git a/libpthread/nptl/cleanup_defer_compat.c b/libpthread/nptl/cleanup_defer_compat.c
new file mode 100644 (file)
index 0000000..a0ed6da
--- /dev/null
@@ -0,0 +1,98 @@
+/* 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.  */
+
+#include "pthreadP.h"
+
+
+void
+_pthread_cleanup_push_defer (buffer, routine, arg)
+     struct _pthread_cleanup_buffer *buffer;
+     void (*routine) (void *);
+     void *arg;
+{
+  struct pthread *self = THREAD_SELF;
+
+  buffer->__routine = routine;
+  buffer->__arg = arg;
+  buffer->__prev = THREAD_GETMEM (self, cleanup);
+
+  int cancelhandling = THREAD_GETMEM (self, cancelhandling);
+
+  /* Disable asynchronous cancellation for now.  */
+  if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0))
+    while (1)
+      {
+       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+                                               cancelhandling
+                                               & ~CANCELTYPE_BITMASK,
+                                               cancelhandling);
+       if (__builtin_expect (curval == cancelhandling, 1))
+         /* Successfully replaced the value.  */
+         break;
+
+       /* Prepare for the next round.  */
+       cancelhandling = curval;
+      }
+
+  buffer->__canceltype = (cancelhandling & CANCELTYPE_BITMASK
+                         ? PTHREAD_CANCEL_ASYNCHRONOUS
+                         : PTHREAD_CANCEL_DEFERRED);
+
+  THREAD_SETMEM (self, cleanup, buffer);
+}
+strong_alias (_pthread_cleanup_push_defer, __pthread_cleanup_push_defer)
+
+
+void
+_pthread_cleanup_pop_restore (buffer, execute)
+     struct _pthread_cleanup_buffer *buffer;
+     int execute;
+{
+  struct pthread *self = THREAD_SELF;
+
+  THREAD_SETMEM (self, cleanup, buffer->__prev);
+
+  int cancelhandling;
+  if (__builtin_expect (buffer->__canceltype != PTHREAD_CANCEL_DEFERRED, 0)
+      && ((cancelhandling = THREAD_GETMEM (self, cancelhandling))
+         & CANCELTYPE_BITMASK) == 0)
+    {
+      while (1)
+       {
+         int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+                                                 cancelhandling
+                                                 | CANCELTYPE_BITMASK,
+                                                 cancelhandling);
+         if (__builtin_expect (curval == cancelhandling, 1))
+           /* Successfully replaced the value.  */
+           break;
+
+         /* Prepare for the next round.  */
+         cancelhandling = curval;
+       }
+
+      CANCELLATION_P (self);
+    }
+
+  /* If necessary call the cleanup routine after we removed the
+     current cleanup block from the list.  */
+  if (execute)
+    buffer->__routine (buffer->__arg);
+}
+strong_alias (_pthread_cleanup_pop_restore, __pthread_cleanup_pop_restore)
diff --git a/libpthread/nptl/cleanup_routine.c b/libpthread/nptl/cleanup_routine.c
new file mode 100644 (file)
index 0000000..cbf2318
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@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 <pthread.h>
+
+
+void
+__pthread_cleanup_routine (struct __pthread_cleanup_frame *f)
+{
+  if (f->__do_it)
+    f->__cancel_routine (f->__cancel_arg);
+}
diff --git a/libpthread/nptl/cond-perf.c b/libpthread/nptl/cond-perf.c
new file mode 100644 (file)
index 0000000..e37914e
--- /dev/null
@@ -0,0 +1,103 @@
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <atomic.h>
+
+static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mut1 = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER;
+
+static bool last_round;
+static int ntogo;
+static bool alldone;
+
+
+static void *
+cons (void *arg)
+{
+  pthread_mutex_lock (&mut1);
+
+  do
+    {
+      if (atomic_decrement_and_test (&ntogo))
+       {
+         pthread_mutex_lock (&mut2);
+         alldone = true;
+         pthread_cond_signal (&cond2);
+         pthread_mutex_unlock (&mut2);
+       }
+
+      pthread_cond_wait (&cond1, &mut1);
+    }
+  while (! last_round);
+
+  pthread_mutex_unlock (&mut1);
+
+  return NULL;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int opt;
+  int err;
+  int nthreads = 10;
+  int nrounds = 100;
+  bool keeplock = false;
+
+  while ((opt = getopt (argc, argv, "n:r:k")) != -1)
+    switch (opt)
+      {
+      case 'n':
+       nthreads = atol (optarg);
+       break;
+      case 'r':
+       nrounds = atol (optarg);
+       break;
+      case 'k':
+       keeplock = true;
+       break;
+      }
+
+  ntogo = nthreads;
+
+  pthread_t th[nthreads];
+  int i;
+  for (i = 0; __builtin_expect (i < nthreads, 1); ++i)
+    if (__builtin_expect ((err = pthread_create (&th[i], NULL, cons, (void *) (long) i)) != 0, 0))
+      printf ("pthread_create: %s\n", strerror (err));
+
+  for (i = 0; __builtin_expect (i < nrounds, 1); ++i)
+    {
+      pthread_mutex_lock (&mut2);
+      while (! alldone)
+       pthread_cond_wait (&cond2, &mut2);
+      pthread_mutex_unlock (&mut2);
+
+      pthread_mutex_lock (&mut1);
+      if (! keeplock)
+       pthread_mutex_unlock (&mut1);
+
+      ntogo = nthreads;
+      alldone = false;
+      if (i + 1 >= nrounds)
+       last_round = true;
+
+      pthread_cond_broadcast (&cond1);
+
+      if (keeplock)
+       pthread_mutex_unlock (&mut1);
+    }
+
+  for (i = 0; i < nthreads; ++i)
+    if ((err = pthread_join (th[i], NULL)) != 0)
+      printf ("pthread_create: %s\n", strerror (err));
+
+  return 0;
+}
diff --git a/libpthread/nptl/descr.h b/libpthread/nptl/descr.h
new file mode 100644 (file)
index 0000000..454bb2a
--- /dev/null
@@ -0,0 +1,260 @@
+/* Copyright (C) 2002, 2003, 2004 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 _DESCR_H
+#define _DESCR_H       1
+
+#include <limits.h>
+#include <sched.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <hp-timing.h>
+#include <list.h>
+#include <lowlevellock.h>
+#include <pthreaddef.h>
+#include <dl-sysdep.h>
+#include "../nptl_db/thread_db.h"
+#include <tls.h>
+#ifdef HAVE_FORCED_UNWIND
+# include <unwind.h>
+#endif
+#define __need_res_state
+#include <resolv.h>
+
+#ifndef TCB_ALIGNMENT
+# define TCB_ALIGNMENT sizeof (double)
+#endif
+
+
+/* We keep thread specific data in a special data structure, a two-level
+   array.  The top-level array contains pointers to dynamically allocated
+   arrays of a certain number of data pointers.  So we can implement a
+   sparse array.  Each dynamic second-level array has
+        PTHREAD_KEY_2NDLEVEL_SIZE
+   entries.  This value shouldn't be too large.  */
+#define PTHREAD_KEY_2NDLEVEL_SIZE       32
+
+/* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE
+   keys in each subarray.  */
+#define PTHREAD_KEY_1STLEVEL_SIZE \
+  ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \
+   / PTHREAD_KEY_2NDLEVEL_SIZE)
+
+
+
+
+/* Internal version of the buffer to store cancellation handler
+   information.  */
+struct pthread_unwind_buf
+{
+  struct
+  {
+    __jmp_buf jmp_buf;
+    int mask_was_saved;
+  } cancel_jmp_buf[1];
+
+  union
+  {
+    /* This is the placeholder of the public version.  */
+    void *pad[4];
+
+    struct
+    {
+      /* Pointer to the previous cleanup buffer.  */
+      struct pthread_unwind_buf *prev;
+
+      /* Backward compatibility: state of the old-style cleanup
+        handler at the time of the previous new-style cleanup handler
+        installment.  */
+      struct _pthread_cleanup_buffer *cleanup;
+
+      /* Cancellation type before the push call.  */
+      int canceltype;
+    } data;
+  } priv;
+};
+
+
+/* Opcodes and data types for communication with the signal handler to
+   change user/group IDs.  */
+struct xid_command
+{
+  int syscall_no;
+  long id[3];
+  volatile int cntr;
+};
+
+
+/* Thread descriptor data structure.  */
+struct pthread
+{
+  union
+  {
+#if !TLS_DTV_AT_TP
+    /* This overlaps the TCB as used for TLS without threads (see tls.h).  */
+    tcbhead_t header;
+#else
+    struct
+    {
+      int multiple_threads;
+    } header;
+#endif
+
+    /* This extra padding has no special purpose, and this structure layout
+       is private and subject to change without affecting the official ABI.
+       We just have it here in case it might be convenient for some
+       implementation-specific instrumentation hack or suchlike.  */
+    void *__padding[16];
+  };
+
+  /* This descriptor's link on the `stack_used' or `__stack_user' list.  */
+  list_t list;
+
+  /* Thread ID - which is also a 'is this thread descriptor (and
+     therefore stack) used' flag.  */
+  pid_t tid;
+
+  /* Process ID - thread group ID in kernel speak.  */
+  pid_t pid;
+
+  /* List of cleanup buffers.  */
+  struct _pthread_cleanup_buffer *cleanup;
+
+  /* Unwind information.  */
+  struct pthread_unwind_buf *cleanup_jmp_buf;
+#define HAVE_CLEANUP_JMP_BUF
+
+  /* Flags determining processing of cancellation.  */
+  int cancelhandling;
+  /* Bit set if cancellation is disabled.  */
+#define CANCELSTATE_BIT                0
+#define CANCELSTATE_BITMASK    0x01
+  /* Bit set if asynchronous cancellation mode is selected.  */
+#define CANCELTYPE_BIT         1
+#define CANCELTYPE_BITMASK     0x02
+  /* Bit set if canceling has been initiated.  */
+#define CANCELING_BIT          2
+#define CANCELING_BITMASK      0x04
+  /* Bit set if canceled.  */
+#define CANCELED_BIT           3
+#define CANCELED_BITMASK       0x08
+  /* Bit set if thread is exiting.  */
+#define EXITING_BIT            4
+#define EXITING_BITMASK                0x10
+  /* Bit set if thread terminated and TCB is freed.  */
+#define TERMINATED_BIT         5
+#define TERMINATED_BITMASK     0x20
+  /* Mask for the rest.  Helps the compiler to optimize.  */
+#define CANCEL_RESTMASK                0xffffffc0
+
+#define CANCEL_ENABLED_AND_CANCELED(value) \
+  (((value) & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK              \
+              | CANCEL_RESTMASK | TERMINATED_BITMASK)) == CANCELED_BITMASK)
+#define CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS(value) \
+  (((value) & (CANCELSTATE_BITMASK | CANCELTYPE_BITMASK | CANCELED_BITMASK    \
+              | EXITING_BITMASK | CANCEL_RESTMASK | TERMINATED_BITMASK))     \
+   == (CANCELTYPE_BITMASK | CANCELED_BITMASK))
+
+  /* We allocate one block of references here.  This should be enough
+     to avoid allocating any memory dynamically for most applications.  */
+  struct pthread_key_data
+  {
+    /* Sequence number.  We use uintptr_t to not require padding on
+       32- and 64-bit machines.  On 64-bit machines it helps to avoid
+       wrapping, too.  */
+    uintptr_t seq;
+
+    /* Data pointer.  */
+    void *data;
+  } specific_1stblock[PTHREAD_KEY_2NDLEVEL_SIZE];
+
+  /* Flag which is set when specific data is set.  */
+  bool specific_used;
+
+  /* Two-level array for the thread-specific data.  */
+  struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
+
+  /* True if events must be reported.  */
+  bool report_events;
+
+  /* True if the user provided the stack.  */
+  bool user_stack;
+
+  /* True if thread must stop at startup time.  */
+  bool stopped_start;
+
+  /* Lock to synchronize access to the descriptor.  */
+  lll_lock_t lock;
+
+#if HP_TIMING_AVAIL
+  /* Offset of the CPU clock at start thread start time.  */
+  hp_timing_t cpuclock_offset;
+#endif
+
+  /* If the thread waits to join another one the ID of the latter is
+     stored here.
+
+     In case a thread is detached this field contains a pointer of the
+     TCB if the thread itself.  This is something which cannot happen
+     in normal operation.  */
+  struct pthread *joinid;
+  /* Check whether a thread is detached.  */
+#define IS_DETACHED(pd) ((pd)->joinid == (pd))
+
+  /* Flags.  Including those copied from the thread attribute.  */
+  int flags;
+
+  /* The result of the thread function.  */
+  void *result;
+
+  /* Scheduling parameters for the new thread.  */
+  struct sched_param schedparam;
+  int schedpolicy;
+
+  /* Start position of the code to be executed and the argument passed
+     to the function.  */
+  void *(*start_routine) (void *);
+  void *arg;
+
+  /* Debug state.  */
+  td_eventbuf_t eventbuf;
+  /* Next descriptor with a pending event.  */
+  struct pthread *nextevent;
+
+#ifdef HAVE_FORCED_UNWIND
+  /* Machine-specific unwind info.  */
+  struct _Unwind_Exception exc;
+#endif
+
+  /* If nonzero pointer to area allocated for the stack and its
+     size.  */
+  void *stackblock;
+  size_t stackblock_size;
+  /* Size of the included guard area.  */
+  size_t guardsize;
+  /* This is what the user specified and what we will report.  */
+  size_t reported_guardsize;
+
+  /* Resolver state.  */
+  struct __res_state res;
+} __attribute ((aligned (TCB_ALIGNMENT)));
+
+
+#endif /* descr.h */
diff --git a/libpthread/nptl/eintr.c b/libpthread/nptl/eintr.c
new file mode 100644 (file)
index 0000000..933c5d8
--- /dev/null
@@ -0,0 +1,89 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@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 <pthread.h>
+#include <signal.h>
+#include <unistd.h>
+
+
+static int the_sig;
+
+
+static void
+eintr_handler (int sig)
+{
+  if (sig != the_sig)
+    {
+      write (STDOUT_FILENO, "eintr_handler: signal number wrong\n", 35);
+      _exit (1);
+    }
+  write (STDOUT_FILENO, ".", 1);
+}
+
+
+static void *
+eintr_source (void *arg)
+{
+  struct timespec ts = { .tv_sec = 0, .tv_nsec = 500000 };
+
+  if (arg == NULL)
+    {
+      sigset_t ss;
+      sigemptyset (&ss);
+      sigaddset (&ss, the_sig);
+      pthread_sigmask (SIG_BLOCK, &ss, NULL);
+    }
+
+  while (1)
+    {
+      if (arg != NULL)
+       pthread_kill (*(pthread_t *) arg, the_sig);
+      else
+       kill (getpid (), the_sig);
+
+      nanosleep (&ts, NULL);
+    }
+
+  /* NOTREACHED */
+  return NULL;
+}
+
+
+static void
+setup_eintr (int sig, pthread_t *thp)
+{
+  struct sigaction sa;
+  sigemptyset (&sa.sa_mask);
+  sa.sa_flags = 0;
+  sa.sa_handler = eintr_handler;
+  if (sigaction (sig, &sa, NULL) != 0)
+    {
+      puts ("setup_eintr: sigaction failed");
+      exit (1);
+    }
+  the_sig = sig;
+
+  /* Create the thread which will fire off the signals.  */
+  pthread_t th;
+  if (pthread_create (&th, NULL, eintr_source, thp) != 0)
+    {
+      puts ("setup_eintr: pthread_create failed");
+      exit (1);
+    }
+}
diff --git a/libpthread/nptl/events.c b/libpthread/nptl/events.c
new file mode 100644 (file)
index 0000000..df97e54
--- /dev/null
@@ -0,0 +1,34 @@
+/* Event functions used while debugging.
+   Copyright (C) 1999, 2000, 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* The functions contained here do nothing, they just return.  */
+
+#include "pthreadP.h"
+
+void
+__nptl_create_event (void)
+{
+}
+hidden_def (__nptl_create_event)
+
+void
+__nptl_death_event (void)
+{
+}
+hidden_def (__nptl_death_event)
diff --git a/libpthread/nptl/forward.c b/libpthread/nptl/forward.c
new file mode 100644 (file)
index 0000000..e5f93d4
--- /dev/null
@@ -0,0 +1,203 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <dlfcn.h>
+#include <pthreadP.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#include <shlib-compat.h>
+#include <atomic.h>
+#include <sysdep.h>
+
+
+/* Pointers to the libc functions.  */
+struct pthread_functions __libc_pthread_functions attribute_hidden;
+
+
+#define FORWARD2(name, rettype, decl, params, defaction) \
+rettype                                                                              \
+name decl                                                                    \
+{                                                                            \
+  if (__libc_pthread_functions.ptr_##name == NULL)                           \
+    defaction;                                                               \
+                                                                             \
+  return __libc_pthread_functions.ptr_##name params;                         \
+}
+
+#define FORWARD(name, decl, params, defretval) \
+  FORWARD2 (name, int, decl, params, return defretval)
+
+
+FORWARD (pthread_attr_destroy, (pthread_attr_t *attr), (attr), 0)
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_1)
+FORWARD (__pthread_attr_init_2_0, (pthread_attr_t *attr), (attr), 0)
+compat_symbol (libc, __pthread_attr_init_2_0, pthread_attr_init, GLIBC_2_0);
+#endif
+
+FORWARD (__pthread_attr_init_2_1, (pthread_attr_t *attr), (attr), 0)
+versioned_symbol (libc, __pthread_attr_init_2_1, pthread_attr_init, GLIBC_2_1);
+
+FORWARD (pthread_attr_getdetachstate,
+        (const pthread_attr_t *attr, int *detachstate), (attr, detachstate),
+        0)
+FORWARD (pthread_attr_setdetachstate, (pthread_attr_t *attr, int detachstate),
+        (attr, detachstate), 0)
+
+FORWARD (pthread_attr_getinheritsched,
+        (const pthread_attr_t *attr, int *inherit), (attr, inherit), 0)
+FORWARD (pthread_attr_setinheritsched, (pthread_attr_t *attr, int inherit),
+        (attr, inherit), 0)
+
+FORWARD (pthread_attr_getschedparam,
+        (const pthread_attr_t *attr, struct sched_param *param),
+        (attr, param), 0)
+FORWARD (pthread_attr_setschedparam,
+        (pthread_attr_t *attr, const struct sched_param *param),
+        (attr, param), 0)
+
+FORWARD (pthread_attr_getschedpolicy,
+        (const pthread_attr_t *attr, int *policy), (attr, policy), 0)
+FORWARD (pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy),
+        (attr, policy), 0)
+
+FORWARD (pthread_attr_getscope,
+        (const pthread_attr_t *attr, int *scope), (attr, scope), 0)
+FORWARD (pthread_attr_setscope, (pthread_attr_t *attr, int scope),
+        (attr, scope), 0)
+
+
+FORWARD (pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), 0)
+FORWARD (pthread_condattr_init, (pthread_condattr_t *attr), (attr), 0)
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
+FORWARD2 (__pthread_cond_broadcast_2_0, int attribute_compat_text_section,
+         (pthread_cond_2_0_t *cond), (cond), return 0)
+compat_symbol (libc, __pthread_cond_broadcast_2_0, pthread_cond_broadcast,
+              GLIBC_2_0);
+#endif
+FORWARD (__pthread_cond_broadcast, (pthread_cond_t *cond), (cond), 0)
+versioned_symbol (libc, __pthread_cond_broadcast, pthread_cond_broadcast,
+                 GLIBC_2_3_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
+FORWARD2 (__pthread_cond_destroy_2_0, int attribute_compat_text_section,
+         (pthread_cond_2_0_t *cond), (cond), return 0)
+compat_symbol (libc, __pthread_cond_destroy_2_0, pthread_cond_destroy,
+              GLIBC_2_0);
+#endif
+FORWARD (__pthread_cond_destroy, (pthread_cond_t *cond), (cond), 0)
+versioned_symbol (libc, __pthread_cond_destroy, pthread_cond_destroy,
+                 GLIBC_2_3_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
+FORWARD2 (__pthread_cond_init_2_0, int attribute_compat_text_section,
+         (pthread_cond_2_0_t *cond, const pthread_condattr_t *cond_attr),
+         (cond, cond_attr), return 0)
+compat_symbol (libc, __pthread_cond_init_2_0, pthread_cond_init, GLIBC_2_0);
+#endif
+FORWARD (__pthread_cond_init,
+        (pthread_cond_t *cond, const pthread_condattr_t *cond_attr),
+        (cond, cond_attr), 0)
+versioned_symbol (libc, __pthread_cond_init, pthread_cond_init, GLIBC_2_3_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
+FORWARD2 (__pthread_cond_signal_2_0, int attribute_compat_text_section,
+         (pthread_cond_2_0_t *cond), (cond), return 0)
+compat_symbol (libc, __pthread_cond_signal_2_0, pthread_cond_signal,
+              GLIBC_2_0);
+#endif
+FORWARD (__pthread_cond_signal, (pthread_cond_t *cond), (cond), 0)
+versioned_symbol (libc, __pthread_cond_signal, pthread_cond_signal,
+                 GLIBC_2_3_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
+FORWARD2 (__pthread_cond_wait_2_0, int attribute_compat_text_section,
+         (pthread_cond_2_0_t *cond, pthread_mutex_t *mutex), (cond, mutex),
+         return 0)
+compat_symbol (libc, __pthread_cond_wait_2_0, pthread_cond_wait,
+              GLIBC_2_0);
+#endif
+FORWARD (__pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
+        (cond, mutex), 0)
+versioned_symbol (libc, __pthread_cond_wait, pthread_cond_wait,
+                 GLIBC_2_3_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
+FORWARD2 (__pthread_cond_timedwait_2_0, int attribute_compat_text_section,
+         (pthread_cond_2_0_t *cond, pthread_mutex_t *mutex,
+          const struct timespec *abstime), (cond, mutex, abstime),
+         return 0)
+compat_symbol (libc, __pthread_cond_timedwait_2_0, pthread_cond_timedwait,
+              GLIBC_2_0);
+#endif
+FORWARD (__pthread_cond_timedwait,
+        (pthread_cond_t *cond, pthread_mutex_t *mutex,
+         const struct timespec *abstime), (cond, mutex, abstime), 0)
+versioned_symbol (libc, __pthread_cond_timedwait, pthread_cond_timedwait,
+                 GLIBC_2_3_2);
+
+
+FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
+        (thread1, thread2), 1)
+
+
+/* Use an alias to avoid warning, as pthread_exit is declared noreturn.  */
+FORWARD2 (__pthread_exit, void, (void *retval), (retval), exit (EXIT_SUCCESS))
+strong_alias (__pthread_exit, pthread_exit);
+
+
+FORWARD (pthread_getschedparam,
+        (pthread_t target_thread, int *policy, struct sched_param *param),
+        (target_thread, policy, param), 0)
+FORWARD (pthread_setschedparam,
+        (pthread_t target_thread, int policy,
+         const struct sched_param *param), (target_thread, policy, param), 0)
+
+
+FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0)
+
+FORWARD (pthread_mutex_init,
+        (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
+        (mutex, mutexattr), 0)
+
+FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
+
+FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
+
+
+FORWARD2 (pthread_self, pthread_t, (void), (), return 0)
+
+
+FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate),
+        0)
+
+FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0)
+
+#define return /* value is void */
+FORWARD2(__pthread_unwind,
+        void attribute_hidden __attribute ((noreturn)) __cleanup_fct_attribute
+        attribute_compat_text_section,
+        (__pthread_unwind_buf_t *buf), (buf), {
+                      /* We cannot call abort() here.  */
+                      INTERNAL_SYSCALL_DECL (err);
+                      INTERNAL_SYSCALL (kill, err, 1, SIGKILL);
+                    })
+#undef return
diff --git a/libpthread/nptl/herrno.c b/libpthread/nptl/herrno.c
new file mode 100644 (file)
index 0000000..6e8339d
--- /dev/null
@@ -0,0 +1,35 @@
+/* Copyright (C) 1996,97,98,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 <features.h>
+#include <netdb.h>
+#undef h_errno
+
+#include <tls.h>
+
+/* We need to have the error status variable of the resolver
+   accessible in the libc.  */
+extern __thread int h_errno;
+
+
+/* When threaded, h_errno may be a per-thread variable.  */
+int *
+__h_errno_location (void)
+{
+  return &h_errno;
+}
diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
new file mode 100644 (file)
index 0000000..86745af
--- /dev/null
@@ -0,0 +1,345 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <assert.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <pthreadP.h>
+#include <atomic.h>
+#include <ldsodefs.h>
+#include <tls.h>
+#include <fork.h>
+#include <version.h>
+#include <shlib-compat.h>
+#include <smp.h>
+#include <lowlevellock.h>
+
+
+#ifndef __NR_set_tid_address
+/* XXX For the time being...  Once we can rely on the kernel headers
+   having the definition remove these lines.  */
+#if defined __s390__
+# define __NR_set_tid_address  252
+#elif defined __ia64__
+# define __NR_set_tid_address  1233
+#elif defined __i386__
+# define __NR_set_tid_address  258
+#elif defined __x86_64__
+# define __NR_set_tid_address  218
+#elif defined __powerpc__
+# define __NR_set_tid_address  232
+#elif defined __sparc__
+# define __NR_set_tid_address  166
+#else
+# error "define __NR_set_tid_address"
+#endif
+#endif
+
+
+/* Size and alignment of static TLS block.  */
+size_t __static_tls_size;
+size_t __static_tls_align_m1;
+
+/* Version of the library, used in libthread_db to detect mismatches.  */
+static const char nptl_version[] __attribute_used__ = VERSION;
+
+
+#if defined USE_TLS && !defined SHARED
+extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
+#endif
+
+
+#ifdef SHARED
+static const struct pthread_functions pthread_functions =
+  {
+    .ptr_pthread_attr_destroy = __pthread_attr_destroy,
+# if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+    .ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0,
+# endif
+    .ptr___pthread_attr_init_2_1 = __pthread_attr_init_2_1,
+    .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate,
+    .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate,
+    .ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched,
+    .ptr_pthread_attr_setinheritsched = __pthread_attr_setinheritsched,
+    .ptr_pthread_attr_getschedparam = __pthread_attr_getschedparam,
+    .ptr_pthread_attr_setschedparam = __pthread_attr_setschedparam,
+    .ptr_pthread_attr_getschedpolicy = __pthread_attr_getschedpolicy,
+    .ptr_pthread_attr_setschedpolicy = __pthread_attr_setschedpolicy,
+    .ptr_pthread_attr_getscope = __pthread_attr_getscope,
+    .ptr_pthread_attr_setscope = __pthread_attr_setscope,
+    .ptr_pthread_condattr_destroy = __pthread_condattr_destroy,
+    .ptr_pthread_condattr_init = __pthread_condattr_init,
+    .ptr___pthread_cond_broadcast = __pthread_cond_broadcast,
+    .ptr___pthread_cond_destroy = __pthread_cond_destroy,
+    .ptr___pthread_cond_init = __pthread_cond_init,
+    .ptr___pthread_cond_signal = __pthread_cond_signal,
+    .ptr___pthread_cond_wait = __pthread_cond_wait,
+    .ptr___pthread_cond_timedwait = __pthread_cond_timedwait,
+# if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+    .ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0,
+    .ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0,
+    .ptr___pthread_cond_init_2_0 = __pthread_cond_init_2_0,
+    .ptr___pthread_cond_signal_2_0 = __pthread_cond_signal_2_0,
+    .ptr___pthread_cond_wait_2_0 = __pthread_cond_wait_2_0,
+    .ptr___pthread_cond_timedwait_2_0 = __pthread_cond_timedwait_2_0,
+# endif
+    .ptr_pthread_equal = __pthread_equal,
+    .ptr___pthread_exit = __pthread_exit,
+    .ptr_pthread_getschedparam = __pthread_getschedparam,
+    .ptr_pthread_setschedparam = __pthread_setschedparam,
+    .ptr_pthread_mutex_destroy = INTUSE(__pthread_mutex_destroy),
+    .ptr_pthread_mutex_init = INTUSE(__pthread_mutex_init),
+    .ptr_pthread_mutex_lock = INTUSE(__pthread_mutex_lock),
+    .ptr_pthread_mutex_unlock = INTUSE(__pthread_mutex_unlock),
+    .ptr_pthread_self = __pthread_self,
+    .ptr_pthread_setcancelstate = __pthread_setcancelstate,
+    .ptr_pthread_setcanceltype = __pthread_setcanceltype,
+    .ptr___pthread_cleanup_upto = __pthread_cleanup_upto,
+    .ptr___pthread_once = __pthread_once_internal,
+    .ptr___pthread_rwlock_rdlock = __pthread_rwlock_rdlock_internal,
+    .ptr___pthread_rwlock_wrlock = __pthread_rwlock_wrlock_internal,
+    .ptr___pthread_rwlock_unlock = __pthread_rwlock_unlock_internal,
+    .ptr___pthread_key_create = __pthread_key_create_internal,
+    .ptr___pthread_getspecific = __pthread_getspecific_internal,
+    .ptr___pthread_setspecific = __pthread_setspecific_internal,
+    .ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer,
+    .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore,
+    .ptr_nthreads = &__nptl_nthreads,
+    .ptr___pthread_unwind = &__pthread_unwind,
+    .ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
+    .ptr__nptl_setxid = __nptl_setxid
+  };
+# define ptr_pthread_functions &pthread_functions
+#else
+# define ptr_pthread_functions NULL
+#endif
+
+
+/* For asynchronous cancellation we use a signal.  This is the handler.  */
+static void
+sigcancel_handler (int sig, siginfo_t *si, void *ctx)
+{
+  /* Safety check.  It would be possible to call this function for
+     other signals and send a signal from another process.  This is not
+     correct and might even be a security problem.  Try to catch as
+     many incorrect invocations as possible.  */
+  if (sig != SIGCANCEL
+#ifdef __ASSUME_CORRECT_SI_PID
+      /* Kernels before 2.5.75 stored the thread ID and not the process
+        ID in si_pid so we skip this test.  */
+      || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)
+#endif
+      || si->si_code != SI_TKILL)
+    return;
+
+  struct pthread *self = THREAD_SELF;
+
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+  while (1)
+    {
+      /* We are canceled now.  When canceled by another thread this flag
+        is already set but if the signal is directly send (internally or
+        from another process) is has to be done here.  */
+      int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
+
+      if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
+       /* Already canceled or exiting.  */
+       break;
+
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+                                             oldval);
+      if (curval == oldval)
+       {
+         /* Set the return value.  */
+         THREAD_SETMEM (self, result, PTHREAD_CANCELED);
+
+         /* Make sure asynchronous cancellation is still enabled.  */
+         if ((newval & CANCELTYPE_BITMASK) != 0)
+           /* Run the registered destructors and terminate the thread.  */
+           __do_cancel ();
+
+         break;
+       }
+
+      oldval = curval;
+    }
+}
+
+
+struct xid_command *__xidcmd attribute_hidden;
+
+/* For asynchronous cancellation we use a signal.  This is the handler.  */
+static void
+sighandler_setxid (int sig, siginfo_t *si, void *ctx)
+{
+  /* Safety check.  It would be possible to call this function for
+     other signals and send a signal from another process.  This is not
+     correct and might even be a security problem.  Try to catch as
+     many incorrect invocations as possible.  */
+  if (sig != SIGSETXID
+#ifdef __ASSUME_CORRECT_SI_PID
+      /* Kernels before 2.5.75 stored the thread ID and not the process
+        ID in si_pid so we skip this test.  */
+      || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)
+#endif
+      || si->si_code != SI_TKILL)
+    return;
+
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL_NCS (__xidcmd->syscall_no, err, 3, __xidcmd->id[0],
+                       __xidcmd->id[1], __xidcmd->id[2]);
+
+  if (atomic_decrement_val (&__xidcmd->cntr) == 0)
+    lll_futex_wake (&__xidcmd->cntr, 1);
+}
+
+
+/* When using __thread for this, we do it in libc so as not
+   to give libpthread its own TLS segment just for this.  */
+extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
+
+
+void
+__pthread_initialize_minimal_internal (void)
+{
+#ifndef SHARED
+  /* Unlike in the dynamically linked case the dynamic linker has not
+     taken care of initializing the TLS data structures.  */
+  __libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN);
+
+  /* We must prevent gcc from being clever and move any of the
+     following code ahead of the __libc_setup_tls call.  This function
+     will initialize the thread register which is subsequently
+     used.  */
+  __asm __volatile ("");
+#endif
+
+  /* Minimal initialization of the thread descriptor.  */
+  struct pthread *pd = THREAD_SELF;
+  INTERNAL_SYSCALL_DECL (err);
+  pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid);
+  THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]);
+  THREAD_SETMEM (pd, user_stack, true);
+  if (LLL_LOCK_INITIALIZER != 0)
+    THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER);
+#if HP_TIMING_AVAIL
+  THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
+#endif
+
+  /* Set initial thread's stack block from 0 up to __libc_stack_end.
+     It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
+     purposes this is good enough.  */
+  THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end);
+
+  /* Initialize the list of all running threads with the main thread.  */
+  INIT_LIST_HEAD (&__stack_user);
+  list_add (&pd->list, &__stack_user);
+
+
+  /* Install the cancellation signal handler.  If for some reason we
+     cannot install the handler we do not abort.  Maybe we should, but
+     it is only asynchronous cancellation which is affected.  */
+  struct sigaction sa;
+  sa.sa_sigaction = sigcancel_handler;
+  sa.sa_flags = SA_SIGINFO;
+  __sigemptyset (&sa.sa_mask);
+
+  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
+
+  /* Install the handle to change the threads' uid/gid.  */
+  sa.sa_sigaction = sighandler_setxid;
+  sa.sa_flags = SA_SIGINFO | SA_RESTART;
+
+  (void) __libc_sigaction (SIGSETXID, &sa, NULL);
+
+  /* The parent process might have left the signals blocked.  Just in
+     case, unblock it.  We reuse the signal mask in the sigaction
+     structure.  It is already cleared.  */
+  __sigaddset (&sa.sa_mask, SIGCANCEL);
+  __sigaddset (&sa.sa_mask, SIGSETXID);
+  (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &sa.sa_mask,
+                          NULL, _NSIG / 8);
+
+
+  /* Determine the default allowed stack size.  This is the size used
+     in case the user does not specify one.  */
+  struct rlimit limit;
+  if (getrlimit (RLIMIT_STACK, &limit) != 0
+      || limit.rlim_cur == RLIM_INFINITY)
+    /* The system limit is not usable.  Use an architecture-specific
+       default.  */
+    __default_stacksize = ARCH_STACK_DEFAULT_SIZE;
+  else if (limit.rlim_cur < PTHREAD_STACK_MIN)
+    /* The system limit is unusably small.
+       Use the minimal size acceptable.  */
+    __default_stacksize = PTHREAD_STACK_MIN;
+  else
+    {
+      /* Round the resource limit up to page size.  */
+      const uintptr_t pagesz = __sysconf (_SC_PAGESIZE);
+      __default_stacksize = (limit.rlim_cur + pagesz - 1) & -pagesz;
+    }
+
+  /* Get the size of the static and alignment requirements for the TLS
+     block.  */
+  size_t static_tls_align;
+  _dl_get_tls_static_info (&__static_tls_size, &static_tls_align);
+
+  /* Make sure the size takes all the alignments into account.  */
+  if (STACK_ALIGN > static_tls_align)
+    static_tls_align = STACK_ALIGN;
+  __static_tls_align_m1 = static_tls_align - 1;
+
+  __static_tls_size = roundup (__static_tls_size, static_tls_align);
+
+#ifdef SHARED
+  /* Transfer the old value from the dynamic linker's internal location.  */
+  *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
+  GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+
+  /* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
+     keep the lock count from the ld.so implementation.  */
+  GL(dl_rtld_lock_recursive) = (void *) INTUSE (__pthread_mutex_lock);
+  GL(dl_rtld_unlock_recursive) = (void *) INTUSE (__pthread_mutex_unlock);
+  unsigned int rtld_lock_count = GL(dl_load_lock).mutex.__data.__count;
+  GL(dl_load_lock).mutex.__data.__count = 0;
+  while (rtld_lock_count-- > 0)
+    INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex);
+
+  GL(dl_make_stack_executable_hook) = &__make_stacks_executable;
+#endif
+
+  GL(dl_init_static_tls) = &__pthread_init_static_tls;
+
+  /* Register the fork generation counter with the libc.  */
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+  __libc_multiple_threads_ptr =
+#endif
+    __libc_pthread_init (&__fork_generation, __reclaim_stacks,
+                        ptr_pthread_functions);
+
+  /* Determine whether the machine is SMP or not.  */
+  __is_smp = is_smp_system ();
+}
+strong_alias (__pthread_initialize_minimal_internal,
+             __pthread_initialize_minimal)
diff --git a/libpthread/nptl/libc-cancellation.c b/libpthread/nptl/libc-cancellation.c
new file mode 100644 (file)
index 0000000..c9237e0
--- /dev/null
@@ -0,0 +1,116 @@
+/* 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.  */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+#include "atomic.h"
+#include <bits/libc-lock.h>
+
+
+#ifndef NOT_IN_libc
+
+/* The next two functions are similar to pthread_setcanceltype() but
+   more specialized for the use in the cancelable functions like write().
+   They do not need to check parameters etc.  */
+int
+attribute_hidden
+__libc_enable_asynccancel (void)
+{
+  struct pthread *self = THREAD_SELF;
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+
+  while (1)
+    {
+      int newval = oldval | CANCELTYPE_BITMASK;
+
+      if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
+       {
+         /* If we are already exiting or if PTHREAD_CANCEL_DISABLED,
+            stop right here.  */
+         if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0)
+           break;
+
+         int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+                                                 newval, oldval);
+         if (__builtin_expect (curval != oldval, 0))
+           {
+             /* Somebody else modified the word, try again.  */
+             oldval = curval;
+             continue;
+           }
+
+         THREAD_SETMEM (self, result, PTHREAD_CANCELED);
+
+         __do_cancel ();
+
+         /* NOTREACHED */
+       }
+
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+                                             oldval);
+      if (__builtin_expect (curval == oldval, 1))
+       break;
+
+      /* Prepare the next round.  */
+      oldval = curval;
+    }
+
+  return oldval;
+}
+
+
+void
+internal_function attribute_hidden
+__libc_disable_asynccancel (int oldtype)
+{
+  /* If asynchronous cancellation was enabled before we do not have
+     anything to do.  */
+  if (oldtype & CANCELTYPE_BITMASK)
+    return;
+
+  struct pthread *self = THREAD_SELF;
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+
+  while (1)
+    {
+      int newval = oldval & ~CANCELTYPE_BITMASK;
+
+      if (newval == oldval)
+       break;
+
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+                                             oldval);
+      if (__builtin_expect (curval == oldval, 1))
+       break;
+
+      /* Prepare the next round.  */
+      oldval = curval;
+    }
+}
+
+
+void
+__libc_cleanup_routine (struct __pthread_cleanup_frame *f)
+{
+  if (f->__do_it)
+    f->__cancel_routine (f->__cancel_arg);
+}
+
+#endif
diff --git a/libpthread/nptl/old_pthread_atfork.c b/libpthread/nptl/old_pthread_atfork.c
new file mode 100644 (file)
index 0000000..768e687
--- /dev/null
@@ -0,0 +1,27 @@
+/* Copyright (C) 2002 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.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_3)
+# define __pthread_atfork __dyn_pthread_atfork
+# include "pthread_atfork.c"
+# undef __pthread_atfork
+compat_symbol (libpthread, __dyn_pthread_atfork, pthread_atfork, GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/old_pthread_cond_broadcast.c b/libpthread/nptl/old_pthread_cond_broadcast.c
new file mode 100644 (file)
index 0000000..3852943
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+#include <atomic.h>
+#include <shlib-compat.h>
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+int
+__pthread_cond_broadcast_2_0 (cond)
+     pthread_cond_2_0_t *cond;
+{
+  if (cond->cond == NULL)
+    {
+      pthread_cond_t *newcond;
+
+#if LLL_MUTEX_LOCK_INITIALIZER == 0
+      newcond = (pthread_cond_t *) calloc (sizeof (pthread_cond_t), 1);
+      if (newcond == NULL)
+       return ENOMEM;
+#else
+      newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+      if (newcond == NULL)
+       return ENOMEM;
+
+      /* Initialize the condvar.  */
+      (void) pthread_cond_init (newcond, NULL);
+#endif
+
+      if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
+       /* Somebody else just initialized the condvar.  */
+       free (newcond);
+    }
+
+  return __pthread_cond_broadcast (cond->cond);
+}
+compat_symbol (libpthread, __pthread_cond_broadcast_2_0,
+              pthread_cond_broadcast, GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/old_pthread_cond_destroy.c b/libpthread/nptl/old_pthread_cond_destroy.c
new file mode 100644 (file)
index 0000000..f6dba11
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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.  */
+
+#include <stdlib.h>
+#include "pthreadP.h"
+#include <shlib-compat.h>
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+int
+__pthread_cond_destroy_2_0 (cond)
+     pthread_cond_2_0_t *cond;
+{
+  /* Free the memory which was eventually allocated.  */
+  free (cond->cond);
+
+  return 0;
+}
+compat_symbol (libpthread, __pthread_cond_destroy_2_0, pthread_cond_destroy,
+              GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/old_pthread_cond_init.c b/libpthread/nptl/old_pthread_cond_init.c
new file mode 100644 (file)
index 0000000..47e68b0
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright (C) 2002, 2003, 2005 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <shlib-compat.h>
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+int
+__pthread_cond_init_2_0 (cond, cond_attr)
+     pthread_cond_2_0_t *cond;
+     const pthread_condattr_t *cond_attr;
+{
+  struct pthread_condattr *icond_attr = (struct pthread_condattr *) cond_attr;
+
+  /* The type of the first argument is actually that of the old, too
+     small pthread_cond_t.  We use only the first word of it, as a
+     pointer.  */
+  cond->cond = NULL;
+
+  /* We can't support PSHARED condvars in the old pthread_cond_*
+     functions and neither clocks other than CLOCK_REALTIME.  */
+  if (icond_attr != NULL && icond_attr->value)
+    return EINVAL;
+
+  return 0;
+}
+compat_symbol (libpthread, __pthread_cond_init_2_0, pthread_cond_init,
+              GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/old_pthread_cond_signal.c b/libpthread/nptl/old_pthread_cond_signal.c
new file mode 100644 (file)
index 0000000..65beb0b
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+#include <atomic.h>
+#include <shlib-compat.h>
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+int
+__pthread_cond_signal_2_0 (cond)
+     pthread_cond_2_0_t *cond;
+{
+  if (cond->cond == NULL)
+    {
+      pthread_cond_t *newcond;
+
+#if LLL_MUTEX_LOCK_INITIALIZER == 0
+      newcond = (pthread_cond_t *) calloc (sizeof (pthread_cond_t), 1);
+      if (newcond == NULL)
+       return ENOMEM;
+#else
+      newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+      if (newcond == NULL)
+       return ENOMEM;
+
+      /* Initialize the condvar.  */
+      (void) pthread_cond_init (newcond, NULL);
+#endif
+
+      if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
+       /* Somebody else just initialized the condvar.  */
+       free (newcond);
+    }
+
+  return __pthread_cond_signal (cond->cond);
+}
+compat_symbol (libpthread, __pthread_cond_signal_2_0, pthread_cond_signal,
+              GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/old_pthread_cond_timedwait.c b/libpthread/nptl/old_pthread_cond_timedwait.c
new file mode 100644 (file)
index 0000000..27c1093
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+#include <atomic.h>
+#include <shlib-compat.h>
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+int
+__pthread_cond_timedwait_2_0 (cond, mutex, abstime)
+     pthread_cond_2_0_t *cond;
+     pthread_mutex_t *mutex;
+     const struct timespec *abstime;
+{
+  if (cond->cond == NULL)
+    {
+      pthread_cond_t *newcond;
+
+#if LLL_MUTEX_LOCK_INITIALIZER == 0
+      newcond = (pthread_cond_t *) calloc (sizeof (pthread_cond_t), 1);
+      if (newcond == NULL)
+       return ENOMEM;
+#else
+      newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+      if (newcond == NULL)
+       return ENOMEM;
+
+      /* Initialize the condvar.  */
+      (void) pthread_cond_init (newcond, NULL);
+#endif
+
+      if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
+       /* Somebody else just initialized the condvar.  */
+       free (newcond);
+    }
+
+  return __pthread_cond_timedwait (cond->cond, mutex, abstime);
+}
+compat_symbol (libpthread, __pthread_cond_timedwait_2_0,
+              pthread_cond_timedwait, GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/old_pthread_cond_wait.c b/libpthread/nptl/old_pthread_cond_wait.c
new file mode 100644 (file)
index 0000000..0a503a1
--- /dev/null
@@ -0,0 +1,59 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+#include <atomic.h>
+#include <shlib-compat.h>
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+int
+__pthread_cond_wait_2_0 (cond, mutex)
+     pthread_cond_2_0_t *cond;
+     pthread_mutex_t *mutex;
+{
+  if (cond->cond == NULL)
+    {
+      pthread_cond_t *newcond;
+
+#if LLL_MUTEX_LOCK_INITIALIZER == 0
+      newcond = (pthread_cond_t *) calloc (sizeof (pthread_cond_t), 1);
+      if (newcond == NULL)
+       return ENOMEM;
+#else
+      newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
+      if (newcond == NULL)
+       return ENOMEM;
+
+      /* Initialize the condvar.  */
+      (void) pthread_cond_init (newcond, NULL);
+#endif
+
+      if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
+       /* Somebody else just initialized the condvar.  */
+       free (newcond);
+    }
+
+  return __pthread_cond_wait (cond->cond, mutex);
+}
+compat_symbol (libpthread, __pthread_cond_wait_2_0, pthread_cond_wait,
+              GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/perf.c b/libpthread/nptl/perf.c
new file mode 100644 (file)
index 0000000..5b920d7
--- /dev/null
@@ -0,0 +1,755 @@
+/* Copyright (C) 2002 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.  */
+
+#define _GNU_SOURCE    1
+#include <argp.h>
+#include <error.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+#ifndef MAX_THREADS
+# define MAX_THREADS           100000
+#endif
+#ifndef DEFAULT_THREADS
+# define DEFAULT_THREADS       50
+#endif
+
+
+#define OPT_TO_THREAD          300
+#define OPT_TO_PROCESS         301
+#define OPT_SYNC_SIGNAL                302
+#define OPT_SYNC_JOIN          303
+#define OPT_TOPLEVEL           304
+
+
+static const struct argp_option options[] =
+  {
+    { NULL, 0, NULL, 0, "\
+This is a test for threads so we allow ther user to selection the number of \
+threads which are used at any one time.  Independently the total number of \
+rounds can be selected.  This is the total number of threads which will have \
+run when the process terminates:" },
+    { "threads", 't', "NUMBER", 0, "Number of threads used at once" },
+    { "starts", 's', "NUMBER", 0, "Total number of working threads" },
+    { "toplevel", OPT_TOPLEVEL, "NUMBER", 0,
+      "Number of toplevel threads which start the other threads; this \
+implies --sync-join" },
+
+    { NULL, 0, NULL, 0, "\
+Each thread can do one of two things: sleep or do work.  The latter is 100% \
+CPU bound.  The work load is the probability a thread does work.  All values \
+from zero to 100 (inclusive) are valid.  How often each thread repeats this \
+can be determined by the number of rounds.  The work cost determines how long \
+each work session (not sleeping) takes.  If it is zero a thread would \
+effectively nothing.  By setting the number of rounds to zero the thread \
+does no work at all and pure thread creation times can be measured." },
+    { "workload", 'w', "PERCENT", 0, "Percentage of time spent working" },
+    { "workcost", 'c', "NUMBER", 0,
+      "Factor in the cost of each round of working" },
+    { "rounds", 'r', "NUMBER", 0, "Number of rounds each thread runs" },
+
+    { NULL, 0, NULL, 0, "\
+There are a number of different methods how thread creation can be \
+synchronized.  Synchronization is necessary since the number of concurrently \
+running threads is limited." },
+    { "sync-signal", OPT_SYNC_SIGNAL, NULL, 0,
+      "Synchronize using a signal (default)" },
+    { "sync-join", OPT_SYNC_JOIN, NULL, 0, "Synchronize using pthread_join" },
+
+    { NULL, 0, NULL, 0, "\
+One parameter for each threads execution is the size of the stack.  If this \
+parameter is not used the system's default stack size is used.  If many \
+threads are used the stack size should be chosen quite small." },
+    { "stacksize", 'S', "BYTES", 0, "Size of threads stack" },
+    { "guardsize", 'g', "BYTES", 0,
+      "Size of stack guard area; must fit into the stack" },
+
+    { NULL, 0, NULL, 0, "Signal options:" },
+    { "to-thread", OPT_TO_THREAD, NULL, 0, "Send signal to main thread" },
+    { "to-process", OPT_TO_PROCESS, NULL, 0,
+      "Send signal to process (default)" },
+
+    { NULL, 0, NULL, 0, "Administrative options:" },
+    { "progress", 'p', NULL, 0, "Show signs of progress" },
+    { "timing", 'T', NULL, 0,
+      "Measure time from startup to the last thread finishing" },
+    { NULL, 0, NULL, 0, NULL }
+  };
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt
+};
+
+
+static unsigned long int threads = DEFAULT_THREADS;
+static unsigned long int workload = 75;
+static unsigned long int workcost = 20;
+static unsigned long int rounds = 10;
+static long int starts = 5000;
+static unsigned long int stacksize;
+static long int guardsize = -1;
+static bool progress;
+static bool timing;
+static bool to_thread;
+static unsigned long int toplevel = 1;
+
+
+static long int running;
+static pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pid_t pid;
+static pthread_t tmain;
+
+static clockid_t cl;
+static struct timespec start_time;
+
+
+static pthread_mutex_t sum_mutex = PTHREAD_MUTEX_INITIALIZER;
+unsigned int sum;
+
+static enum
+  {
+    sync_signal,
+    sync_join
+  }
+sync_method;
+
+
+/* We use 64bit values for the times.  */
+typedef unsigned long long int hp_timing_t;
+
+
+/* Attributes for all created threads.  */
+static pthread_attr_t attr;
+
+
+static void *
+work (void *arg)
+{
+  unsigned long int i;
+  unsigned int state = (unsigned long int) arg;
+
+  for (i = 0; i < rounds; ++i)
+    {
+      /* Determine what to do.  */
+      unsigned int rnum;
+
+      /* Uniform distribution.  */
+      do
+       rnum = rand_r (&state);
+      while (rnum >= UINT_MAX - (UINT_MAX % 100));
+
+      rnum %= 100;
+
+      if (rnum < workload)
+       {
+         int j;
+         int a[4] = { i, rnum, i + rnum, rnum - i };
+
+         if (progress)
+           write (STDERR_FILENO, "c", 1);
+
+         for (j = 0; j < workcost; ++j)
+           {
+             a[0] += a[3] >> 12;
+             a[1] += a[2] >> 20;
+             a[2] += a[1] ^ 0x3423423;
+             a[3] += a[0] - a[1];
+           }
+
+         pthread_mutex_lock (&sum_mutex);
+         sum += a[0] + a[1] + a[2] + a[3];
+         pthread_mutex_unlock (&sum_mutex);
+       }
+      else
+       {
+         /* Just sleep.  */
+         struct timespec tv;
+
+         tv.tv_sec = 0;
+         tv.tv_nsec = 10000000;
+
+         if (progress)
+           write (STDERR_FILENO, "w", 1);
+
+         nanosleep (&tv, NULL);
+       }
+    }
+
+  return NULL;
+}
+
+
+static void *
+thread_function (void *arg)
+{
+  work (arg);
+
+  pthread_mutex_lock (&running_mutex);
+  if (--running <= 0 && starts <= 0)
+    {
+      /* We are done.  */
+      if (progress)
+       write (STDERR_FILENO, "\n", 1);
+
+      if (timing)
+       {
+         struct timespec end_time;
+
+         if (clock_gettime (cl, &end_time) == 0)
+           {
+             end_time.tv_sec -= start_time.tv_sec;
+             end_time.tv_nsec -= start_time.tv_nsec;
+             if (end_time.tv_nsec < 0)
+               {
+                 end_time.tv_nsec += 1000000000;
+                 --end_time.tv_sec;
+               }
+
+             printf ("\nRuntime: %lu.%09lu seconds\n",
+                     (unsigned long int) end_time.tv_sec,
+                     (unsigned long int) end_time.tv_nsec);
+           }
+       }
+
+      printf ("Result: %08x\n", sum);
+
+      exit (0);
+    }
+  pthread_mutex_unlock (&running_mutex);
+
+  if (sync_method == sync_signal)
+    {
+      if (to_thread)
+       /* This code sends a signal to the main thread.  */
+       pthread_kill (tmain, SIGUSR1);
+      else
+       /* Use this code to test sending a signal to the process.  */
+       kill (pid, SIGUSR1);
+    }
+
+  if (progress)
+    write (STDERR_FILENO, "f", 1);
+
+  return NULL;
+}
+
+
+struct start_info
+{
+  unsigned int starts;
+  unsigned int threads;
+};
+
+
+static void *
+start_threads (void *arg)
+{
+  struct start_info *si = arg;
+  unsigned int starts = si->starts;
+  pthread_t ths[si->threads];
+  unsigned int state = starts;
+  unsigned int n;
+  unsigned int i = 0;
+  int err;
+
+  if (progress)
+    write (STDERR_FILENO, "T", 1);
+
+  memset (ths, '\0', sizeof (pthread_t) * si->threads);
+
+  while (starts-- > 0)
+    {
+      if (ths[i] != 0)
+       {
+         /* Wait for the threads in the order they were created.  */
+         err = pthread_join (ths[i], NULL);
+         if (err != 0)
+           error (EXIT_FAILURE, err, "cannot join thread");
+
+         if (progress)
+           write (STDERR_FILENO, "f", 1);
+       }
+
+      err = pthread_create (&ths[i], &attr, work,
+                           (void *) (long) (rand_r (&state) + starts + i));
+
+      if (err != 0)
+       error (EXIT_FAILURE, err, "cannot start thread");
+
+      if (progress)
+       write (STDERR_FILENO, "t", 1);
+
+      if (++i == si->threads)
+       i = 0;
+    }
+
+  n = i;
+  do
+    {
+      if (ths[i] != 0)
+       {
+         err = pthread_join (ths[i], NULL);
+         if (err != 0)
+           error (EXIT_FAILURE, err, "cannot join thread");
+
+         if (progress)
+           write (STDERR_FILENO, "f", 1);
+       }
+
+      if (++i == si->threads)
+       i = 0;
+    }
+  while (i != n);
+
+  if (progress)
+    write (STDERR_FILENO, "F", 1);
+
+  return NULL;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+  sigset_t ss;
+  pthread_t th;
+  pthread_t *ths = NULL;
+  int empty = 0;
+  int last;
+  bool cont = true;
+
+  /* Parse and process arguments.  */
+  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  if (sync_method == sync_join)
+    {
+      ths = (pthread_t *) calloc (threads, sizeof (pthread_t));
+      if (ths == NULL)
+       error (EXIT_FAILURE, errno,
+              "cannot allocate memory for thread descriptor array");
+
+      last = threads;
+    }
+  else
+    {
+      ths = &th;
+      last = 1;
+    }
+
+  if (toplevel > threads)
+    {
+      printf ("resetting number of toplevel threads to %lu to not surpass number to concurrent threads\n",
+             threads);
+      toplevel = threads;
+    }
+
+  if (timing)
+    {
+      if (clock_getcpuclockid (0, &cl) != 0
+         || clock_gettime (cl, &start_time) != 0)
+       timing = false;
+    }
+
+  /* We need this later.  */
+  pid = getpid ();
+  tmain = pthread_self ();
+
+  /* We use signal SIGUSR1 for communication between the threads and
+     the main thread.  We only want sychronous notification.  */
+  if (sync_method == sync_signal)
+    {
+      sigemptyset (&ss);
+      sigaddset (&ss, SIGUSR1);
+      if (sigprocmask (SIG_BLOCK, &ss, NULL) != 0)
+       error (EXIT_FAILURE, errno, "cannot set signal mask");
+    }
+
+  /* Create the thread attributes.  */
+  pthread_attr_init (&attr);
+
+  /* If the user provided a stack size use it.  */
+  if (stacksize != 0
+      && pthread_attr_setstacksize (&attr, stacksize) != 0)
+    puts ("could not set stack size; will use default");
+  /* And stack guard size.  */
+  if (guardsize != -1
+      && pthread_attr_setguardsize (&attr, guardsize) != 0)
+    puts ("invalid stack guard size; will use default");
+
+  /* All threads are created detached if we are not using pthread_join
+     to synchronize.  */
+  if (sync_method != sync_join)
+    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+  if (sync_method == sync_signal)
+    {
+      while (1)
+       {
+         int err;
+         bool do_wait = false;
+
+         pthread_mutex_lock (&running_mutex);
+         if (starts-- < 0)
+           cont = false;
+         else
+           do_wait = ++running >= threads && starts > 0;
+
+         pthread_mutex_unlock (&running_mutex);
+
+         if (! cont)
+           break;
+
+         if (progress)
+           write (STDERR_FILENO, "t", 1);
+
+         err = pthread_create (&ths[empty], &attr, thread_function,
+                               (void *) starts);
+         if (err != 0)
+           error (EXIT_FAILURE, err, "cannot start thread %lu", starts);
+
+         if (++empty == last)
+           empty = 0;
+
+         if (do_wait)
+           sigwaitinfo (&ss, NULL);
+       }
+
+      /* Do nothing anymore.  On of the threads will terminate the program.  */
+      sigfillset (&ss);
+      sigdelset (&ss, SIGINT);
+      while (1)
+       sigsuspend (&ss);
+    }
+  else
+    {
+      pthread_t ths[toplevel];
+      struct start_info si[toplevel];
+      unsigned int i;
+
+      for (i = 0; i < toplevel; ++i)
+       {
+         unsigned int child_starts = starts / (toplevel - i);
+         unsigned int child_threads = threads / (toplevel - i);
+         int err;
+
+         si[i].starts = child_starts;
+         si[i].threads = child_threads;
+
+         err = pthread_create (&ths[i], &attr, start_threads, &si[i]);
+         if (err != 0)
+           error (EXIT_FAILURE, err, "cannot start thread");
+
+         starts -= child_starts;
+         threads -= child_threads;
+       }
+
+      for (i = 0; i < toplevel; ++i)
+       {
+         int err = pthread_join (ths[i], NULL);
+
+         if (err != 0)
+           error (EXIT_FAILURE, err, "cannot join thread");
+       }
+
+      /* We are done.  */
+      if (progress)
+       write (STDERR_FILENO, "\n", 1);
+
+      if (timing)
+       {
+         struct timespec end_time;
+
+         if (clock_gettime (cl, &end_time) == 0)
+           {
+             end_time.tv_sec -= start_time.tv_sec;
+             end_time.tv_nsec -= start_time.tv_nsec;
+             if (end_time.tv_nsec < 0)
+               {
+                 end_time.tv_nsec += 1000000000;
+                 --end_time.tv_sec;
+               }
+
+             printf ("\nRuntime: %lu.%09lu seconds\n",
+                     (unsigned long int) end_time.tv_sec,
+                     (unsigned long int) end_time.tv_nsec);
+           }
+       }
+
+      printf ("Result: %08x\n", sum);
+
+      exit (0);
+    }
+
+  /* NOTREACHED */
+  return 0;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  unsigned long int num;
+  long int snum;
+
+  switch (key)
+    {
+    case 't':
+      num = strtoul (arg, NULL, 0);
+      if (num <= MAX_THREADS)
+       threads = num;
+      else
+       printf ("\
+number of threads limited to %u; recompile with a higher limit if necessary",
+               MAX_THREADS);
+      break;
+
+    case 'w':
+      num = strtoul (arg, NULL, 0);
+      if (num <= 100)
+       workload = num;
+      else
+       puts ("workload must be between 0 and 100 percent");
+      break;
+
+    case 'c':
+      workcost = strtoul (arg, NULL, 0);
+      break;
+
+    case 'r':
+      rounds = strtoul (arg, NULL, 0);
+      break;
+
+    case 's':
+      starts = strtoul (arg, NULL, 0);
+      break;
+
+    case 'S':
+      num = strtoul (arg, NULL, 0);
+      if (num >= PTHREAD_STACK_MIN)
+       stacksize = num;
+      else
+       printf ("minimum stack size is %d\n", PTHREAD_STACK_MIN);
+      break;
+
+    case 'g':
+      snum = strtol (arg, NULL, 0);
+      if (snum < 0)
+       printf ("invalid guard size %s\n", arg);
+      else
+       guardsize = snum;
+      break;
+
+    case 'p':
+      progress = true;
+      break;
+
+    case 'T':
+      timing = true;
+      break;
+
+    case OPT_TO_THREAD:
+      to_thread = true;
+      break;
+
+    case OPT_TO_PROCESS:
+      to_thread = false;
+      break;
+
+    case OPT_SYNC_SIGNAL:
+      sync_method = sync_signal;
+      break;
+
+    case OPT_SYNC_JOIN:
+      sync_method = sync_join;
+      break;
+
+    case OPT_TOPLEVEL:
+      num = strtoul (arg, NULL, 0);
+      if (num < MAX_THREADS)
+       toplevel = num;
+      else
+       printf ("\
+number of threads limited to %u; recompile with a higher limit if necessary",
+               MAX_THREADS);
+      sync_method = sync_join;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+
+  return 0;
+}
+
+
+static hp_timing_t
+get_clockfreq (void)
+{
+  /* We read the information from the /proc filesystem.  It contains at
+     least one line like
+       cpu MHz         : 497.840237
+     or also
+       cpu MHz         : 497.841
+     We search for this line and convert the number in an integer.  */
+  static hp_timing_t result;
+  int fd;
+
+  /* If this function was called before, we know the result.  */
+  if (result != 0)
+    return result;
+
+  fd = open ("/proc/cpuinfo", O_RDONLY);
+  if (__builtin_expect (fd != -1, 1))
+    {
+      /* XXX AFAIK the /proc filesystem can generate "files" only up
+         to a size of 4096 bytes.  */
+      char buf[4096];
+      ssize_t n;
+
+      n = read (fd, buf, sizeof buf);
+      if (__builtin_expect (n, 1) > 0)
+       {
+         char *mhz = memmem (buf, n, "cpu MHz", 7);
+
+         if (__builtin_expect (mhz != NULL, 1))
+           {
+             char *endp = buf + n;
+             int seen_decpoint = 0;
+             int ndigits = 0;
+
+             /* Search for the beginning of the string.  */
+             while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
+               ++mhz;
+
+             while (mhz < endp && *mhz != '\n')
+               {
+                 if (*mhz >= '0' && *mhz <= '9')
+                   {
+                     result *= 10;
+                     result += *mhz - '0';
+                     if (seen_decpoint)
+                       ++ndigits;
+                   }
+                 else if (*mhz == '.')
+                   seen_decpoint = 1;
+
+                 ++mhz;
+               }
+
+             /* Compensate for missing digits at the end.  */
+             while (ndigits++ < 6)
+               result *= 10;
+           }
+       }
+
+      close (fd);
+    }
+
+  return result;
+}
+
+
+int
+clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
+{
+  /* We don't allow any process ID but our own.  */
+  if (pid != 0 && pid != getpid ())
+    return EPERM;
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+  /* Store the number.  */
+  *clock_id = CLOCK_PROCESS_CPUTIME_ID;
+
+  return 0;
+#else
+  /* We don't have a timer for that.  */
+  return ENOENT;
+#endif
+}
+
+
+#ifdef i386
+#define HP_TIMING_NOW(Var)     __asm__ __volatile__ ("rdtsc" : "=A" (Var))
+#elif defined __ia64__
+#define HP_TIMING_NOW(Var)     __asm__ __volatile__ ("mov %0=ar.itc" : "=r" (Var) : : "memory")
+#else
+#error "HP_TIMING_NOW missing"
+#endif
+
+/* Get current value of CLOCK and store it in TP.  */
+int
+clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+  int retval = -1;
+
+  switch (clock_id)
+    {
+    case CLOCK_PROCESS_CPUTIME_ID:
+      {
+
+       static hp_timing_t freq;
+       hp_timing_t tsc;
+
+       /* Get the current counter.  */
+       HP_TIMING_NOW (tsc);
+
+       if (freq == 0)
+         {
+           freq = get_clockfreq ();
+           if (freq == 0)
+             return EINVAL;
+         }
+
+       /* Compute the seconds.  */
+       tp->tv_sec = tsc / freq;
+
+       /* And the nanoseconds.  This computation should be stable until
+          we get machines with about 16GHz frequency.  */
+       tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
+
+       retval = 0;
+      }
+    break;
+
+    default:
+      errno = EINVAL;
+      break;
+    }
+
+  return retval;
+}
diff --git a/libpthread/nptl/pt-allocrtsig.c b/libpthread/nptl/pt-allocrtsig.c
new file mode 100644 (file)
index 0000000..347bf13
--- /dev/null
@@ -0,0 +1,51 @@
+/* Copyright (C) 2002, 2004 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.  */
+
+#include <signal.h>
+
+
+/* These are defined in libc.  We want to have only one definition
+   so we "forward" the calls.  */
+extern int __libc_current_sigrtmin_private (void);
+extern int __libc_current_sigrtmax_private (void);
+extern int __libc_allocate_rtsig_private (int high);
+
+
+/* We reserve __SIGRTMIN for use as the cancellation signal and
+   __SIGRTMIN+1 to handle setuid et.al.  These signals are used
+   internally.  */
+int
+__libc_current_sigrtmin (void)
+{
+  return __libc_current_sigrtmin_private ();
+}
+
+
+int
+__libc_current_sigrtmax (void)
+{
+  return __libc_current_sigrtmax_private ();
+}
+
+
+int
+__libc_allocate_rtsig (int high)
+{
+  return __libc_allocate_rtsig_private (high);
+}
diff --git a/libpthread/nptl/pt-cleanup.c b/libpthread/nptl/pt-cleanup.c
new file mode 100644 (file)
index 0000000..96836a1
--- /dev/null
@@ -0,0 +1,64 @@
+/* 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.  */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+#include "jmpbuf-unwind.h"
+
+void
+__pthread_cleanup_upto (__jmp_buf target, char *targetframe)
+{
+  struct pthread *self = THREAD_SELF;
+  struct _pthread_cleanup_buffer *cbuf;
+
+  /* Adjust all pointers used in comparisons, so that top of thread's
+     stack is at the top of address space.  Without that, things break
+     if stack is allocated above the main stack.  */
+  uintptr_t adj = (uintptr_t) self->stackblock + self->stackblock_size;
+  uintptr_t targetframe_adj = (uintptr_t) targetframe - adj;
+
+  for (cbuf = THREAD_GETMEM (self, cleanup);
+       cbuf != NULL && _JMPBUF_UNWINDS_ADJ (target, cbuf, adj);
+       cbuf = cbuf->__prev)
+    {
+#if _STACK_GROWS_DOWN
+      if ((uintptr_t) cbuf - adj <= targetframe_adj)
+        {
+          cbuf = NULL;
+          break;
+        }
+#elif _STACK_GROWS_UP
+      if ((uintptr_t) cbuf - adj >= targetframe_adj)
+        {
+          cbuf = NULL;
+          break;
+        }
+#else
+# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
+#endif
+
+      /* Call the cleanup code.  */
+      cbuf->__routine (cbuf->__arg);
+    }
+
+  THREAD_SETMEM (self, cleanup, cbuf);
+}
+hidden_def (__pthread_cleanup_upto)
+
diff --git a/libpthread/nptl/pt-system.c b/libpthread/nptl/pt-system.c
new file mode 100644 (file)
index 0000000..b3b45ab
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sysdep.h>
+#include "pthreadP.h"
+
+
+int
+system (const char *line)
+{
+  return __libc_system (line);
+}
+
+/* __libc_system in libc.so handles cancellation.  */
+LIBC_CANCEL_HANDLED ();
diff --git a/libpthread/nptl/pthread-errnos.sym b/libpthread/nptl/pthread-errnos.sym
new file mode 100644 (file)
index 0000000..2bb4d0d
--- /dev/null
@@ -0,0 +1,12 @@
+#include <errno.h>
+
+-- These errno codes are used by some assembly code.
+
+EAGAIN         EAGAIN
+EBUSY          EBUSY
+EDEADLK                EDEADLK
+EINTR          EINTR
+EINVAL         EINVAL
+ENOSYS         ENOSYS
+ETIMEDOUT      ETIMEDOUT
+EWOULDBLOCK    EWOULDBLOCK
diff --git a/libpthread/nptl/pthreadP.h b/libpthread/nptl/pthreadP.h
new file mode 100644 (file)
index 0000000..2416814
--- /dev/null
@@ -0,0 +1,466 @@
+/* Copyright (C) 2002, 2003, 2004 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 _PTHREADP_H
+#define _PTHREADP_H    1
+
+#include <pthread.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <sys/syscall.h>
+#include "descr.h"
+#include <tls.h>
+#include <lowlevellock.h>
+#include <stackinfo.h>
+#include <internaltypes.h>
+#include <pthread-functions.h>
+#include <atomic.h>
+
+
+/* Atomic operations on TLS memory.  */
+#ifndef THREAD_ATOMIC_CMPXCHG_VAL
+# define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, new, old) \
+  atomic_compare_and_exchange_val_acq (&(descr)->member, new, old)
+#endif
+
+#ifndef THREAD_ATOMIC_BIT_SET
+# define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
+  atomic_bit_set (&(descr)->member, bit)
+#endif
+
+
+/* Adaptive mutex definitions.  */
+#ifndef MAX_ADAPTIVE_COUNT
+# define MAX_ADAPTIVE_COUNT 100
+#endif
+
+
+/* Internal variables.  */
+
+
+/* Default stack size.  */
+extern size_t __default_stacksize attribute_hidden;
+
+/* Size and alignment of static TLS block.  */
+extern size_t __static_tls_size attribute_hidden;
+extern size_t __static_tls_align_m1 attribute_hidden;
+
+/* Flag whether the machine is SMP or not.  */
+extern int __is_smp attribute_hidden;
+
+/* Thread descriptor handling.  */
+extern list_t __stack_user;
+hidden_proto (__stack_user)
+
+/* Attribute handling.  */
+extern struct pthread_attr *__attr_list attribute_hidden;
+extern lll_lock_t __attr_list_lock attribute_hidden;
+
+/* First available RT signal.  */
+extern int __current_sigrtmin attribute_hidden;
+/* Last available RT signal.  */
+extern int __current_sigrtmax attribute_hidden;
+
+/* Concurrency handling.  */
+extern int __concurrency_level attribute_hidden;
+
+/* Thread-local data key handling.  */
+extern struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX];
+hidden_proto (__pthread_keys)
+
+/* Number of threads running.  */
+extern unsigned int __nptl_nthreads attribute_hidden;
+
+/* The library can run in debugging mode where it performs a lot more
+   tests.  */
+extern int __pthread_debug attribute_hidden;
+/** For now disable debugging support.  */
+#if 0
+# define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
+# define INVALID_TD_P(pd) (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
+# define INVALID_NOT_TERMINATED_TD_P(pd) INVALID_TD_P (pd)
+#else
+# define DEBUGGING_P 0
+/* Simplified test.  This will not catch all invalid descriptors but
+   is better than nothing.  And if the test triggers the thread
+   descriptor is guaranteed to be invalid.  */
+# define INVALID_TD_P(pd) __builtin_expect ((pd)->tid <= 0, 0)
+# define INVALID_NOT_TERMINATED_TD_P(pd) __builtin_expect ((pd)->tid < 0, 0)
+#endif
+
+
+/* Cancellation test.  */
+#define CANCELLATION_P(self) \
+  do {                                                                       \
+    int cancelhandling = THREAD_GETMEM (self, cancelhandling);               \
+    if (CANCEL_ENABLED_AND_CANCELED (cancelhandling))                        \
+      {                                                                              \
+       THREAD_SETMEM (self, result, PTHREAD_CANCELED);                       \
+       __do_cancel ();                                                       \
+      }                                                                              \
+  } while (0)
+
+
+extern void __pthread_unwind (__pthread_unwind_buf_t *__buf)
+     __cleanup_fct_attribute __attribute ((__noreturn__))
+#if !defined SHARED && !defined IS_IN_libpthread
+     weak_function
+#endif
+     ;
+extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
+     __cleanup_fct_attribute __attribute ((__noreturn__))
+#ifndef SHARED
+     weak_function
+#endif
+     ;
+extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
+     __cleanup_fct_attribute;
+extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
+     __cleanup_fct_attribute;
+#if defined NOT_IN_libc && defined IS_IN_libpthread
+hidden_proto (__pthread_unwind)
+hidden_proto (__pthread_unwind_next)
+hidden_proto (__pthread_register_cancel)
+hidden_proto (__pthread_unregister_cancel)
+# ifdef SHARED
+extern void attribute_hidden pthread_cancel_init (void);
+# endif
+#endif
+
+
+/* Called when a thread reacts on a cancellation request.  */
+static inline void
+__attribute ((noreturn, always_inline))
+__do_cancel (void)
+{
+  struct pthread *self = THREAD_SELF;
+
+  /* Make sure we get no more cancellations.  */
+  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
+
+  __pthread_unwind ((__pthread_unwind_buf_t *)
+                   THREAD_GETMEM (self, cleanup_jmp_buf));
+}
+
+
+/* Set cancellation mode to asynchronous.  */
+#define CANCEL_ASYNC() \
+  __pthread_enable_asynccancel ()
+/* Reset to previous cancellation mode.  */
+#define CANCEL_RESET(oldtype) \
+  __pthread_disable_asynccancel (oldtype)
+
+#if !defined NOT_IN_libc
+/* Same as CANCEL_ASYNC, but for use in libc.so.  */
+# define LIBC_CANCEL_ASYNC() \
+  __libc_enable_asynccancel ()
+/* Same as CANCEL_RESET, but for use in libc.so.  */
+# define LIBC_CANCEL_RESET(oldtype) \
+  __libc_disable_asynccancel (oldtype)
+# define LIBC_CANCEL_HANDLED() \
+  __asm (".globl " __SYMBOL_PREFIX "__libc_enable_asynccancel"); \
+  __asm (".globl " __SYMBOL_PREFIX "__libc_disable_asynccancel")
+#elif defined NOT_IN_libc && defined IS_IN_libpthread
+# define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
+# define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
+# define LIBC_CANCEL_HANDLED() \
+  __asm (".globl " __SYMBOL_PREFIX "__pthread_enable_asynccancel"); \
+  __asm (".globl " __SYMBOL_PREFIX "__pthread_disable_asynccancel")
+#elif defined NOT_IN_libc && defined IS_IN_librt
+# define LIBC_CANCEL_ASYNC() \
+  __librt_enable_asynccancel ()
+# define LIBC_CANCEL_RESET(val) \
+  __librt_disable_asynccancel (val)
+# define LIBC_CANCEL_HANDLED() \
+  __asm (".globl " __SYMBOL_PREFIX "__librt_enable_asynccancel"); \
+  __asm (".globl " __SYMBOL_PREFIX "__librt_disable_asynccancel")
+#else
+# define LIBC_CANCEL_ASYNC()   0 /* Just a dummy value.  */
+# define LIBC_CANCEL_RESET(val)        ((void)(val)) /* Nothing, but evaluate it.  */
+# define LIBC_CANCEL_HANDLED() /* Nothing.  */
+#endif
+
+/* The signal used for asynchronous cancelation.  */
+#define SIGCANCEL      __SIGRTMIN
+
+
+/* Signal needed for the kernel-supported POSIX timer implementation.
+   We can reuse the cancellation signal since we can distinguish
+   cancellation from timer expirations.  */
+#define SIGTIMER       SIGCANCEL
+
+
+/* Signal used to implement the setuid et.al. functions.  */
+#define SIGSETXID      (__SIGRTMIN + 1)
+
+/* Used to communicate with signal handler.  */
+extern struct xid_command *__xidcmd attribute_hidden;
+
+
+/* Internal prototypes.  */
+
+/* Thread list handling.  */
+extern struct pthread *__find_in_stack_list (struct pthread *pd)
+     attribute_hidden internal_function;
+
+/* Deallocate a thread's stack after optionally making sure the thread
+   descriptor is still valid.  */
+extern void __free_tcb (struct pthread *pd) attribute_hidden internal_function;
+
+/* Free allocated stack.  */
+extern void __deallocate_stack (struct pthread *pd)
+     attribute_hidden internal_function;
+
+/* Mark all the stacks except for the current one as available.  This
+   function also re-initializes the lock for the stack cache.  */
+extern void __reclaim_stacks (void) attribute_hidden;
+
+/* Make all threads's stacks executable.  */
+extern int __make_stacks_executable (void **stack_endp)
+     internal_function attribute_hidden;
+
+/* longjmp handling.  */
+extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
+#if defined NOT_IN_libc && defined IS_IN_libpthread
+hidden_proto (__pthread_cleanup_upto)
+#endif
+
+
+/* Functions with versioned interfaces.  */
+extern int __pthread_create_2_1 (pthread_t *newthread,
+                                const pthread_attr_t *attr,
+                                void *(*start_routine) (void *), void *arg);
+extern int __pthread_create_2_0 (pthread_t *newthread,
+                                const pthread_attr_t *attr,
+                                void *(*start_routine) (void *), void *arg);
+extern int __pthread_attr_init_2_1 (pthread_attr_t *attr);
+extern int __pthread_attr_init_2_0 (pthread_attr_t *attr);
+
+
+/* Event handlers for libthread_db interface.  */
+extern void __nptl_create_event (void);
+extern void __nptl_death_event (void);
+hidden_proto (__nptl_create_event)
+hidden_proto (__nptl_death_event)
+
+/* Register the generation counter in the libpthread with the libc.  */
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
+extern void __libc_pthread_init (unsigned long int *ptr,
+                                void (*reclaim) (void),
+                                const struct pthread_functions *functions)
+     internal_function;
+#else
+extern int *__libc_pthread_init (unsigned long int *ptr,
+                                void (*reclaim) (void),
+                                const struct pthread_functions *functions)
+     internal_function;
+
+/* Variable set to a nonzero value if more than one thread runs or ran.  */
+extern int __pthread_multiple_threads attribute_hidden;
+/* Pointer to the corresponding variable in libc.  */
+extern int *__libc_multiple_threads_ptr attribute_hidden;
+#endif
+
+/* Find a thread given its TID.  */
+extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden
+#ifdef SHARED
+;
+#else
+weak_function;
+#define __find_thread_by_id(tid) \
+  (__find_thread_by_id ? (__find_thread_by_id) (tid) : (struct pthread *) NULL)
+#endif
+
+extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
+
+
+/* Namespace save aliases.  */
+extern int __pthread_getschedparam (pthread_t thread_id, int *policy,
+                                   struct sched_param *param);
+extern int __pthread_setschedparam (pthread_t thread_id, int policy,
+                                   const struct sched_param *param);
+extern int __pthread_setcancelstate (int state, int *oldstate);
+extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
+                                __const pthread_mutexattr_t *__mutexattr);
+extern int __pthread_mutex_init_internal (pthread_mutex_t *__mutex,
+                                         __const pthread_mutexattr_t *__mutexattr)
+     attribute_hidden;
+extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_destroy_internal (pthread_mutex_t *__mutex)
+     attribute_hidden;
+extern int __pthread_mutex_trylock (pthread_mutex_t *_mutex);
+extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex)
+     attribute_hidden;
+extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
+     attribute_hidden internal_function;
+extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex)
+     attribute_hidden;
+extern int __pthread_mutex_unlock_usercnt (pthread_mutex_t *__mutex,
+                                          int __decr)
+     attribute_hidden internal_function;
+extern int __pthread_mutexattr_init (pthread_mutexattr_t *attr);
+extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *attr);
+extern int __pthread_mutexattr_settype (pthread_mutexattr_t *attr, int kind);
+extern int __pthread_attr_destroy (pthread_attr_t *attr);
+extern int __pthread_attr_getdetachstate (const pthread_attr_t *attr,
+                                         int *detachstate);
+extern int __pthread_attr_setdetachstate (pthread_attr_t *attr,
+                                         int detachstate);
+extern int __pthread_attr_getinheritsched (const pthread_attr_t *attr,
+                                          int *inherit);
+extern int __pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit);
+extern int __pthread_attr_getschedparam (const pthread_attr_t *attr,
+                                        struct sched_param *param);
+extern int __pthread_attr_setschedparam (pthread_attr_t *attr,
+                                        const struct sched_param *param);
+extern int __pthread_attr_getschedpolicy (const pthread_attr_t *attr,
+                                         int *policy);
+extern int __pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
+extern int __pthread_attr_getscope (const pthread_attr_t *attr, int *scope);
+extern int __pthread_attr_setscope (pthread_attr_t *attr, int scope);
+extern int __pthread_attr_getstackaddr (__const pthread_attr_t *__restrict
+                                       __attr, void **__restrict __stackaddr);
+extern int __pthread_attr_setstackaddr (pthread_attr_t *__attr,
+                                       void *__stackaddr);
+extern int __pthread_attr_getstacksize (__const pthread_attr_t *__restrict
+                                       __attr,
+                                       size_t *__restrict __stacksize);
+extern int __pthread_attr_setstacksize (pthread_attr_t *__attr,
+                                       size_t __stacksize);
+extern int __pthread_attr_getstack (__const pthread_attr_t *__restrict __attr,
+                                   void **__restrict __stackaddr,
+                                   size_t *__restrict __stacksize);
+extern int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
+                                   size_t __stacksize);
+extern int __pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
+                                 __const pthread_rwlockattr_t *__restrict
+                                 __attr);
+extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_rdlock_internal (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_wrlock_internal (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
+extern int __pthread_rwlock_unlock_internal (pthread_rwlock_t *__rwlock);
+extern int __pthread_cond_broadcast (pthread_cond_t *cond);
+extern int __pthread_cond_destroy (pthread_cond_t *cond);
+extern int __pthread_cond_init (pthread_cond_t *cond,
+                               const pthread_condattr_t *cond_attr);
+extern int __pthread_cond_signal (pthread_cond_t *cond);
+extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
+extern int __pthread_cond_timedwait (pthread_cond_t *cond,
+                                    pthread_mutex_t *mutex,
+                                    const struct timespec *abstime);
+extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
+extern int __pthread_condattr_init (pthread_condattr_t *attr);
+extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));
+extern int __pthread_key_create_internal (pthread_key_t *key,
+                                         void (*destr) (void *));
+extern void *__pthread_getspecific (pthread_key_t key);
+extern void *__pthread_getspecific_internal (pthread_key_t key);
+extern int __pthread_setspecific (pthread_key_t key, const void *value);
+extern int __pthread_setspecific_internal (pthread_key_t key,
+                                          const void *value);
+extern int __pthread_once (pthread_once_t *once_control,
+                          void (*init_routine) (void));
+extern int __pthread_once_internal (pthread_once_t *once_control,
+                                   void (*init_routine) (void));
+extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void),
+                            void (*child) (void));
+extern pthread_t __pthread_self (void);
+extern int __pthread_equal (pthread_t thread1, pthread_t thread2);
+extern int __pthread_kill (pthread_t threadid, int signo);
+extern void __pthread_exit (void *value);
+extern int __pthread_setcanceltype (int type, int *oldtype);
+extern int __pthread_enable_asynccancel (void) attribute_hidden;
+extern void __pthread_disable_asynccancel (int oldtype)
+     internal_function attribute_hidden;
+
+extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond);
+extern int __pthread_cond_destroy_2_0 (pthread_cond_2_0_t *cond);
+extern int __pthread_cond_init_2_0 (pthread_cond_2_0_t *cond,
+                                   const pthread_condattr_t *cond_attr);
+extern int __pthread_cond_signal_2_0 (pthread_cond_2_0_t *cond);
+extern int __pthread_cond_timedwait_2_0 (pthread_cond_2_0_t *cond,
+                                        pthread_mutex_t *mutex,
+                                        const struct timespec *abstime);
+extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond,
+                                   pthread_mutex_t *mutex);
+
+extern int __pthread_getaffinity_np (pthread_t th, size_t cpusetsize,
+                                    cpu_set_t *cpuset);
+
+/* The two functions are in libc.so and not exported.  */
+extern int __libc_enable_asynccancel (void) attribute_hidden;
+extern void __libc_disable_asynccancel (int oldtype)
+     internal_function attribute_hidden;
+
+
+/* The two functions are in librt.so and not exported.  */
+extern int __librt_enable_asynccancel (void) attribute_hidden;
+extern void __librt_disable_asynccancel (int oldtype)
+     internal_function attribute_hidden;
+
+#ifdef IS_IN_libpthread
+/* Special versions which use non-exported functions.  */
+extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
+                                   void (*routine) (void *), void *arg)
+     attribute_hidden;
+# undef pthread_cleanup_push
+# define pthread_cleanup_push(routine,arg) \
+  { struct _pthread_cleanup_buffer _buffer;                                  \
+    __pthread_cleanup_push (&_buffer, (routine), (arg));
+
+extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
+                                  int execute) attribute_hidden;
+# undef pthread_cleanup_pop
+# define pthread_cleanup_pop(execute) \
+    __pthread_cleanup_pop (&_buffer, (execute)); }
+#endif
+
+extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
+                                         void (*routine) (void *), void *arg);
+extern void __pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
+                                          int execute);
+
+/* Old cleanup interfaces, still used in libc.so.  */
+extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
+                                   void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
+                                  int execute);
+extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
+                                         void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
+                                          int execute);
+
+extern void __nptl_deallocate_tsd (void) attribute_hidden;
+
+extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
+
+#ifdef SHARED
+# define PTHREAD_STATIC_FN_REQUIRE(name)
+#else
+# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
+#endif
+
+#endif /* pthreadP.h */
diff --git a/libpthread/nptl/pthread_atfork.c b/libpthread/nptl/pthread_atfork.c
new file mode 100644 (file)
index 0000000..6437d64
--- /dev/null
@@ -0,0 +1,63 @@
+/* Copyright (C) 2002 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.
+
+   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 GNU 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.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   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 <fork.h>
+
+/* This is defined by newer gcc version unique for each module.  */
+extern void *__dso_handle __attribute__ ((__weak__));
+
+
+/* Hide the symbol so that no definition but the one locally in the
+   executable or DSO is used.  */
+int
+#ifndef __pthread_atfork
+/* Don't mark the compatibility function as hidden.  */
+attribute_hidden
+#endif
+__pthread_atfork (prepare, parent, child)
+     void (*prepare) (void);
+     void (*parent) (void);
+     void (*child) (void);
+{
+  return __register_atfork (prepare, parent, child,
+                           &__dso_handle == NULL ? NULL : __dso_handle);
+}
+#ifndef __pthread_atfork
+extern int pthread_atfork (void (*prepare) (void), void (*parent) (void),
+                          void (*child) (void)) attribute_hidden;
+strong_alias (__pthread_atfork, pthread_atfork)
+#endif
diff --git a/libpthread/nptl/pthread_attr_destroy.c b/libpthread/nptl/pthread_attr_destroy.c
new file mode 100644 (file)
index 0000000..b8d9a20
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include "pthreadP.h"
+#include <shlib-compat.h>
+
+int
+__pthread_attr_destroy (attr)
+     pthread_attr_t *attr;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+  /* In old struct pthread_attr, neither next nor cpuset are
+     present.  */
+  if (__builtin_expect ((iattr->flags & ATTR_FLAG_OLDATTR), 0) == 0)
+#endif
+    /* The affinity CPU set might be allocated dynamically.  */
+    free (iattr->cpuset);
+
+  return 0;
+}
+strong_alias (__pthread_attr_destroy, pthread_attr_destroy)
diff --git a/libpthread/nptl/pthread_attr_getdetachstate.c b/libpthread/nptl/pthread_attr_getdetachstate.c
new file mode 100644 (file)
index 0000000..502cfa4
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getdetachstate (attr, detachstate)
+     const pthread_attr_t *attr;
+     int *detachstate;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  *detachstate = (iattr->flags & ATTR_FLAG_DETACHSTATE
+                 ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE);
+
+  return 0;
+}
+strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate)
diff --git a/libpthread/nptl/pthread_attr_getguardsize.c b/libpthread/nptl/pthread_attr_getguardsize.c
new file mode 100644 (file)
index 0000000..e1d0ed6
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+pthread_attr_getguardsize (attr, guardsize)
+     const pthread_attr_t *attr;
+     size_t *guardsize;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  *guardsize = iattr->guardsize;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_attr_getinheritsched.c b/libpthread/nptl/pthread_attr_getinheritsched.c
new file mode 100644 (file)
index 0000000..f47bf71
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getinheritsched (attr, inherit)
+     const pthread_attr_t *attr;
+     int *inherit;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Store the current values.  */
+  *inherit = (iattr->flags & ATTR_FLAG_NOTINHERITSCHED
+             ? PTHREAD_EXPLICIT_SCHED : PTHREAD_INHERIT_SCHED);
+
+  return 0;
+}
+strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched)
diff --git a/libpthread/nptl/pthread_attr_getschedparam.c b/libpthread/nptl/pthread_attr_getschedparam.c
new file mode 100644 (file)
index 0000000..0ff0c0c
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include <string.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getschedparam (attr, param)
+     const pthread_attr_t *attr;
+     struct sched_param *param;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Copy the current values.  */
+  memcpy (param, &iattr->schedparam, sizeof (struct sched_param));
+
+  return 0;
+}
+strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam)
diff --git a/libpthread/nptl/pthread_attr_getschedpolicy.c b/libpthread/nptl/pthread_attr_getschedpolicy.c
new file mode 100644 (file)
index 0000000..8364f3b
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getschedpolicy (attr, policy)
+     const pthread_attr_t *attr;
+     int *policy;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Store the current values.  */
+  *policy = iattr->schedpolicy;
+
+  return 0;
+}
+strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy)
diff --git a/libpthread/nptl/pthread_attr_getscope.c b/libpthread/nptl/pthread_attr_getscope.c
new file mode 100644 (file)
index 0000000..b6aa5a2
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getscope (attr, scope)
+     const pthread_attr_t *attr;
+     int *scope;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Store the current values.  */
+  *scope = (iattr->flags & ATTR_FLAG_SCOPEPROCESS
+             ? PTHREAD_SCOPE_PROCESS : PTHREAD_SCOPE_SYSTEM);
+
+  return 0;
+}
+strong_alias (__pthread_attr_getscope, pthread_attr_getscope)
diff --git a/libpthread/nptl/pthread_attr_getstack.c b/libpthread/nptl/pthread_attr_getstack.c
new file mode 100644 (file)
index 0000000..1db135e
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getstack (attr, stackaddr, stacksize)
+     const pthread_attr_t *attr;
+     void **stackaddr;
+     size_t *stacksize;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Store the result.  */
+  *stackaddr = (char *) iattr->stackaddr - iattr->stacksize;
+  *stacksize = iattr->stacksize;
+
+  return 0;
+}
+strong_alias (__pthread_attr_getstack, pthread_attr_getstack)
diff --git a/libpthread/nptl/pthread_attr_getstackaddr.c b/libpthread/nptl/pthread_attr_getstackaddr.c
new file mode 100644 (file)
index 0000000..7656600
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (C) 2002, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getstackaddr (attr, stackaddr)
+     const pthread_attr_t *attr;
+     void **stackaddr;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Some code assumes this function to work even if no stack address
+     has been set.  Let them figure it out for themselves what the
+     value means.  Simply store the result.  */
+  *stackaddr = iattr->stackaddr;
+
+  return 0;
+}
+strong_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr)
+
+link_warning (pthread_attr_getstackaddr,
+              "the use of `pthread_attr_getstackaddr' is deprecated, use `pthread_attr_getstack'")
diff --git a/libpthread/nptl/pthread_attr_getstacksize.c b/libpthread/nptl/pthread_attr_getstacksize.c
new file mode 100644 (file)
index 0000000..d4ff54f
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_getstacksize (attr, stacksize)
+     const pthread_attr_t *attr;
+     size_t *stacksize;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* If the user has not set a stack size we return what the system
+     will use as the default.  */
+  *stacksize = iattr->stacksize ?: __default_stacksize;
+
+  return 0;
+}
+strong_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
diff --git a/libpthread/nptl/pthread_attr_init.c b/libpthread/nptl/pthread_attr_init.c
new file mode 100644 (file)
index 0000000..c84b33f
--- /dev/null
@@ -0,0 +1,88 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include "pthreadP.h"
+
+#include <shlib-compat.h>
+
+
+struct pthread_attr *__attr_list;
+lll_lock_t __attr_list_lock = LLL_LOCK_INITIALIZER;
+
+
+int
+__pthread_attr_init_2_1 (attr)
+     pthread_attr_t *attr;
+{
+  struct pthread_attr *iattr;
+
+  /* Many elements are initialized to zero so let us do it all at
+     once.  This also takes care of clearing the bytes which are not
+     internally used.  */
+  memset (attr, '\0', __SIZEOF_PTHREAD_ATTR_T);
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Default guard size specified by the standard.  */
+  iattr->guardsize = __getpagesize ();
+
+  return 0;
+}
+versioned_symbol (libpthread, __pthread_attr_init_2_1, pthread_attr_init,
+                 GLIBC_2_1);
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+__pthread_attr_init_2_0 (attr)
+     pthread_attr_t *attr;
+{
+  /* This code is specific to the old LinuxThread code which has a too
+     small pthread_attr_t definition.  The struct looked like
+     this:  */
+  struct old_attr
+  {
+    int detachstate;
+    int schedpolicy;
+    struct sched_param schedparam;
+    int inheritsched;
+    int scope;
+  };
+  struct pthread_attr *iattr;
+
+  /* Many elements are initialized to zero so let us do it all at
+     once.  This also takes care of clearing the bytes which are not
+     internally used.  */
+  memset (attr, '\0', sizeof (struct old_attr));
+
+  iattr = (struct pthread_attr *) attr;
+  iattr->flags |= ATTR_FLAG_OLDATTR;
+
+  /* We cannot enqueue the attribute because that member is not in the
+     old attribute structure.  */
+  return 0;
+}
+compat_symbol (libpthread, __pthread_attr_init_2_0, pthread_attr_init,
+              GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/pthread_attr_setdetachstate.c b/libpthread/nptl/pthread_attr_setdetachstate.c
new file mode 100644 (file)
index 0000000..a0e6c20
--- /dev/null
@@ -0,0 +1,48 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setdetachstate (attr, detachstate)
+     pthread_attr_t *attr;
+     int detachstate;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid values.  */
+  if (detachstate != PTHREAD_CREATE_DETACHED
+      && __builtin_expect (detachstate != PTHREAD_CREATE_JOINABLE, 0))
+    return EINVAL;
+
+  /* Set the flag.  It is nonzero if threads are created detached.  */
+  if (detachstate == PTHREAD_CREATE_DETACHED)
+    iattr->flags |= ATTR_FLAG_DETACHSTATE;
+  else
+    iattr->flags &= ~ATTR_FLAG_DETACHSTATE;
+
+  return 0;
+}
+strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate)
diff --git a/libpthread/nptl/pthread_attr_setguardsize.c b/libpthread/nptl/pthread_attr_setguardsize.c
new file mode 100644 (file)
index 0000000..4c674f4
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include "pthreadP.h"
+
+
+int
+pthread_attr_setguardsize (attr, guardsize)
+     pthread_attr_t *attr;
+     size_t guardsize;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Note that we don't round the value here.  The standard requires
+     that subsequent pthread_attr_getguardsize calls return the value
+     set by the user.  */
+  iattr->guardsize = guardsize;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_attr_setinheritsched.c b/libpthread/nptl/pthread_attr_setinheritsched.c
new file mode 100644 (file)
index 0000000..8a77eeb
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setinheritsched (attr, inherit)
+     pthread_attr_t *attr;
+     int inherit;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid values.  */
+  if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
+    return EINVAL;
+
+  /* Store the new values.  */
+  if (inherit != PTHREAD_INHERIT_SCHED)
+    iattr->flags |= ATTR_FLAG_NOTINHERITSCHED;
+  else
+    iattr->flags &= ~ATTR_FLAG_NOTINHERITSCHED;
+
+  return 0;
+}
+strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched)
diff --git a/libpthread/nptl/pthread_attr_setschedparam.c b/libpthread/nptl/pthread_attr_setschedparam.c
new file mode 100644 (file)
index 0000000..976ad13
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright (C) 2002, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setschedparam (attr, param)
+     pthread_attr_t *attr;
+     const struct sched_param *param;
+{
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  struct pthread_attr *iattr = (struct pthread_attr *) attr;
+
+  /* Copy the new values.  */
+  memcpy (&iattr->schedparam, param, sizeof (struct sched_param));
+
+  /* Remember we set the value.  */
+  iattr->flags |= ATTR_FLAG_SCHED_SET;
+
+  return 0;
+}
+strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam)
diff --git a/libpthread/nptl/pthread_attr_setschedpolicy.c b/libpthread/nptl/pthread_attr_setschedpolicy.c
new file mode 100644 (file)
index 0000000..b9710d5
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright (C) 2002, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setschedpolicy (attr, policy)
+     pthread_attr_t *attr;
+     int policy;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid values.  */
+  if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
+    return EINVAL;
+
+  /* Store the new values.  */
+  iattr->schedpolicy = policy;
+
+  /* Remember we set the value.  */
+  iattr->flags |= ATTR_FLAG_POLICY_SET;
+
+  return 0;
+}
+strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy)
diff --git a/libpthread/nptl/pthread_attr_setscope.c b/libpthread/nptl/pthread_attr_setscope.c
new file mode 100644 (file)
index 0000000..8b3e161
--- /dev/null
@@ -0,0 +1,51 @@
+/* Copyright (C) 2002 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setscope (attr, scope)
+     pthread_attr_t *attr;
+     int scope;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid values.  */
+  switch (scope)
+    {
+    case PTHREAD_SCOPE_SYSTEM:
+      iattr->flags &= ~ATTR_FLAG_SCOPEPROCESS;
+      break;
+
+    case PTHREAD_SCOPE_PROCESS:
+      return ENOTSUP;
+
+    default:
+      return EINVAL;
+    }
+
+  return 0;
+}
+strong_alias (__pthread_attr_setscope, pthread_attr_setscope)
diff --git a/libpthread/nptl/pthread_attr_setstack.c b/libpthread/nptl/pthread_attr_setstack.c
new file mode 100644 (file)
index 0000000..622e4a2
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setstack (attr, stackaddr, stacksize)
+     pthread_attr_t *attr;
+     void *stackaddr;
+     size_t stacksize;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid sizes.  */
+  if (stacksize < PTHREAD_STACK_MIN)
+    return EINVAL;
+
+#ifdef EXTRA_PARAM_CHECKS
+  EXTRA_PARAM_CHECKS;
+#endif
+
+  iattr->stacksize = stacksize;
+  iattr->stackaddr = (char *) stackaddr + stacksize;
+  iattr->flags |= ATTR_FLAG_STACKADDR;
+
+  return 0;
+}
+
+#if PTHREAD_STACK_MIN == 16384
+strong_alias (__pthread_attr_setstack, pthread_attr_setstack)
+#else
+# include <shlib-compat.h>
+versioned_symbol (libpthread, __pthread_attr_setstack, pthread_attr_setstack,
+                 GLIBC_2_3_3);
+
+# if SHLIB_COMPAT(libpthread, GLIBC_2_2, GLIBC_2_3_3)
+
+int
+__old_pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
+                            size_t stacksize)
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid sizes.  */
+  if (stacksize < 16384)
+    return EINVAL;
+
+# ifdef EXTRA_PARAM_CHECKS
+  EXTRA_PARAM_CHECKS;
+# endif
+
+  iattr->stacksize = stacksize;
+  iattr->stackaddr = (char *) stackaddr + stacksize;
+  iattr->flags |= ATTR_FLAG_STACKADDR;
+
+  return 0;
+}
+
+compat_symbol (libpthread, __old_pthread_attr_setstack, pthread_attr_setstack,
+              GLIBC_2_2);
+# endif
+
+#endif
diff --git a/libpthread/nptl/pthread_attr_setstackaddr.c b/libpthread/nptl/pthread_attr_setstackaddr.c
new file mode 100644 (file)
index 0000000..0d7a7c0
--- /dev/null
@@ -0,0 +1,47 @@
+/* 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setstackaddr (attr, stackaddr)
+     pthread_attr_t *attr;
+     void *stackaddr;
+{
+  struct pthread_attr *iattr;
+
+#ifdef EXTRA_PARAM_CHECKS
+  EXTRA_PARAM_CHECKS;
+#endif
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  iattr->stackaddr = stackaddr;
+  iattr->flags |= ATTR_FLAG_STACKADDR;
+
+  return 0;
+}
+strong_alias (__pthread_attr_setstackaddr, pthread_attr_setstackaddr)
+
+link_warning (pthread_attr_setstackaddr,
+              "the use of `pthread_attr_setstackaddr' is deprecated, use `pthread_attr_setstack'")
diff --git a/libpthread/nptl/pthread_attr_setstacksize.c b/libpthread/nptl/pthread_attr_setstacksize.c
new file mode 100644 (file)
index 0000000..f84a9f6
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_attr_setstacksize (attr, stacksize)
+     pthread_attr_t *attr;
+     size_t stacksize;
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid sizes.  */
+  if (stacksize < PTHREAD_STACK_MIN)
+    return EINVAL;
+
+  iattr->stacksize = stacksize;
+
+  return 0;
+}
+
+#if PTHREAD_STACK_MIN == 16384
+strong_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize)
+#else
+# include <shlib-compat.h>
+versioned_symbol (libpthread, __pthread_attr_setstacksize,
+                 pthread_attr_setstacksize, GLIBC_2_3_3);
+
+# if SHLIB_COMPAT(libpthread, GLIBC_2_1, GLIBC_2_3_3)
+
+int
+__old_pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize)
+{
+  struct pthread_attr *iattr;
+
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid sizes.  */
+  if (stacksize < 16384)
+    return EINVAL;
+
+  iattr->stacksize = stacksize;
+
+  return 0;
+}
+
+compat_symbol (libpthread, __old_pthread_attr_setstacksize,
+              pthread_attr_setstacksize, GLIBC_2_1);
+# endif
+
+#endif
diff --git a/libpthread/nptl/pthread_barrier_destroy.c b/libpthread/nptl/pthread_barrier_destroy.c
new file mode 100644 (file)
index 0000000..492b294
--- /dev/null
@@ -0,0 +1,44 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+pthread_barrier_destroy (barrier)
+     pthread_barrier_t *barrier;
+{
+  struct pthread_barrier *ibarrier;
+  int result = EBUSY;
+
+  ibarrier = (struct pthread_barrier *) barrier;
+
+  lll_lock (ibarrier->lock);
+
+  if (__builtin_expect (ibarrier->left == ibarrier->init_count, 1))
+    /* The barrier is not used anymore.  */
+    result = 0;
+  else
+    /* Still used, return with an error.  */
+    lll_unlock (ibarrier->lock);
+
+  return result;
+}
diff --git a/libpthread/nptl/pthread_barrier_init.c b/libpthread/nptl/pthread_barrier_init.c
new file mode 100644 (file)
index 0000000..19e82fa
--- /dev/null
@@ -0,0 +1,57 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+pthread_barrier_init (barrier, attr, count)
+     pthread_barrier_t *barrier;
+     const pthread_barrierattr_t *attr;
+     unsigned int count;
+{
+  struct pthread_barrier *ibarrier;
+
+  if (__builtin_expect (count == 0, 0))
+    return EINVAL;
+
+  if (attr != NULL)
+    {
+      struct pthread_barrierattr *iattr;
+
+      iattr = (struct pthread_barrierattr *) attr;
+
+      if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+         && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
+       /* Invalid attribute.  */
+       return EINVAL;
+    }
+
+  ibarrier = (struct pthread_barrier *) barrier;
+
+  /* Initialize the individual fields.  */
+  ibarrier->lock = LLL_LOCK_INITIALIZER;
+  ibarrier->left = count;
+  ibarrier->init_count = count;
+  ibarrier->curr_event = 0;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_barrierattr_destroy.c b/libpthread/nptl/pthread_barrierattr_destroy.c
new file mode 100644 (file)
index 0000000..f947daf
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_barrierattr_destroy (attr)
+     pthread_barrierattr_t *attr;
+{
+  /* Nothing to do.  */
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_barrierattr_getpshared.c b/libpthread/nptl/pthread_barrierattr_getpshared.c
new file mode 100644 (file)
index 0000000..246c888
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_barrierattr_getpshared (attr, pshared)
+     const pthread_barrierattr_t *attr;
+     int *pshared;
+{
+  *pshared = ((const struct pthread_barrierattr *) attr)->pshared;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_barrierattr_init.c b/libpthread/nptl/pthread_barrierattr_init.c
new file mode 100644 (file)
index 0000000..a0be952
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_barrierattr_init (attr)
+     pthread_barrierattr_t *attr;
+{
+  ((struct pthread_barrierattr *) attr)->pshared = PTHREAD_PROCESS_PRIVATE;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_barrierattr_setpshared.c b/libpthread/nptl/pthread_barrierattr_setpshared.c
new file mode 100644 (file)
index 0000000..b69f23e
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+pthread_barrierattr_setpshared (attr, pshared)
+     pthread_barrierattr_t *attr;
+     int pshared;
+{
+  struct pthread_barrierattr *iattr;
+
+  if (pshared != PTHREAD_PROCESS_PRIVATE
+      && __builtin_expect (pshared != PTHREAD_PROCESS_SHARED, 0))
+    return EINVAL;
+
+  iattr = (struct pthread_barrierattr *) attr;
+
+  iattr->pshared = pshared;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_cancel.c b/libpthread/nptl/pthread_cancel.c
new file mode 100644 (file)
index 0000000..a13af56
--- /dev/null
@@ -0,0 +1,104 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <errno.h>
+#include <signal.h>
+#include "pthreadP.h"
+#include "atomic.h"
+#include <sysdep.h>
+#include <kernel-features.h>
+
+
+int
+pthread_cancel (th)
+     pthread_t th;
+{
+  volatile struct pthread *pd = (volatile struct pthread *) th;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+#ifdef SHARED
+  pthread_cancel_init ();
+#endif
+  int result = 0;
+  int oldval;
+  int newval;
+  do
+    {
+      oldval = pd->cancelhandling;
+      newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
+
+      /* Avoid doing unnecessary work.  The atomic operation can
+        potentially be expensive if the bug has to be locked and
+        remote cache lines have to be invalidated.  */
+      if (oldval == newval)
+       break;
+
+      /* If the cancellation is handled asynchronously just send a
+        signal.  We avoid this if possible since it's more
+        expensive.  */
+      if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
+       {
+         /* Mark the cancellation as "in progress".  */
+         atomic_bit_set (&pd->cancelhandling, CANCELING_BIT);
+
+         /* The cancellation handler will take care of marking the
+            thread as canceled.  */
+         INTERNAL_SYSCALL_DECL (err);
+
+         /* One comment: The PID field in the TCB can temporarily be
+            changed (in fork).  But this must not affect this code
+            here.  Since this function would have to be called while
+            the thread is executing fork, it would have to happen in
+            a signal handler.  But this is no allowed, pthread_cancel
+            is not guaranteed to be async-safe.  */
+         int val;
+#if __ASSUME_TGKILL
+         val = INTERNAL_SYSCALL (tgkill, err, 3,
+                                 THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
+                                 SIGCANCEL);
+#else
+# ifdef __NR_tgkill
+         val = INTERNAL_SYSCALL (tgkill, err, 3,
+                                 THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
+                                 SIGCANCEL);
+         if (INTERNAL_SYSCALL_ERROR_P (val, err)
+             && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
+# endif
+           val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL);
+#endif
+
+         if (INTERNAL_SYSCALL_ERROR_P (val, err))
+           result = INTERNAL_SYSCALL_ERRNO (val, err);
+
+         break;
+       }
+    }
+  /* Mark the thread as canceled.  This has to be done
+     atomically since other bits could be modified as well.  */
+  while (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, newval,
+                                              oldval));
+
+  return result;
+}
+
+PTHREAD_STATIC_FN_REQUIRE (pthread_create)
diff --git a/libpthread/nptl/pthread_clock_gettime.c b/libpthread/nptl/pthread_clock_gettime.c
new file mode 100644 (file)
index 0000000..a71174c
--- /dev/null
@@ -0,0 +1,69 @@
+/* Copyright (C) 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.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <libc-internal.h>
+#include "pthreadP.h"
+
+
+#if HP_TIMING_AVAIL
+int
+__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
+                        struct timespec *tp)
+{
+  hp_timing_t tsc;
+
+  /* Get the current counter.  */
+  HP_TIMING_NOW (tsc);
+
+  /* This is the ID of the thread we are looking for.  */
+  pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE;
+
+  /* Compute the offset since the start time of the process.  */
+  if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid))
+    /* Our own clock.  */
+    tsc -= THREAD_GETMEM (THREAD_SELF, cpuclock_offset);
+  else
+    {
+      /* This is more complicated.  We have to locate the thread based
+        on the ID.  This means walking the list of existing
+        threads.  */
+      struct pthread *thread = __find_thread_by_id (tid);
+      if (thread == NULL)
+       {
+         __set_errno (EINVAL);
+         return -1;
+       }
+
+      /* There is a race here.  The thread might terminate and the stack
+        become unusable.  But this is the user's problem.  */
+      tsc -= thread->cpuclock_offset;
+    }
+
+  /* Compute the seconds.  */
+  tp->tv_sec = tsc / freq;
+
+  /* And the nanoseconds.  This computation should be stable until
+     we get machines with about 16GHz frequency.  */
+  tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq;
+
+  return 0;
+}
+#endif
diff --git a/libpthread/nptl/pthread_clock_settime.c b/libpthread/nptl/pthread_clock_settime.c
new file mode 100644 (file)
index 0000000..61002a8
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright (C) 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.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <libc-internal.h>
+#include "pthreadP.h"
+
+
+#if HP_TIMING_AVAIL
+int
+__pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
+{
+  /* This is the ID of the thread we are looking for.  */
+  pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE;
+
+  /* Compute the offset since the start time of the process.  */
+  if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid))
+    /* Our own clock.  */
+    THREAD_SETMEM (THREAD_SELF, cpuclock_offset, offset);
+  else
+    {
+      /* This is more complicated.  We have to locate the thread based
+        on the ID.  This means walking the list of existing
+        threads.  */
+      struct pthread *thread = __find_thread_by_id (tid);
+      if (thread == NULL)
+       {
+         __set_errno (EINVAL);
+         return -1;
+       }
+
+      /* There is a race here.  The thread might terminate and the stack
+        become unusable.  But this is the user's problem.  */
+      thread->cpuclock_offset = offset;
+    }
+
+  return 0;
+}
+#endif
diff --git a/libpthread/nptl/pthread_cond_destroy.c b/libpthread/nptl/pthread_cond_destroy.c
new file mode 100644 (file)
index 0000000..0208d18
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <errno.h>
+#include <shlib-compat.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_cond_destroy (cond)
+     pthread_cond_t *cond;
+{
+  /* Make sure we are alone.  */
+  lll_mutex_lock (cond->__data.__lock);
+
+  if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
+    {
+      /* If there are still some waiters which have not been
+        woken up, this is an application bug.  */
+      lll_mutex_unlock (cond->__data.__lock);
+      return EBUSY;
+    }
+
+  /* Tell pthread_cond_*wait that this condvar is being destroyed.  */
+  cond->__data.__total_seq = -1ULL;
+
+  /* If there are waiters which have been already signalled or
+     broadcasted, but still are using the pthread_cond_t structure,
+     pthread_cond_destroy needs to wait for them.  */
+  unsigned int nwaiters = cond->__data.__nwaiters;
+  while (nwaiters >= (1 << COND_CLOCK_BITS))
+    {
+      lll_mutex_unlock (cond->__data.__lock);
+
+      lll_futex_wait (&cond->__data.__nwaiters, nwaiters);
+
+      lll_mutex_lock (cond->__data.__lock);
+
+      nwaiters = cond->__data.__nwaiters;
+    }
+
+  return 0;
+}
+versioned_symbol (libpthread, __pthread_cond_destroy,
+                 pthread_cond_destroy, GLIBC_2_3_2);
diff --git a/libpthread/nptl/pthread_cond_init.c b/libpthread/nptl/pthread_cond_init.c
new file mode 100644 (file)
index 0000000..5e2e670
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002, 2003, 2004, 2005 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.  */
+
+#include <shlib-compat.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_cond_init (cond, cond_attr)
+     pthread_cond_t *cond;
+     const pthread_condattr_t *cond_attr;
+{
+  struct pthread_condattr *icond_attr = (struct pthread_condattr *) cond_attr;
+
+  cond->__data.__lock = LLL_MUTEX_LOCK_INITIALIZER;
+  cond->__data.__futex = 0;
+  cond->__data.__nwaiters = (icond_attr != NULL
+                            && ((icond_attr->value & (COND_CLOCK_BITS << 1))
+                                >> 1));
+  cond->__data.__total_seq = 0;
+  cond->__data.__wakeup_seq = 0;
+  cond->__data.__woken_seq = 0;
+  cond->__data.__mutex = (icond_attr == NULL || (icond_attr->value & 1) == 0
+                         ? NULL : (void *) ~0l);
+  cond->__data.__broadcast_seq = 0;
+
+  return 0;
+}
+versioned_symbol (libpthread, __pthread_cond_init,
+                 pthread_cond_init, GLIBC_2_3_2);
diff --git a/libpthread/nptl/pthread_condattr_destroy.c b/libpthread/nptl/pthread_condattr_destroy.c
new file mode 100644 (file)
index 0000000..e6d069e
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+__pthread_condattr_destroy (attr)
+     pthread_condattr_t *attr;
+{
+  /* Nothing to be done.  */
+  return 0;
+}
+strong_alias (__pthread_condattr_destroy, pthread_condattr_destroy)
diff --git a/libpthread/nptl/pthread_condattr_getclock.c b/libpthread/nptl/pthread_condattr_getclock.c
new file mode 100644 (file)
index 0000000..84de918
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@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_condattr_getclock (attr, clock_id)
+     const pthread_condattr_t *attr;
+     clockid_t *clock_id;
+{
+  *clock_id = (((((const struct pthread_condattr *) attr)->value) >> 1)
+              & ((1 << COND_CLOCK_BITS) - 1));
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_condattr_getpshared.c b/libpthread/nptl/pthread_condattr_getpshared.c
new file mode 100644 (file)
index 0000000..b44eac9
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_condattr_getpshared (attr, pshared)
+     const pthread_condattr_t *attr;
+     int *pshared;
+{
+  *pshared = ((const struct pthread_condattr *) attr)->value & 1;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_condattr_init.c b/libpthread/nptl/pthread_condattr_init.c
new file mode 100644 (file)
index 0000000..738deb4
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002 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.  */
+
+#include <string.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_condattr_init (attr)
+     pthread_condattr_t *attr;
+{
+  memset (attr, '\0', sizeof (*attr));
+
+  return 0;
+}
+strong_alias (__pthread_condattr_init, pthread_condattr_init)
diff --git a/libpthread/nptl/pthread_condattr_setclock.c b/libpthread/nptl/pthread_condattr_setclock.c
new file mode 100644 (file)
index 0000000..04e246b
--- /dev/null
@@ -0,0 +1,72 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@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 <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <time.h>
+#include <sysdep.h>
+#include "pthreadP.h"
+#include <kernel-features.h>
+
+
+int
+pthread_condattr_setclock (attr, clock_id)
+     pthread_condattr_t *attr;
+     clockid_t clock_id;
+{
+  /* Only a few clocks are allowed.  CLOCK_REALTIME is always allowed.
+     CLOCK_MONOTONIC only if the kernel has the necessary support.  */
+  if (clock_id == CLOCK_MONOTONIC)
+    {
+#ifndef __ASSUME_POSIX_TIMERS
+# ifdef __NR_clock_getres
+      /* Check whether the clock is available.  */
+      static int avail;
+
+      if (avail == 0)
+       {
+         struct timespec ts;
+
+         INTERNAL_SYSCALL_DECL (err);
+         int val;
+         val = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
+         avail = INTERNAL_SYSCALL_ERROR_P (val, err) ? -1 : 1;
+       }
+
+      if (avail < 0)
+# endif
+       /* Not available.  */
+       return EINVAL;
+#endif
+    }
+  else if (clock_id != CLOCK_REALTIME)
+    /* If more clocks are allowed some day the storing of the clock ID
+       in the pthread_cond_t structure needs to be adjusted.  */
+    return EINVAL;
+
+  /* Make sure the value fits in the bits we reserved.  */
+  assert (clock_id < (1 << COND_CLOCK_BITS));
+
+  int *valuep = &((struct pthread_condattr *) attr)->value;
+
+  *valuep = (*valuep & ~(1 << (COND_CLOCK_BITS + 1)) & ~1) | (clock_id << 1);
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_condattr_setpshared.c b/libpthread/nptl/pthread_condattr_setpshared.c
new file mode 100644 (file)
index 0000000..f008587
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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.  */
+
+#include <errno.h>
+#include <pthreadP.h>
+
+int
+pthread_condattr_setpshared (attr, pshared)
+     pthread_condattr_t *attr;
+     int pshared;
+{
+  if (pshared != PTHREAD_PROCESS_PRIVATE
+      && __builtin_expect (pshared != PTHREAD_PROCESS_SHARED, 0))
+    return EINVAL;
+
+  int *valuep = &((struct pthread_condattr *) attr)->value;
+
+  *valuep = (*valuep & ~1) | (pshared != PTHREAD_PROCESS_PRIVATE);
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_create.c b/libpthread/nptl/pthread_create.c
new file mode 100644 (file)
index 0000000..18f1c03
--- /dev/null
@@ -0,0 +1,520 @@
+/* Copyright (C) 2002, 2003, 2004, 2005 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.  */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pthreadP.h"
+#include <hp-timing.h>
+#include <ldsodefs.h>
+#include <atomic.h>
+#include <libc-internal.h>
+#include <resolv.h>
+
+#include <shlib-compat.h>
+
+
+/* Local function to start thread and handle cleanup.  */
+static int start_thread (void *arg);
+
+
+/* Nozero if debugging mode is enabled.  */
+int __pthread_debug;
+
+/* Globally enabled events.  */
+static td_thr_events_t __nptl_threads_events;
+
+/* Pointer to descriptor with the last event.  */
+static struct pthread *__nptl_last_event;
+
+/* Number of threads running.  */
+unsigned int __nptl_nthreads = 1;
+
+
+/* Code to allocate and deallocate a stack.  */
+#include "allocatestack.c"
+
+/* Code to create the thread.  */
+#include "createthread.c"
+
+
+struct pthread *
+internal_function
+__find_in_stack_list (pd)
+     struct pthread *pd;
+{
+  list_t *entry;
+  struct pthread *result = NULL;
+
+  lll_lock (stack_cache_lock);
+
+  list_for_each (entry, &stack_used)
+    {
+      struct pthread *curp;
+
+      curp = list_entry (entry, struct pthread, list);
+      if (curp == pd)
+       {
+         result = curp;
+         break;
+       }
+    }
+
+  if (result == NULL)
+    list_for_each (entry, &__stack_user)
+      {
+       struct pthread *curp;
+
+       curp = list_entry (entry, struct pthread, list);
+       if (curp == pd)
+         {
+           result = curp;
+           break;
+         }
+      }
+
+  lll_unlock (stack_cache_lock);
+
+  return result;
+}
+
+
+/* Deallocate POSIX thread-local-storage.  */
+void
+attribute_hidden
+__nptl_deallocate_tsd (void)
+{
+  struct pthread *self = THREAD_SELF;
+
+  /* Maybe no data was ever allocated.  This happens often so we have
+     a flag for this.  */
+  if (THREAD_GETMEM (self, specific_used))
+    {
+      size_t round;
+      size_t cnt;
+
+      round = 0;
+      do
+       {
+         size_t idx;
+
+         /* So far no new nonzero data entry.  */
+         THREAD_SETMEM (self, specific_used, false);
+
+         for (cnt = idx = 0; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
+           {
+             struct pthread_key_data *level2;
+
+             level2 = THREAD_GETMEM_NC (self, specific, cnt);
+
+             if (level2 != NULL)
+               {
+                 size_t inner;
+
+                 for (inner = 0; inner < PTHREAD_KEY_2NDLEVEL_SIZE;
+                      ++inner, ++idx)
+                   {
+                     void *data = level2[inner].data;
+
+                     if (data != NULL)
+                       {
+                         /* Always clear the data.  */
+                         level2[inner].data = NULL;
+
+                         /* Make sure the data corresponds to a valid
+                            key.  This test fails if the key was
+                            deallocated and also if it was
+                            re-allocated.  It is the user's
+                            responsibility to free the memory in this
+                            case.  */
+                         if (level2[inner].seq
+                             == __pthread_keys[idx].seq
+                             /* It is not necessary to register a destructor
+                                function.  */
+                             && __pthread_keys[idx].destr != NULL)
+                           /* Call the user-provided destructor.  */
+                           __pthread_keys[idx].destr (data);
+                       }
+                   }
+               }
+             else
+               idx += PTHREAD_KEY_1STLEVEL_SIZE;
+           }
+
+         if (THREAD_GETMEM (self, specific_used) == 0)
+           /* No data has been modified.  */
+           goto just_free;
+       }
+      /* We only repeat the process a fixed number of times.  */
+      while (__builtin_expect (++round < PTHREAD_DESTRUCTOR_ITERATIONS, 0));
+
+      /* Just clear the memory of the first block for reuse.  */
+      memset (&THREAD_SELF->specific_1stblock, '\0',
+             sizeof (self->specific_1stblock));
+
+    just_free:
+      /* Free the memory for the other blocks.  */
+      for (cnt = 1; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
+       {
+         struct pthread_key_data *level2;
+
+         level2 = THREAD_GETMEM_NC (self, specific, cnt);
+         if (level2 != NULL)
+           {
+             /* The first block is allocated as part of the thread
+                descriptor.  */
+             free (level2);
+             THREAD_SETMEM_NC (self, specific, cnt, NULL);
+           }
+       }
+
+      THREAD_SETMEM (self, specific_used, false);
+    }
+}
+
+
+/* Deallocate a thread's stack after optionally making sure the thread
+   descriptor is still valid.  */
+void
+internal_function
+__free_tcb (struct pthread *pd)
+{
+  /* The thread is exiting now.  */
+  if (__builtin_expect (atomic_bit_test_set (&pd->cancelhandling,
+                                            TERMINATED_BIT) == 0, 1))
+    {
+      /* Remove the descriptor from the list.  */
+      if (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
+       /* Something is really wrong.  The descriptor for a still
+          running thread is gone.  */
+       abort ();
+
+      /* Queue the stack memory block for reuse and exit the process.  The
+        kernel will signal via writing to the address returned by
+        QUEUE-STACK when the stack is available.  */
+      __deallocate_stack (pd);
+    }
+}
+
+
+static int
+start_thread (void *arg)
+{
+  struct pthread *pd = (struct pthread *) arg;
+
+#if HP_TIMING_AVAIL
+  /* Remember the time when the thread was started.  */
+  hp_timing_t now;
+  HP_TIMING_NOW (now);
+  THREAD_SETMEM (pd, cpuclock_offset, now);
+#endif
+
+  /* Initialize resolver state pointer.  */
+  __resp = &pd->res;
+
+  /* This is where the try/finally block should be created.  For
+     compilers without that support we do use setjmp.  */
+  struct pthread_unwind_buf unwind_buf;
+
+  /* No previous handlers.  */
+  unwind_buf.priv.data.prev = NULL;
+  unwind_buf.priv.data.cleanup = NULL;
+
+  int not_first_call;
+  not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+  if (__builtin_expect (! not_first_call, 1))
+    {
+      /* Store the new cleanup handler info.  */
+      THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf);
+
+      if (__builtin_expect (pd->stopped_start, 0))
+       {
+         int oldtype = CANCEL_ASYNC ();
+
+         /* Get the lock the parent locked to force synchronization.  */
+         lll_lock (pd->lock);
+         /* And give it up right away.  */
+         lll_unlock (pd->lock);
+
+         CANCEL_RESET (oldtype);
+       }
+
+      /* Run the code the user provided.  */
+#ifdef CALL_THREAD_FCT
+      THREAD_SETMEM (pd, result, CALL_THREAD_FCT (pd));
+#else
+      THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));
+#endif
+    }
+
+  /* Run the destructor for the thread-local data.  */
+  __nptl_deallocate_tsd ();
+
+  /* Clean up any state libc stored in thread-local variables.  */
+  __libc_thread_freeres ();
+
+  /* If this is the last thread we terminate the process now.  We
+     do not notify the debugger, it might just irritate it if there
+     is no thread left.  */
+  if (__builtin_expect (atomic_decrement_and_test (&__nptl_nthreads), 0))
+    /* This was the last thread.  */
+    exit (0);
+
+  /* Report the death of the thread if this is wanted.  */
+  if (__builtin_expect (pd->report_events, 0))
+    {
+      /* See whether TD_DEATH is in any of the mask.  */
+      const int idx = __td_eventword (TD_DEATH);
+      const uint32_t mask = __td_eventmask (TD_DEATH);
+
+      if ((mask & (__nptl_threads_events.event_bits[idx]
+                  | pd->eventbuf.eventmask.event_bits[idx])) != 0)
+       {
+         /* Yep, we have to signal the death.  Add the descriptor to
+            the list but only if it is not already on it.  */
+         if (pd->nextevent == NULL)
+           {
+             pd->eventbuf.eventnum = TD_DEATH;
+             pd->eventbuf.eventdata = pd;
+
+             do
+               pd->nextevent = __nptl_last_event;
+             while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
+                                                          pd, pd->nextevent));
+           }
+
+         /* Now call the function to signal the event.  */
+         __nptl_death_event ();
+       }
+    }
+
+  /* The thread is exiting now.  Don't set this bit until after we've hit
+     the event-reporting breakpoint, so that td_thr_get_info on us while at
+     the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE.  */
+  atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
+
+  /* If the thread is detached free the TCB.  */
+  if (IS_DETACHED (pd))
+    /* Free the TCB.  */
+    __free_tcb (pd);
+
+  /* We cannot call '_exit' here.  '_exit' will terminate the process.
+
+     The 'exit' implementation in the kernel will signal when the
+     process is really dead since 'clone' got passed the CLONE_CLEARTID
+     flag.  The 'tid' field in the TCB will be set to zero.
+
+     The exit code is zero since in case all threads exit by calling
+     'pthread_exit' the exit status must be 0 (zero).  */
+  __exit_thread_inline (0);
+
+  /* NOTREACHED */
+  return 0;
+}
+
+
+/* Default thread attributes for the case when the user does not
+   provide any.  */
+static const struct pthread_attr default_attr =
+  {
+    /* Just some value > 0 which gets rounded to the nearest page size.  */
+    .guardsize = 1,
+  };
+
+
+int
+__pthread_create_2_1 (newthread, attr, start_routine, arg)
+     pthread_t *newthread;
+     const pthread_attr_t *attr;
+     void *(*start_routine) (void *);
+     void *arg;
+{
+  STACK_VARIABLES;
+
+  const struct pthread_attr *iattr = (struct pthread_attr *) attr;
+  if (iattr == NULL)
+    /* Is this the best idea?  On NUMA machines this could mean
+       accessing far-away memory.  */
+    iattr = &default_attr;
+
+  struct pthread *pd;
+  int err = ALLOCATE_STACK (iattr, &pd);
+  if (__builtin_expect (err != 0, 0))
+    /* Something went wrong.  Maybe a parameter of the attributes is
+       invalid or we could not allocate memory.  */
+    return err;
+
+
+  /* Initialize the TCB.  All initializations with zero should be
+     performed in 'get_cached_stack'.  This way we avoid doing this if
+     the stack freshly allocated with 'mmap'.  */
+
+#ifdef TLS_TCB_AT_TP
+  /* Reference to the TCB itself.  */
+  pd->header.self = pd;
+
+  /* Self-reference for TLS.  */
+  pd->header.tcb = pd;
+#endif
+
+  /* Store the address of the start routine and the parameter.  Since
+     we do not start the function directly the stillborn thread will
+     get the information from its thread descriptor.  */
+  pd->start_routine = start_routine;
+  pd->arg = arg;
+
+  /* Copy the thread attribute flags.  */
+  struct pthread *self = THREAD_SELF;
+  pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
+              | (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)));
+
+  /* Initialize the field for the ID of the thread which is waiting
+     for us.  This is a self-reference in case the thread is created
+     detached.  */
+  pd->joinid = iattr->flags & ATTR_FLAG_DETACHSTATE ? pd : NULL;
+
+  /* The debug events are inherited from the parent.  */
+  pd->eventbuf = self->eventbuf;
+
+
+  /* Copy the parent's scheduling parameters.  The flags will say what
+     is valid and what is not.  */
+  pd->schedpolicy = self->schedpolicy;
+  pd->schedparam = self->schedparam;
+
+  /* Determine scheduling parameters for the thread.  */
+  if (attr != NULL
+      && __builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
+      && (iattr->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) != 0)
+    {
+      INTERNAL_SYSCALL_DECL (scerr);
+
+      /* Use the scheduling parameters the user provided.  */
+      if (iattr->flags & ATTR_FLAG_POLICY_SET)
+       pd->schedpolicy = iattr->schedpolicy;
+      else if ((pd->flags & ATTR_FLAG_POLICY_SET) == 0)
+       {
+         pd->schedpolicy = INTERNAL_SYSCALL (sched_getscheduler, scerr, 1, 0);
+         pd->flags |= ATTR_FLAG_POLICY_SET;
+       }
+
+      if (iattr->flags & ATTR_FLAG_SCHED_SET)
+       memcpy (&pd->schedparam, &iattr->schedparam,
+               sizeof (struct sched_param));
+      else if ((pd->flags & ATTR_FLAG_SCHED_SET) == 0)
+       {
+         INTERNAL_SYSCALL (sched_getparam, scerr, 2, 0, &pd->schedparam);
+         pd->flags |= ATTR_FLAG_SCHED_SET;
+       }
+
+      /* Check for valid priorities.  */
+      int minprio = INTERNAL_SYSCALL (sched_get_priority_min, scerr, 1,
+                                     iattr->schedpolicy);
+      int maxprio = INTERNAL_SYSCALL (sched_get_priority_max, scerr, 1,
+                                     iattr->schedpolicy);
+      if (pd->schedparam.sched_priority < minprio
+         || pd->schedparam.sched_priority > maxprio)
+       {
+         err = EINVAL;
+         goto errout;
+       }
+    }
+
+  /* Pass the descriptor to the caller.  */
+  *newthread = (pthread_t) pd;
+
+  /* Remember whether the thread is detached or not.  In case of an
+     error we have to free the stacks of non-detached stillborn
+     threads.  */
+  bool is_detached = IS_DETACHED (pd);
+
+  /* Start the thread.  */
+  err = create_thread (pd, iattr, STACK_VARIABLES_ARGS);
+  if (err != 0)
+    {
+      /* Something went wrong.  Free the resources.  */
+      if (!is_detached)
+       {
+       errout:
+         __deallocate_stack (pd);
+       }
+      return err;
+    }
+
+  return 0;
+}
+versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1);
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+__pthread_create_2_0 (newthread, attr, start_routine, arg)
+     pthread_t *newthread;
+     const pthread_attr_t *attr;
+     void *(*start_routine) (void *);
+     void *arg;
+{
+  /* The ATTR attribute is not really of type `pthread_attr_t *'.  It has
+     the old size and access to the new members might crash the program.
+     We convert the struct now.  */
+  struct pthread_attr new_attr;
+
+  if (attr != NULL)
+    {
+      struct pthread_attr *iattr = (struct pthread_attr *) attr;
+      size_t ps = __getpagesize ();
+
+      /* Copy values from the user-provided attributes.  */
+      new_attr.schedparam = iattr->schedparam;
+      new_attr.schedpolicy = iattr->schedpolicy;
+      new_attr.flags = iattr->flags;
+
+      /* Fill in default values for the fields not present in the old
+        implementation.  */
+      new_attr.guardsize = ps;
+      new_attr.stackaddr = NULL;
+      new_attr.stacksize = 0;
+      new_attr.cpuset = NULL;
+
+      /* We will pass this value on to the real implementation.  */
+      attr = (pthread_attr_t *) &new_attr;
+    }
+
+  return __pthread_create_2_1 (newthread, attr, start_routine, arg);
+}
+compat_symbol (libpthread, __pthread_create_2_0, pthread_create,
+              GLIBC_2_0);
+#endif
+\f
+/* Information for libthread_db.  */
+
+#include "../nptl_db/db_info.c"
+\f
+/* If pthread_create is present, libgcc_eh.a and libsupc++.a expects some other POSIX thread
+   functions to be present as well.  */
+PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_lock)
+PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_unlock)
+
+PTHREAD_STATIC_FN_REQUIRE (pthread_once)
+PTHREAD_STATIC_FN_REQUIRE (pthread_cancel)
+
+PTHREAD_STATIC_FN_REQUIRE (pthread_key_create)
+PTHREAD_STATIC_FN_REQUIRE (pthread_setspecific)
+PTHREAD_STATIC_FN_REQUIRE (pthread_getspecific)
diff --git a/libpthread/nptl/pthread_detach.c b/libpthread/nptl/pthread_detach.c
new file mode 100644 (file)
index 0000000..1f0c2fe
--- /dev/null
@@ -0,0 +1,57 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <atomic.h>
+
+
+int
+pthread_detach (th)
+     pthread_t th;
+{
+  struct pthread *pd = (struct pthread *) th;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_NOT_TERMINATED_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  int result = 0;
+
+  /* Mark the thread as detached.  */
+  if (atomic_compare_and_exchange_bool_acq (&pd->joinid, pd, NULL))
+    {
+      /* There are two possibilities here.  First, the thread might
+        already be detached.  In this case we return EINVAL.
+        Otherwise there might already be a waiter.  The standard does
+        not mention what happens in this case.  */
+      if (IS_DETACHED (pd))
+       result = EINVAL;
+    }
+  else
+    /* Check whether the thread terminated meanwhile.  In this case we
+       will just free the TCB.  */
+    if ((pd->cancelhandling & EXITING_BITMASK) != 0)
+      /* Note that the code in __free_tcb makes sure each thread
+        control block is freed only once.  */
+      __free_tcb (pd);
+
+  return result;
+}
diff --git a/libpthread/nptl/pthread_equal.c b/libpthread/nptl/pthread_equal.c
new file mode 100644 (file)
index 0000000..c998609
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+__pthread_equal (thread1, thread2)
+     pthread_t thread1;
+     pthread_t thread2;
+{
+  return thread1 == thread2;
+}
+strong_alias (__pthread_equal, pthread_equal)
diff --git a/libpthread/nptl/pthread_exit.c b/libpthread/nptl/pthread_exit.c
new file mode 100644 (file)
index 0000000..85d8fd4
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002 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.  */
+
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+void
+__pthread_exit (value)
+     void *value;
+{
+  THREAD_SETMEM (THREAD_SELF, result, value);
+
+  __do_cancel ();
+}
+strong_alias (__pthread_exit, pthread_exit)
diff --git a/libpthread/nptl/pthread_getattr_np.c b/libpthread/nptl/pthread_getattr_np.c
new file mode 100644 (file)
index 0000000..ba720af
--- /dev/null
@@ -0,0 +1,177 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+#include <ldsodefs.h>
+
+
+int
+pthread_getattr_np (thread_id, attr)
+     pthread_t thread_id;
+     pthread_attr_t *attr;
+{
+  struct pthread *thread = (struct pthread *) thread_id;
+  struct pthread_attr *iattr = (struct pthread_attr *) attr;
+  int ret = 0;
+
+  /* We have to handle cancellation in the following code since we are
+     locking another threads desriptor.  */
+  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &thread->lock);
+
+  lll_lock (thread->lock);
+
+  /* The thread library is responsible for keeping the values in the
+     thread desriptor up-to-date in case the user changes them.  */
+  memcpy (&iattr->schedparam, &thread->schedparam,
+         sizeof (struct sched_param));
+  iattr->schedpolicy = thread->schedpolicy;
+
+  /* Clear the flags work.  */
+  iattr->flags = thread->flags;
+
+  /* The thread might be detached by now.  */
+  if (IS_DETACHED (thread))
+    iattr->flags |= ATTR_FLAG_DETACHSTATE;
+
+  /* This is the guardsize after adjusting it.  */
+  iattr->guardsize = thread->reported_guardsize;
+
+  /* The sizes are subject to alignment.  */
+  if (__builtin_expect (thread->stackblock != NULL, 1))
+    {
+      iattr->stacksize = thread->stackblock_size;
+      iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
+    }
+  else
+    {
+      /* No stack information available.  This must be for the initial
+        thread.  Get the info in some magical way.  */
+      assert (abs (thread->pid) == thread->tid);
+
+      /* Stack size limit.  */
+      struct rlimit rl;
+
+      /* The safest way to get the top of the stack is to read
+        /proc/self/maps and locate the line into which
+        __libc_stack_end falls.  */
+      FILE *fp = fopen ("/proc/self/maps", "rc");
+      if (fp == NULL)
+       ret = errno;
+      /* We need the limit of the stack in any case.  */
+      else if (getrlimit (RLIMIT_STACK, &rl) != 0)
+       ret = errno;
+      else
+       {
+         /* We need no locking.  */
+         __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+         /* Until we found an entry (which should always be the case)
+            mark the result as a failure.  */
+         ret = ENOENT;
+
+         char *line = NULL;
+         size_t linelen = 0;
+         uintptr_t last_to = 0;
+
+         while (! feof_unlocked (fp))
+           {
+             if (__getdelim (&line, &linelen, '\n', fp) <= 0)
+               break;
+
+             uintptr_t from;
+             uintptr_t to;
+             if (sscanf (line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2)
+               continue;
+             if (from <= (uintptr_t) __libc_stack_end
+                 && (uintptr_t) __libc_stack_end < to)
+               {
+                 /* Found the entry.  Now we have the info we need.  */
+                 iattr->stacksize = rl.rlim_cur;
+                 iattr->stackaddr = (void *) to;
+
+                 /* The limit might be too high.  */
+                 if ((size_t) iattr->stacksize
+                     > (size_t) iattr->stackaddr - last_to)
+                   iattr->stacksize = (size_t) iattr->stackaddr - last_to;
+
+                 /* We succeed and no need to look further.  */
+                 ret = 0;
+                 break;
+               }
+             last_to = to;
+           }
+
+         fclose (fp);
+         free (line);
+       }
+    }
+
+  iattr->flags |= ATTR_FLAG_STACKADDR;
+
+  if (ret == 0)
+    {
+      size_t size = 16;
+      cpu_set_t *cpuset = NULL;
+
+      do
+       {
+         size <<= 1;
+
+         void *newp = realloc (cpuset, size);
+         if (newp == NULL)
+           {
+             ret = ENOMEM;
+             break;
+           }
+         cpuset = (cpu_set_t *) newp;
+
+         ret = __pthread_getaffinity_np (thread_id, size, cpuset);
+       }
+      /* Pick some ridiculous upper limit.  Is 8 million CPUs enough?  */
+      while (ret == EINVAL && size < 1024 * 1024);
+
+      if (ret == 0)
+       {
+         iattr->cpuset = cpuset;
+         iattr->cpusetsize = size;
+       }
+      else
+       {
+         free (cpuset);
+         if (ret == ENOSYS)
+           /* There is no such functionality.  */
+           ret = 0;
+       }
+    }
+
+  lll_unlock (thread->lock);
+
+  pthread_cleanup_pop (0);
+
+  return ret;
+}
diff --git a/libpthread/nptl/pthread_getconcurrency.c b/libpthread/nptl/pthread_getconcurrency.c
new file mode 100644 (file)
index 0000000..52c0c7c
--- /dev/null
@@ -0,0 +1,27 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_getconcurrency (void)
+{
+  return __concurrency_level;
+}
diff --git a/libpthread/nptl/pthread_getschedparam.c b/libpthread/nptl/pthread_getschedparam.c
new file mode 100644 (file)
index 0000000..434d867
--- /dev/null
@@ -0,0 +1,81 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <errno.h>
+#include <string.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+__pthread_getschedparam (threadid, policy, param)
+     pthread_t threadid;
+     int *policy;
+     struct sched_param *param;
+{
+  struct pthread *pd = (struct pthread *) threadid;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  int result = 0;
+
+  /* We have to handle cancellation in the following code since we are
+     locking another threads descriptor.  */
+  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
+
+  lll_lock (pd->lock);
+
+  /* The library is responsible for maintaining the values at all
+     times.  If the user uses a interface other than
+     pthread_setschedparam to modify the scheduler setting it is not
+     the library's problem.  In case the descriptor's values have
+     not yet been retrieved do it now.  */
+  if ((pd->flags & ATTR_FLAG_SCHED_SET) == 0)
+    {
+      if (__sched_getparam (pd->tid, &pd->schedparam) != 0)
+       result = 1;
+      else
+       pd->flags |= ATTR_FLAG_SCHED_SET;
+    }
+
+  if ((pd->flags & ATTR_FLAG_POLICY_SET) == 0)
+    {
+      pd->schedpolicy = __sched_getscheduler (pd->tid);
+      if (pd->schedpolicy == -1)
+       result = 1;
+      else
+       pd->flags |= ATTR_FLAG_POLICY_SET;
+    }
+
+  if (result == 0)
+    {
+      *policy = pd->schedpolicy;
+      memcpy (param, &pd->schedparam, sizeof (struct sched_param));
+    }
+
+  lll_unlock (pd->lock);
+
+  pthread_cleanup_pop (0);
+
+  return result;
+}
+strong_alias (__pthread_getschedparam, pthread_getschedparam)
diff --git a/libpthread/nptl/pthread_getspecific.c b/libpthread/nptl/pthread_getspecific.c
new file mode 100644 (file)
index 0000000..afb4d26
--- /dev/null
@@ -0,0 +1,69 @@
+/* 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.  */
+
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+void *
+__pthread_getspecific (key)
+     pthread_key_t key;
+{
+  struct pthread_key_data *data;
+
+  /* Special case access to the first 2nd-level block.  This is the
+     usual case.  */
+  if (__builtin_expect (key < PTHREAD_KEY_2NDLEVEL_SIZE, 1))
+    data = &THREAD_SELF->specific_1stblock[key];
+  else
+    {
+      /* Verify the key is sane.  */
+      if (key >= PTHREAD_KEYS_MAX)
+       /* Not valid.  */
+       return NULL;
+
+      unsigned int idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
+      unsigned int idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
+
+      /* If the sequence number doesn't match or the key cannot be defined
+        for this thread since the second level array is not allocated
+        return NULL, too.  */
+      struct pthread_key_data *level2 = THREAD_GETMEM_NC (THREAD_SELF,
+                                                         specific, idx1st);
+      if (level2 == NULL)
+       /* Not allocated, therefore no data.  */
+       return NULL;
+
+      /* There is data.  */
+      data = &level2[idx2nd];
+    }
+
+  void *result = data->data;
+  if (result != NULL)
+    {
+      uintptr_t seq = data->seq;
+
+      if (__builtin_expect (seq != __pthread_keys[key].seq, 0))
+       result = data->data = NULL;
+    }
+
+  return result;
+}
+strong_alias (__pthread_getspecific, pthread_getspecific)
+strong_alias (__pthread_getspecific, __pthread_getspecific_internal)
diff --git a/libpthread/nptl/pthread_join.c b/libpthread/nptl/pthread_join.c
new file mode 100644 (file)
index 0000000..f94128d
--- /dev/null
@@ -0,0 +1,108 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "atomic.h"
+#include "pthreadP.h"
+
+
+static void
+cleanup (void *arg)
+{
+  *(void **) arg = NULL;
+}
+
+
+int
+pthread_join (threadid, thread_return)
+     pthread_t threadid;
+     void **thread_return;
+{
+  struct pthread *self;
+  struct pthread *pd = (struct pthread *) threadid;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_NOT_TERMINATED_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  /* Is the thread joinable?.  */
+  if (IS_DETACHED (pd))
+    /* We cannot wait for the thread.  */
+    return EINVAL;
+
+  self = THREAD_SELF;
+  if (pd == self
+      || (self->joinid == pd
+         && (pd->cancelhandling
+             & (CANCELING_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
+                | TERMINATED_BITMASK)) == 0))
+    /* This is a deadlock situation.  The threads are waiting for each
+       other to finish.  Note that this is a "may" error.  To be 100%
+       sure we catch this error we would have to lock the data
+       structures but it is not necessary.  In the unlikely case that
+       two threads are really caught in this situation they will
+       deadlock.  It is the programmer's problem to figure this
+       out.  */
+    return EDEADLK;
+
+  /* Wait for the thread to finish.  If it is already locked something
+     is wrong.  There can only be one waiter.  */
+  if (__builtin_expect (atomic_compare_and_exchange_bool_acq (&pd->joinid,
+                                                             self,
+                                                             NULL), 0))
+    /* There is already somebody waiting for the thread.  */
+    return EINVAL;
+
+
+  /* During the wait we change to asynchronous cancellation.  If we
+     are cancelled the thread we are waiting for must be marked as
+     un-wait-ed for again.  */
+  pthread_cleanup_push (cleanup, &pd->joinid);
+
+  /* Switch to asynchronous cancellation.  */
+  int oldtype = CANCEL_ASYNC ();
+
+
+  /* Wait for the child.  */
+  lll_wait_tid (pd->tid);
+
+
+  /* Restore cancellation mode.  */
+  CANCEL_RESET (oldtype);
+
+  /* Remove the handler.  */
+  pthread_cleanup_pop (0);
+
+
+  /* We mark the thread as terminated and as joined.  */
+  pd->tid = -1;
+
+  /* Store the return value if the caller is interested.  */
+  if (thread_return != NULL)
+    *thread_return = pd->result;
+
+
+  /* Free the TCB.  */
+  __free_tcb (pd);
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_key_create.c b/libpthread/nptl/pthread_key_create.c
new file mode 100644 (file)
index 0000000..cf35bc8
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+
+/* Internal mutex for __pthread_keys table handling.  */
+lll_lock_t __pthread_keys_lock = LLL_LOCK_INITIALIZER;
+
+int
+__pthread_key_create (key, destr)
+     pthread_key_t *key;
+     void (*destr) (void *);
+{
+  int result = EAGAIN;
+  size_t cnt;
+
+  lll_lock (__pthread_keys_lock);
+
+  /* Find a slot in __pthread_kyes which is unused.  */
+  for (cnt = 0; cnt < PTHREAD_KEYS_MAX; ++cnt)
+    if (KEY_UNUSED (__pthread_keys[cnt].seq)
+       && KEY_USABLE (__pthread_keys[cnt].seq))
+      {
+       /* We found an unused slot.  */
+       ++__pthread_keys[cnt].seq;
+
+       /* Remember the destructor.  */
+       __pthread_keys[cnt].destr = destr;
+
+       /* Return the key to the caller.  */
+       *key = cnt;
+
+       /* The call succeeded.  */
+       result = 0;
+
+       /* We found a key and can stop now.  */
+       break;
+      }
+
+  lll_unlock (__pthread_keys_lock);
+
+  return result;
+}
+strong_alias (__pthread_key_create, pthread_key_create)
+strong_alias (__pthread_key_create, __pthread_key_create_internal)
diff --git a/libpthread/nptl/pthread_key_delete.c b/libpthread/nptl/pthread_key_delete.c
new file mode 100644 (file)
index 0000000..ae7d7c4
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <atomic.h>
+
+
+int
+pthread_key_delete (key)
+     pthread_key_t key;
+{
+  int result = EINVAL;
+
+  if (__builtin_expect (key < PTHREAD_KEYS_MAX, 1))
+    {
+      unsigned int seq = __pthread_keys[key].seq;
+
+      if (__builtin_expect (! KEY_UNUSED (seq), 1)
+         && ! atomic_compare_and_exchange_bool_acq (&__pthread_keys[key].seq,
+                                                    seq + 1, seq))
+       /* We deleted a valid key.  */
+       result = 0;
+    }
+
+  return result;
+}
diff --git a/libpthread/nptl/pthread_kill_other_threads.c b/libpthread/nptl/pthread_kill_other_threads.c
new file mode 100644 (file)
index 0000000..a446423
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (C) 2002 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.  */
+
+#include <shlib-compat.h>
+
+
+#ifdef SHARED
+/* This function does not serve a useful purpose in the thread library
+   implementation anymore.  It used to be necessary when then kernel
+   could not shut down "processes" but this is not the case anymore.
+
+   We could theoretically provide an equivalent implementation but
+   this is not necessary since the kernel already does a much better
+   job than we ever could.  */
+void
+__pthread_kill_other_threads_np (void)
+{
+}
+compat_symbol (libpthread, __pthread_kill_other_threads_np,
+              pthread_kill_other_threads_np, GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/pthread_mutex_destroy.c b/libpthread/nptl/pthread_mutex_destroy.c
new file mode 100644 (file)
index 0000000..91ccfb0
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_mutex_destroy (mutex)
+     pthread_mutex_t *mutex;
+{
+  if (mutex->__data.__nusers != 0)
+    return EBUSY;
+
+  return 0;
+}
+strong_alias (__pthread_mutex_destroy, pthread_mutex_destroy)
+INTDEF(__pthread_mutex_destroy)
diff --git a/libpthread/nptl/pthread_mutex_init.c b/libpthread/nptl/pthread_mutex_init.c
new file mode 100644 (file)
index 0000000..074941d
--- /dev/null
@@ -0,0 +1,58 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <assert.h>
+#include <string.h>
+#include "pthreadP.h"
+
+
+static const struct pthread_mutexattr default_attr =
+  {
+    /* Default is a normal mutex, not shared between processes.  */
+    .mutexkind = PTHREAD_MUTEX_NORMAL
+  };
+
+
+int
+__pthread_mutex_init (mutex, mutexattr)
+     pthread_mutex_t *mutex;
+     const pthread_mutexattr_t *mutexattr;
+{
+  const struct pthread_mutexattr *imutexattr;
+
+  assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T);
+
+  imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
+
+  /* Clear the whole variable.  */
+  memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T);
+
+  /* Copy the values from the attribute.  */
+  mutex->__data.__kind = imutexattr->mutexkind & ~0x80000000;
+
+  /* Default values: mutex not used yet.  */
+  // mutex->__count = 0;       already done by memset
+  // mutex->__owner = 0;       already done by memset
+  // mutex->__nusers = 0;      already done by memset
+  // mutex->__spins = 0;       already done by memset
+
+  return 0;
+}
+strong_alias (__pthread_mutex_init, pthread_mutex_init)
+INTDEF(__pthread_mutex_init)
diff --git a/libpthread/nptl/pthread_mutex_lock.c b/libpthread/nptl/pthread_mutex_lock.c
new file mode 100644 (file)
index 0000000..ee39f20
--- /dev/null
@@ -0,0 +1,119 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <assert.h>
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+#ifndef LLL_MUTEX_LOCK
+# define LLL_MUTEX_LOCK(mutex) lll_mutex_lock (mutex)
+# define LLL_MUTEX_TRYLOCK(mutex) lll_mutex_trylock (mutex)
+#endif
+
+
+int
+__pthread_mutex_lock (mutex)
+     pthread_mutex_t *mutex;
+{
+  assert (sizeof (mutex->__size) >= sizeof (mutex->__data));
+
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+
+  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+    {
+      /* Recursive mutex.  */
+    case PTHREAD_MUTEX_RECURSIVE_NP:
+      /* Check whether we already hold the mutex.  */
+      if (mutex->__data.__owner == id)
+       {
+         /* Just bump the counter.  */
+         if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+           /* Overflow of the counter.  */
+           return EAGAIN;
+
+         ++mutex->__data.__count;
+
+         return 0;
+       }
+
+      /* We have to get the mutex.  */
+      LLL_MUTEX_LOCK (mutex->__data.__lock);
+
+      mutex->__data.__count = 1;
+      break;
+
+      /* Error checking mutex.  */
+    case PTHREAD_MUTEX_ERRORCHECK_NP:
+      /* Check whether we already hold the mutex.  */
+      if (mutex->__data.__owner == id)
+       return EDEADLK;
+
+      /* FALLTHROUGH */
+
+    default:
+      /* Correct code cannot set any other type.  */
+    case PTHREAD_MUTEX_TIMED_NP:
+    simple:
+      /* Normal mutex.  */
+      LLL_MUTEX_LOCK (mutex->__data.__lock);
+      break;
+
+    case PTHREAD_MUTEX_ADAPTIVE_NP:
+      if (! __is_smp)
+       goto simple;
+
+      if (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0)
+       {
+         int cnt = 0;
+         int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
+                            mutex->__data.__spins * 2 + 10);
+         do
+           {
+             if (cnt++ >= max_cnt)
+               {
+                 LLL_MUTEX_LOCK (mutex->__data.__lock);
+                 break;
+               }
+
+#ifdef BUSY_WAIT_NOP
+             BUSY_WAIT_NOP;
+#endif
+           }
+         while (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0);
+
+         mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
+       }
+      break;
+    }
+
+  /* Record the ownership.  */
+  assert (mutex->__data.__owner == 0);
+  mutex->__data.__owner = id;
+#ifndef NO_INCR
+  ++mutex->__data.__nusers;
+#endif
+
+  return 0;
+}
+#ifndef __pthread_mutex_lock
+strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
+strong_alias (__pthread_mutex_lock, __pthread_mutex_lock_internal)
+#endif
diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c
new file mode 100644 (file)
index 0000000..1cd2c7e
--- /dev/null
@@ -0,0 +1,118 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+pthread_mutex_timedlock (mutex, abstime)
+     pthread_mutex_t *mutex;
+     const struct timespec *abstime;
+{
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+  int result = 0;
+
+  /* We must not check ABSTIME here.  If the thread does not block
+     abstime must not be checked for a valid value.  */
+
+  switch (mutex->__data.__kind)
+    {
+      /* Recursive mutex.  */
+    case PTHREAD_MUTEX_RECURSIVE_NP:
+      /* Check whether we already hold the mutex.  */
+      if (mutex->__data.__owner == id)
+       {
+         /* Just bump the counter.  */
+         if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+           /* Overflow of the counter.  */
+           return EAGAIN;
+
+         ++mutex->__data.__count;
+
+         goto out;
+       }
+      else
+       {
+         /* We have to get the mutex.  */
+         result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+
+         if (result != 0)
+           goto out;
+
+         /* Only locked once so far.  */
+         mutex->__data.__count = 1;
+       }
+      break;
+
+      /* Error checking mutex.  */
+    case PTHREAD_MUTEX_ERRORCHECK_NP:
+      /* Check whether we already hold the mutex.  */
+      if (mutex->__data.__owner == id)
+       return EDEADLK;
+
+      /* FALLTHROUGH */
+
+    default:
+      /* Correct code cannot set any other type.  */
+    case PTHREAD_MUTEX_TIMED_NP:
+    simple:
+      /* Normal mutex.  */
+      result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+      break;
+
+    case PTHREAD_MUTEX_ADAPTIVE_NP:
+      if (! __is_smp)
+       goto simple;
+
+      if (lll_mutex_trylock (mutex->__data.__lock) != 0)
+       {
+         int cnt = 0;
+         int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
+                            mutex->__data.__spins * 2 + 10);
+         do
+           {
+             if (cnt++ >= max_cnt)
+               {
+                 result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+                 break;
+               }
+
+#ifdef BUSY_WAIT_NOP
+             BUSY_WAIT_NOP;
+#endif
+           }
+         while (lll_mutex_trylock (mutex->__data.__lock) != 0);
+
+         mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
+       }
+      break;
+    }
+
+  if (result == 0)
+    {
+      /* Record the ownership.  */
+      mutex->__data.__owner = id;
+      ++mutex->__data.__nusers;
+    }
+
+ out:
+  return result;
+}
diff --git a/libpthread/nptl/pthread_mutex_trylock.c b/libpthread/nptl/pthread_mutex_trylock.c
new file mode 100644 (file)
index 0000000..7008af3
--- /dev/null
@@ -0,0 +1,77 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+__pthread_mutex_trylock (mutex)
+     pthread_mutex_t *mutex;
+{
+  pid_t id;
+
+  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+    {
+      /* Recursive mutex.  */
+    case PTHREAD_MUTEX_RECURSIVE_NP:
+      id = THREAD_GETMEM (THREAD_SELF, tid);
+      /* Check whether we already hold the mutex.  */
+      if (mutex->__data.__owner == id)
+       {
+         /* Just bump the counter.  */
+         if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+           /* Overflow of the counter.  */
+           return EAGAIN;
+
+         ++mutex->__data.__count;
+         return 0;
+       }
+
+      if (lll_mutex_trylock (mutex->__data.__lock) == 0)
+       {
+         /* Record the ownership.  */
+         mutex->__data.__owner = id;
+         mutex->__data.__count = 1;
+         ++mutex->__data.__nusers;
+         return 0;
+       }
+      break;
+
+    case PTHREAD_MUTEX_ERRORCHECK_NP:
+      /* Error checking mutex.  We do not check for deadlocks.  */
+    default:
+      /* Correct code cannot set any other type.  */
+    case PTHREAD_MUTEX_TIMED_NP:
+    case PTHREAD_MUTEX_ADAPTIVE_NP:
+      /* Normal mutex.  */
+      if (lll_mutex_trylock (mutex->__data.__lock) == 0)
+       {
+         /* Record the ownership.  */
+         mutex->__data.__owner = THREAD_GETMEM (THREAD_SELF, tid);
+         ++mutex->__data.__nusers;
+
+         return 0;
+       }
+    }
+
+  return EBUSY;
+}
+strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
diff --git a/libpthread/nptl/pthread_mutex_unlock.c b/libpthread/nptl/pthread_mutex_unlock.c
new file mode 100644 (file)
index 0000000..32bc2a4
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+internal_function attribute_hidden
+__pthread_mutex_unlock_usercnt (mutex, decr)
+     pthread_mutex_t *mutex;
+     int decr;
+{
+  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+    {
+    case PTHREAD_MUTEX_RECURSIVE_NP:
+      /* Recursive mutex.  */
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
+       return EPERM;
+
+      if (--mutex->__data.__count != 0)
+       /* We still hold the mutex.  */
+       return 0;
+      break;
+
+    case PTHREAD_MUTEX_ERRORCHECK_NP:
+      /* Error checking mutex.  */
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
+         || ! lll_mutex_islocked (mutex->__data.__lock))
+       return EPERM;
+      break;
+
+    default:
+      /* Correct code cannot set any other type.  */
+    case PTHREAD_MUTEX_TIMED_NP:
+    case PTHREAD_MUTEX_ADAPTIVE_NP:
+      /* Normal mutex.  Nothing special to do.  */
+      break;
+    }
+
+  /* Always reset the owner field.  */
+  mutex->__data.__owner = 0;
+  if (decr)
+    /* One less user.  */
+    --mutex->__data.__nusers;
+
+  /* Unlock.  */
+  lll_mutex_unlock (mutex->__data.__lock);
+
+  return 0;
+}
+
+
+int
+__pthread_mutex_unlock (mutex)
+     pthread_mutex_t *mutex;
+{
+  return __pthread_mutex_unlock_usercnt (mutex, 1);
+}
+strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
+strong_alias (__pthread_mutex_unlock, __pthread_mutex_unlock_internal)
diff --git a/libpthread/nptl/pthread_mutexattr_destroy.c b/libpthread/nptl/pthread_mutexattr_destroy.c
new file mode 100644 (file)
index 0000000..eab27d3
--- /dev/null
@@ -0,0 +1,29 @@
+/* Copyright (C) 2002 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.  */
+
+#include <pthreadP.h>
+
+
+int
+__pthread_mutexattr_destroy (attr)
+     pthread_mutexattr_t *attr;
+{
+  return 0;
+}
+strong_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy)
diff --git a/libpthread/nptl/pthread_mutexattr_getpshared.c b/libpthread/nptl/pthread_mutexattr_getpshared.c
new file mode 100644 (file)
index 0000000..4bd4ea1
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (C) 2002 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.  */
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_getpshared (attr, pshared)
+     const pthread_mutexattr_t *attr;
+     int *pshared;
+{
+  const struct pthread_mutexattr *iattr;
+
+  iattr = (const struct pthread_mutexattr *) attr;
+
+  /* We use bit 31 to signal whether the mutex is going to be
+     process-shared or not.  */
+  *pshared = ((iattr->mutexkind & 0x80000000) != 0
+             ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE);
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_mutexattr_gettype.c b/libpthread/nptl/pthread_mutexattr_gettype.c
new file mode 100644 (file)
index 0000000..5c32b2c
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (C) 2002 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.  */
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_gettype (attr, kind)
+     const pthread_mutexattr_t *attr;
+     int *kind;
+{
+  const struct pthread_mutexattr *iattr;
+
+  iattr = (const struct pthread_mutexattr *) attr;
+
+  /* We use bit 31 to signal whether the mutex is going to be
+     process-shared or not.  */
+  *kind = iattr->mutexkind & ~0x80000000;
+
+  return 0;
+}
+weak_alias (pthread_mutexattr_gettype, pthread_mutexattr_getkind_np)
diff --git a/libpthread/nptl/pthread_mutexattr_init.c b/libpthread/nptl/pthread_mutexattr_init.c
new file mode 100644 (file)
index 0000000..ee026c6
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (C) 2002 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.  */
+
+#include <string.h>
+#include <pthreadP.h>
+
+
+int
+__pthread_mutexattr_init (attr)
+     pthread_mutexattr_t *attr;
+{
+  if (sizeof (struct pthread_mutexattr) != sizeof (pthread_mutexattr_t))
+    memset (attr, '\0', sizeof (*attr));
+
+  /* We use bit 31 to signal whether the mutex is going to be
+     process-shared or not.  By default it is zero, i.e., the mutex is
+     not process-shared.  */
+  ((struct pthread_mutexattr *) attr)->mutexkind = PTHREAD_MUTEX_NORMAL;
+
+  return 0;
+}
+strong_alias (__pthread_mutexattr_init, pthread_mutexattr_init)
diff --git a/libpthread/nptl/pthread_mutexattr_setpshared.c b/libpthread/nptl/pthread_mutexattr_setpshared.c
new file mode 100644 (file)
index 0000000..5f2cf41
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_setpshared (attr, pshared)
+     pthread_mutexattr_t *attr;
+     int pshared;
+{
+  struct pthread_mutexattr *iattr;
+
+  if (pshared != PTHREAD_PROCESS_PRIVATE
+      && __builtin_expect (pshared != PTHREAD_PROCESS_SHARED, 0))
+    return EINVAL;
+
+  iattr = (struct pthread_mutexattr *) attr;
+
+  /* We use bit 31 to signal whether the mutex is going to be
+     process-shared or not.  */
+  if (pshared == PTHREAD_PROCESS_PRIVATE)
+    iattr->mutexkind &= ~0x80000000;
+  else
+    iattr->mutexkind |= 0x80000000;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_mutexattr_settype.c b/libpthread/nptl/pthread_mutexattr_settype.c
new file mode 100644 (file)
index 0000000..c77fe79
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int
+__pthread_mutexattr_settype (attr, kind)
+     pthread_mutexattr_t *attr;
+     int kind;
+{
+  struct pthread_mutexattr *iattr;
+
+  if (kind < PTHREAD_MUTEX_NORMAL || kind > PTHREAD_MUTEX_ADAPTIVE_NP)
+    return EINVAL;
+
+  iattr = (struct pthread_mutexattr *) attr;
+
+  /* We use bit 31 to signal whether the mutex is going to be
+     process-shared or not.  */
+  iattr->mutexkind = (iattr->mutexkind & 0x80000000) | kind;
+
+  return 0;
+}
+weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_setkind_np)
+strong_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype)
diff --git a/libpthread/nptl/pthread_rwlock_destroy.c b/libpthread/nptl/pthread_rwlock_destroy.c
new file mode 100644 (file)
index 0000000..28fd24b
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+__pthread_rwlock_destroy (rwlock)
+     pthread_rwlock_t *rwlock;
+{
+  /* Nothing to be done.  For now.  */
+  return 0;
+}
+strong_alias (__pthread_rwlock_destroy, pthread_rwlock_destroy)
diff --git a/libpthread/nptl/pthread_rwlock_init.c b/libpthread/nptl/pthread_rwlock_init.c
new file mode 100644 (file)
index 0000000..f664dd8
--- /dev/null
@@ -0,0 +1,51 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+static const struct pthread_rwlockattr default_attr =
+  {
+    .lockkind = PTHREAD_RWLOCK_DEFAULT_NP,
+    .pshared = PTHREAD_PROCESS_PRIVATE
+  };
+
+
+int
+__pthread_rwlock_init (rwlock, attr)
+     pthread_rwlock_t *rwlock;
+     const pthread_rwlockattr_t *attr;
+{
+  const struct pthread_rwlockattr *iattr;
+
+  iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr;
+
+  rwlock->__data.__lock = 0;
+  rwlock->__data.__flags
+    = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
+  rwlock->__data.__nr_readers = 0;
+  rwlock->__data.__writer = 0;
+  rwlock->__data.__readers_wakeup = 0;
+  rwlock->__data.__writer_wakeup = 0;
+  rwlock->__data.__nr_readers_queued = 0;
+  rwlock->__data.__nr_writers_queued = 0;
+
+  return 0;
+}
+strong_alias (__pthread_rwlock_init, pthread_rwlock_init)
diff --git a/libpthread/nptl/pthread_rwlock_tryrdlock.c b/libpthread/nptl/pthread_rwlock_tryrdlock.c
new file mode 100644 (file)
index 0000000..446af05
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+__pthread_rwlock_tryrdlock (rwlock)
+     pthread_rwlock_t *rwlock;
+{
+  int result = EBUSY;
+
+  lll_mutex_lock (rwlock->__data.__lock);
+
+  if (rwlock->__data.__writer == 0
+      && (rwlock->__data.__nr_writers_queued == 0
+         || rwlock->__data.__flags == 0))
+    {
+      if (__builtin_expect (++rwlock->__data.__nr_readers == 0, 0))
+       {
+         --rwlock->__data.__nr_readers;
+         result = EAGAIN;
+       }
+      else
+       result = 0;
+    }
+
+  lll_mutex_unlock (rwlock->__data.__lock);
+
+  return result;
+}
+strong_alias (__pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock)
diff --git a/libpthread/nptl/pthread_rwlock_trywrlock.c b/libpthread/nptl/pthread_rwlock_trywrlock.c
new file mode 100644 (file)
index 0000000..b754a19
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+__pthread_rwlock_trywrlock (rwlock)
+     pthread_rwlock_t *rwlock;
+{
+  int result = EBUSY;
+
+  lll_mutex_lock (rwlock->__data.__lock);
+
+  if (rwlock->__data.__writer == 0 && rwlock->__data.__nr_readers == 0)
+    {
+      rwlock->__data.__writer = THREAD_GETMEM (THREAD_SELF, tid);
+      result = 0;
+    }
+
+  lll_mutex_unlock (rwlock->__data.__lock);
+
+  return result;
+}
+strong_alias (__pthread_rwlock_trywrlock, pthread_rwlock_trywrlock)
diff --git a/libpthread/nptl/pthread_rwlockattr_destroy.c b/libpthread/nptl/pthread_rwlockattr_destroy.c
new file mode 100644 (file)
index 0000000..4f0c2c4
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_rwlockattr_destroy (attr)
+     pthread_rwlockattr_t *attr;
+{
+  /* Nothing to do.  For now.  */
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_rwlockattr_getkind_np.c b/libpthread/nptl/pthread_rwlockattr_getkind_np.c
new file mode 100644 (file)
index 0000000..aad9468
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_rwlockattr_getkind_np (attr, pref)
+     const pthread_rwlockattr_t *attr;
+     int *pref;
+{
+  *pref = ((const struct pthread_rwlockattr *) attr)->lockkind;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_rwlockattr_getpshared.c b/libpthread/nptl/pthread_rwlockattr_getpshared.c
new file mode 100644 (file)
index 0000000..3a77683
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_rwlockattr_getpshared (attr, pshared)
+     const pthread_rwlockattr_t *attr;
+     int *pshared;
+{
+  *pshared = ((const struct pthread_rwlockattr *) attr)->pshared;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_rwlockattr_init.c b/libpthread/nptl/pthread_rwlockattr_init.c
new file mode 100644 (file)
index 0000000..b299534
--- /dev/null
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+
+
+int
+pthread_rwlockattr_init (attr)
+     pthread_rwlockattr_t *attr;
+{
+  struct pthread_rwlockattr *iattr;
+
+  iattr = (struct pthread_rwlockattr *) attr;
+
+  iattr->lockkind = PTHREAD_RWLOCK_DEFAULT_NP;
+  iattr->pshared = PTHREAD_PROCESS_PRIVATE;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_rwlockattr_setkind_np.c b/libpthread/nptl/pthread_rwlockattr_setkind_np.c
new file mode 100644 (file)
index 0000000..0311f1b
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+pthread_rwlockattr_setkind_np (attr, pref)
+     pthread_rwlockattr_t *attr;
+     int pref;
+{
+  struct pthread_rwlockattr *iattr;
+
+  if (pref != PTHREAD_RWLOCK_PREFER_READER_NP
+      && pref != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
+      && __builtin_expect  (pref != PTHREAD_RWLOCK_PREFER_WRITER_NP, 0))
+    return EINVAL;
+
+  iattr = (struct pthread_rwlockattr *) attr;
+
+  iattr->lockkind = pref;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_rwlockattr_setpshared.c b/libpthread/nptl/pthread_rwlockattr_setpshared.c
new file mode 100644 (file)
index 0000000..9438d29
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+
+int
+pthread_rwlockattr_setpshared (attr, pshared)
+     pthread_rwlockattr_t *attr;
+     int pshared;
+{
+  struct pthread_rwlockattr *iattr;
+
+  if (pshared != PTHREAD_PROCESS_SHARED
+      && __builtin_expect (pshared != PTHREAD_PROCESS_PRIVATE, 0))
+    return EINVAL;
+
+  iattr = (struct pthread_rwlockattr *) attr;
+
+  iattr->pshared = pshared;
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_self.c b/libpthread/nptl/pthread_self.c
new file mode 100644 (file)
index 0000000..f0e3b3f
--- /dev/null
@@ -0,0 +1,29 @@
+/* Copyright (C) 2002 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.  */
+
+#include "pthreadP.h"
+#include <tls.h>
+
+
+pthread_t
+__pthread_self (void)
+{
+  return (pthread_t) THREAD_SELF;
+}
+strong_alias (__pthread_self, pthread_self)
diff --git a/libpthread/nptl/pthread_setcancelstate.c b/libpthread/nptl/pthread_setcancelstate.c
new file mode 100644 (file)
index 0000000..a452c2e
--- /dev/null
@@ -0,0 +1,73 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <atomic.h>
+
+
+int
+__pthread_setcancelstate (state, oldstate)
+     int state;
+     int *oldstate;
+{
+  volatile struct pthread *self;
+
+  if (state < PTHREAD_CANCEL_ENABLE || state > PTHREAD_CANCEL_DISABLE)
+    return EINVAL;
+
+  self = THREAD_SELF;
+
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+  while (1)
+    {
+      int newval = (state == PTHREAD_CANCEL_DISABLE
+                   ? oldval | CANCELSTATE_BITMASK
+                   : oldval & ~CANCELSTATE_BITMASK);
+
+      /* Store the old value.  */
+      if (oldstate != NULL)
+       *oldstate = ((oldval & CANCELSTATE_BITMASK)
+                    ? PTHREAD_CANCEL_DISABLE : PTHREAD_CANCEL_ENABLE);
+
+      /* Avoid doing unnecessary work.  The atomic operation can
+        potentially be expensive if the memory has to be locked and
+        remote cache lines have to be invalidated.  */
+      if (oldval == newval)
+       break;
+
+      /* Update the cancel handling word.  This has to be done
+        atomically since other bits could be modified as well.  */
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+                                             oldval);
+      if (__builtin_expect (curval == oldval, 1))
+       {
+         if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
+           __do_cancel ();
+
+         break;
+       }
+
+      /* Prepare for the next round.  */
+      oldval = curval;
+    }
+
+  return 0;
+}
+strong_alias (__pthread_setcancelstate, pthread_setcancelstate)
diff --git a/libpthread/nptl/pthread_setcanceltype.c b/libpthread/nptl/pthread_setcanceltype.c
new file mode 100644 (file)
index 0000000..bbe87ba
--- /dev/null
@@ -0,0 +1,76 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <atomic.h>
+
+
+int
+__pthread_setcanceltype (type, oldtype)
+     int type;
+     int *oldtype;
+{
+  volatile struct pthread *self;
+
+  if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
+    return EINVAL;
+
+  self = THREAD_SELF;
+
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+  while (1)
+    {
+      int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS
+                   ? oldval | CANCELTYPE_BITMASK
+                   : oldval & ~CANCELTYPE_BITMASK);
+
+      /* Store the old value.  */
+      if (oldtype != NULL)
+       *oldtype = ((oldval & CANCELTYPE_BITMASK)
+                   ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
+
+      /* Avoid doing unnecessary work.  The atomic operation can
+        potentially be expensive if the memory has to be locked and
+        remote cache lines have to be invalidated.  */
+      if (oldval == newval)
+       break;
+
+      /* Update the cancel handling word.  This has to be done
+        atomically since other bits could be modified as well.  */
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+                                             oldval);
+      if (__builtin_expect (curval == oldval, 1))
+       {
+         if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
+           {
+             THREAD_SETMEM (self, result, PTHREAD_CANCELED);
+             __do_cancel ();
+           }
+
+         break;
+       }
+
+      /* Prepare for the next round.  */
+      oldval = curval;
+    }
+
+  return 0;
+}
+strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
diff --git a/libpthread/nptl/pthread_setconcurrency.c b/libpthread/nptl/pthread_setconcurrency.c
new file mode 100644 (file)
index 0000000..8cf1507
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+
+/* Global definition.  Needed in pthread_getconcurrency as well.  */
+int __concurrency_level;
+
+
+int
+pthread_setconcurrency (level)
+     int level;
+{
+  if (level < 0)
+    return EINVAL;
+
+  __concurrency_level = level;
+
+  /* XXX For ports which actually need to handle the concurrency level
+     some more code is probably needed here.  */
+
+  return 0;
+}
diff --git a/libpthread/nptl/pthread_setegid.c b/libpthread/nptl/pthread_setegid.c
new file mode 100644 (file)
index 0000000..9252dfa
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define setegid pthread_setegid_np
+#include <setegid.c>
diff --git a/libpthread/nptl/pthread_seteuid.c b/libpthread/nptl/pthread_seteuid.c
new file mode 100644 (file)
index 0000000..47bb698
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define seteuid pthread_seteuid_np
+#include <seteuid.c>
diff --git a/libpthread/nptl/pthread_setgid.c b/libpthread/nptl/pthread_setgid.c
new file mode 100644 (file)
index 0000000..b06bffb
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define __setgid pthread_setgid_np
+#include <setgid.c>
diff --git a/libpthread/nptl/pthread_setregid.c b/libpthread/nptl/pthread_setregid.c
new file mode 100644 (file)
index 0000000..7461d2b
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define __setregid pthread_setregid_np
+#include <setregid.c>
diff --git a/libpthread/nptl/pthread_setresgid.c b/libpthread/nptl/pthread_setresgid.c
new file mode 100644 (file)
index 0000000..369fae2
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define __setresgid pthread_setresgid_np
+#include <setresgid.c>
diff --git a/libpthread/nptl/pthread_setresuid.c b/libpthread/nptl/pthread_setresuid.c
new file mode 100644 (file)
index 0000000..ac57c0f
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define __setresuid pthread_setresuid_np
+#include <setresuid.c>
diff --git a/libpthread/nptl/pthread_setreuid.c b/libpthread/nptl/pthread_setreuid.c
new file mode 100644 (file)
index 0000000..aa804ab
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define __setreuid pthread_setreuid_np
+#include <setreuid.c>
diff --git a/libpthread/nptl/pthread_setschedparam.c b/libpthread/nptl/pthread_setschedparam.c
new file mode 100644 (file)
index 0000000..5889cc9
--- /dev/null
@@ -0,0 +1,67 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <errno.h>
+#include <sched.h>
+#include <string.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+__pthread_setschedparam (threadid, policy, param)
+     pthread_t threadid;
+     int policy;
+     const struct sched_param *param;
+{
+  struct pthread *pd = (struct pthread *) threadid;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  int result = 0;
+
+  /* We have to handle cancellation in the following code since we are
+     locking another threads desriptor.  */
+  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
+
+  lll_lock (pd->lock);
+
+  /* Try to set the scheduler information.  */
+  if (__builtin_expect (__sched_setscheduler (pd->tid, policy,
+                                             param) == -1, 0))
+    result = errno;
+  else
+    {
+      /* We succeeded changing the kernel information.  Reflect this
+        change in the thread descriptor.  */
+      pd->schedpolicy = policy;
+      memcpy (&pd->schedparam, param, sizeof (struct sched_param));
+      pd->flags |= ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET;
+    }
+
+  lll_unlock (pd->lock);
+
+  pthread_cleanup_pop (0);
+
+  return result;
+}
+strong_alias (__pthread_setschedparam, pthread_setschedparam)
diff --git a/libpthread/nptl/pthread_setschedprio.c b/libpthread/nptl/pthread_setschedprio.c
new file mode 100644 (file)
index 0000000..063f523
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002, 2003, 2004 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.  */
+
+#include <errno.h>
+#include <sched.h>
+#include <string.h>
+#include <sched.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+int
+pthread_setschedprio (threadid, prio)
+     pthread_t threadid;
+     int prio;
+{
+  struct pthread *pd = (struct pthread *) threadid;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  int result = 0;
+  struct sched_param param;
+  param.sched_priority = prio;
+
+  /* We have to handle cancellation in the following code since we are
+     locking another threads desriptor.  */
+  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
+
+  lll_lock (pd->lock);
+
+  /* Try to set the scheduler information.  */
+  if (__builtin_expect (sched_setparam (pd->tid, &param) == -1, 0))
+    result = errno;
+  else
+    {
+      /* We succeeded changing the kernel information.  Reflect this
+        change in the thread descriptor.  */
+      memcpy (&pd->schedparam, &param, sizeof (struct sched_param));
+      pd->flags |= ATTR_FLAG_SCHED_SET;
+    }
+
+  lll_unlock (pd->lock);
+
+  pthread_cleanup_pop (0);
+
+  return result;
+}
diff --git a/libpthread/nptl/pthread_setspecific.c b/libpthread/nptl/pthread_setspecific.c
new file mode 100644 (file)
index 0000000..b6e66b5
--- /dev/null
@@ -0,0 +1,96 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+int
+__pthread_setspecific (key, value)
+     pthread_key_t key;
+     const void *value;
+{
+  struct pthread *self;
+  unsigned int idx1st;
+  unsigned int idx2nd;
+  struct pthread_key_data *level2;
+  unsigned int seq;
+
+  self = THREAD_SELF;
+
+  /* Special case access to the first 2nd-level block.  This is the
+     usual case.  */
+  if (__builtin_expect (key < PTHREAD_KEY_2NDLEVEL_SIZE, 1))
+    {
+      /* Verify the key is sane.  */
+      if (KEY_UNUSED ((seq = __pthread_keys[key].seq)))
+       /* Not valid.  */
+       return EINVAL;
+
+      level2 = &self->specific_1stblock[key];
+
+      /* Remember that we stored at least one set of data.  */
+      if (value != NULL)
+       THREAD_SETMEM (self, specific_used, true);
+    }
+  else
+    {
+      if (KEY_UNUSED ((seq = __pthread_keys[key].seq))
+         || key >= PTHREAD_KEYS_MAX)
+       /* Not valid.  */
+       return EINVAL;
+
+      idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
+      idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
+
+      /* This is the second level array.  Allocate it if necessary.  */
+      level2 = THREAD_GETMEM_NC (self, specific, idx1st);
+      if (level2 == NULL)
+       {
+         if (value == NULL)
+           /* We don't have to do anything.  The value would in any case
+              be NULL.  We can save the memory allocation.  */
+           return 0;
+
+         level2
+           = (struct pthread_key_data *) calloc (PTHREAD_KEY_2NDLEVEL_SIZE,
+                                                 sizeof (*level2));
+         if (level2 == NULL)
+           return ENOMEM;
+
+         THREAD_SETMEM_NC (self, specific, idx1st, level2);
+       }
+
+      /* Pointer to the right array element.  */
+      level2 = &level2[idx2nd];
+
+      /* Remember that we stored at least one set of data.  */
+      THREAD_SETMEM (self, specific_used, true);
+    }
+
+  /* Store the data and the sequence number so that we can recognize
+     stale data.  */
+  level2->seq = seq;
+  level2->data = (void *) value;
+
+  return 0;
+}
+strong_alias (__pthread_setspecific, pthread_setspecific)
+strong_alias (__pthread_setspecific, __pthread_setspecific_internal)
diff --git a/libpthread/nptl/pthread_setuid.c b/libpthread/nptl/pthread_setuid.c
new file mode 100644 (file)
index 0000000..ff949c8
--- /dev/null
@@ -0,0 +1,3 @@
+#define SINGLE_THREAD
+#define __setuid pthread_setuid_np
+#include <setuid.c>
diff --git a/libpthread/nptl/pthread_testcancel.c b/libpthread/nptl/pthread_testcancel.c
new file mode 100644 (file)
index 0000000..e9b17b4
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (C) 2002 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.  */
+
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+void
+pthread_testcancel (void)
+{
+  CANCELLATION_P (THREAD_SELF);
+}
diff --git a/libpthread/nptl/pthread_timedjoin.c b/libpthread/nptl/pthread_timedjoin.c
new file mode 100644 (file)
index 0000000..1cc0721
--- /dev/null
@@ -0,0 +1,107 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "atomic.h"
+#include "pthreadP.h"
+
+
+static void
+cleanup (void *arg)
+{
+  *(void **) arg = NULL;
+}
+
+
+int
+pthread_timedjoin_np (threadid, thread_return, abstime)
+     pthread_t threadid;
+     void **thread_return;
+     const struct timespec *abstime;
+{
+  struct pthread *self;
+  struct pthread *pd = (struct pthread *) threadid;
+  int result;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_NOT_TERMINATED_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  /* Is the thread joinable?.  */
+  if (IS_DETACHED (pd))
+    /* We cannot wait for the thread.  */
+    return EINVAL;
+
+  self = THREAD_SELF;
+  if (pd == self || self->joinid == pd)
+    /* This is a deadlock situation.  The threads are waiting for each
+       other to finish.  Note that this is a "may" error.  To be 100%
+       sure we catch this error we would have to lock the data
+       structures but it is not necessary.  In the unlikely case that
+       two threads are really caught in this situation they will
+       deadlock.  It is the programmer's problem to figure this
+       out.  */
+    return EDEADLK;
+
+  /* Wait for the thread to finish.  If it is already locked something
+     is wrong.  There can only be one waiter.  */
+  if (__builtin_expect (atomic_compare_and_exchange_bool_acq (&pd->joinid,
+                                                             self, NULL), 0))
+    /* There is already somebody waiting for the thread.  */
+    return EINVAL;
+
+
+  /* During the wait we change to asynchronous cancellation.  If we
+     are cancelled the thread we are waiting for must be marked as
+     un-wait-ed for again.  */
+  pthread_cleanup_push (cleanup, &pd->joinid);
+
+  /* Switch to asynchronous cancellation.  */
+  int oldtype = CANCEL_ASYNC ();
+
+
+  /* Wait for the child.  */
+  result = lll_timedwait_tid (pd->tid, abstime);
+
+
+  /* Restore cancellation mode.  */
+  CANCEL_RESET (oldtype);
+
+  /* Remove the handler.  */
+  pthread_cleanup_pop (0);
+
+
+  /* We might have timed out.  */
+  if (result == 0)
+    {
+      /* Store the return value if the caller is interested.  */
+      if (thread_return != NULL)
+       *thread_return = pd->result;
+
+
+      /* Free the TCB.  */
+      __free_tcb (pd);
+    }
+  else
+    pd->joinid = NULL;
+
+  return result;
+}
diff --git a/libpthread/nptl/pthread_tryjoin.c b/libpthread/nptl/pthread_tryjoin.c
new file mode 100644 (file)
index 0000000..904cb52
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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.  */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "atomic.h"
+#include "pthreadP.h"
+
+
+int
+pthread_tryjoin_np (threadid, thread_return)
+     pthread_t threadid;
+     void **thread_return;
+{
+  struct pthread *self;
+  struct pthread *pd = (struct pthread *) threadid;
+
+  /* Make sure the descriptor is valid.  */
+  if (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  /* Is the thread joinable?.  */
+  if (IS_DETACHED (pd))
+    /* We cannot wait for the thread.  */
+    return EINVAL;
+
+  self = THREAD_SELF;
+  if (pd == self || self->joinid == pd)
+    /* This is a deadlock situation.  The threads are waiting for each
+       other to finish.  Note that this is a "may" error.  To be 100%
+       sure we catch this error we would have to lock the data
+       structures but it is not necessary.  In the unlikely case that
+       two threads are really caught in this situation they will
+       deadlock.  It is the programmer's problem to figure this
+       out.  */
+    return EDEADLK;
+
+  /* Return right away if the thread hasn't terminated yet.  */
+  if (pd->tid != 0)
+    return EBUSY;
+
+  /* Wait for the thread to finish.  If it is already locked something
+     is wrong.  There can only be one waiter.  */
+  if (atomic_compare_and_exchange_bool_acq (&pd->joinid, self, NULL))
+    /* There is already somebody waiting for the thread.  */
+    return EINVAL;
+
+  /* Store the return value if the caller is interested.  */
+  if (thread_return != NULL)
+    *thread_return = pd->result;
+
+
+  /* Free the TCB.  */
+  __free_tcb (pd);
+
+  return 0;
+}
diff --git a/libpthread/nptl/res.c b/libpthread/nptl/res.c
new file mode 100644 (file)
index 0000000..ba4f81d
--- /dev/null
@@ -0,0 +1,27 @@
+/* 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.  */
+
+#include <features.h>
+#include <resolv.h>
+#include <tls.h>
+
+struct __res_state *
+__res_state (void)
+{
+  return __resp;
+}
diff --git a/libpthread/nptl/sem_close.c b/libpthread/nptl/sem_close.c
new file mode 100644 (file)
index 0000000..279522d
--- /dev/null
@@ -0,0 +1,81 @@
+/* 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.  */
+
+#include <errno.h>
+#include <search.h>
+#include <sys/mman.h>
+#include "semaphoreP.h"
+
+
+/* Global variables to parametrize the walk function.  This works
+   since we always have to use locks.  And we have to use the twalk
+   function since the entries are not sorted wrt the mapping
+   address.  */
+static sem_t *the_sem;
+static struct inuse_sem *rec;
+
+static void
+walker (const void *inodep, const VISIT which, const int depth)
+{
+  struct inuse_sem *nodep = *(struct inuse_sem **) inodep;
+
+  if (nodep->sem == the_sem)
+    rec = nodep;
+}
+
+
+int
+sem_close (sem)
+     sem_t *sem;
+{
+  int result = 0;
+
+  /* Get the lock.  */
+  lll_lock (__sem_mappings_lock);
+
+  /* Locate the entry for the mapping the caller provided.  */
+  rec = NULL;
+  the_sem = sem;
+  twalk (__sem_mappings, walker);
+  if  (rec != NULL)
+    {
+      /* Check the reference counter.  If it is going to be zero, free
+        all the resources.  */
+      if (--rec->refcnt == 0)
+       {
+         /* Remove the record from the tree.  */
+         (void) tdelete (rec, &__sem_mappings, __sem_search);
+
+         result = munmap (rec->sem, sizeof (sem_t));
+
+         free (rec);
+       }
+    }
+  else
+    {
+      /* This is no valid semaphore.  */
+      result = -1;
+      __set_errno (EINVAL);
+    }
+
+  /* Release the lock.  */
+  lll_unlock (__sem_mappings_lock);
+
+  return result;
+}
diff --git a/libpthread/nptl/sem_destroy.c b/libpthread/nptl/sem_destroy.c
new file mode 100644 (file)
index 0000000..1c823dc
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (C) 2002 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.  */
+
+#include <semaphore.h>
+#include <shlib-compat.h>
+#include "semaphoreP.h"
+
+
+int
+__new_sem_destroy (sem)
+     sem_t *sem;
+{
+  /* XXX Check for valid parameter.  */
+
+  /* Nothing to do.  */
+  return 0;
+}
+versioned_symbol (libpthread, __new_sem_destroy, sem_destroy, GLIBC_2_1);
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_destroy, __old_sem_destroy)
+compat_symbol (libpthread, __old_sem_destroy, sem_destroy, GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/sem_getvalue.c b/libpthread/nptl/sem_getvalue.c
new file mode 100644 (file)
index 0000000..6bc7ea8
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright (C) 2002 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.  */
+
+#include <semaphore.h>
+#include <shlib-compat.h>
+#include "semaphoreP.h"
+
+
+int
+__new_sem_getvalue (sem, sval)
+     sem_t *sem;
+     int *sval;
+{
+  struct sem *isem = (struct sem *) sem;
+
+  /* XXX Check for valid SEM parameter.  */
+
+  *sval = isem->count;
+
+  return 0;
+}
+versioned_symbol (libpthread, __new_sem_getvalue, sem_getvalue, GLIBC_2_1);
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_getvalue, __old_sem_getvalue)
+compat_symbol (libpthread, __old_sem_getvalue, sem_getvalue, GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/sem_init.c b/libpthread/nptl/sem_init.c
new file mode 100644 (file)
index 0000000..8709911
--- /dev/null
@@ -0,0 +1,55 @@
+/* Copyright (C) 2002 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.  */
+
+#include <errno.h>
+#include <semaphore.h>
+#include <lowlevellock.h>
+#include <shlib-compat.h>
+#include "semaphoreP.h"
+
+
+int
+__new_sem_init (sem, pshared, value)
+     sem_t *sem;
+     int pshared;
+     unsigned int value;
+{
+  /* Parameter sanity check.  */
+  if (__builtin_expect (value > SEM_VALUE_MAX, 0))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* Map to the internal type.  */
+  struct sem *isem = (struct sem *) sem;
+
+  /* Use the value the user provided.  */
+  isem->count = value;
+
+  /* We can completely ignore the PSHARED parameter since inter-process
+     use needs no special preparation.  */
+
+  return 0;
+}
+versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1);
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_init, __old_sem_init)
+compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
+#endif
diff --git a/libpthread/nptl/sem_open.c b/libpthread/nptl/sem_open.c
new file mode 100644 (file)
index 0000000..a4b2f5b
--- /dev/null
@@ -0,0 +1,404 @@
+/* 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.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <mntent.h>
+#include <paths.h>
+#include <pthread.h>
+#include <search.h>
+#include <semaphore.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <linux_fsinfo.h>
+#include "semaphoreP.h"
+
+
+
+/* Information about the mount point.  */
+struct mountpoint_info mountpoint attribute_hidden;
+
+/* This is the default mount point.  */
+static const char defaultmount[] = "/dev/shm";
+/* This is the default directory.  */
+static const char defaultdir[] = "/dev/shm/sem.";
+
+/* Protect the `mountpoint' variable above.  */
+pthread_once_t __namedsem_once attribute_hidden = PTHREAD_ONCE_INIT;
+
+
+/* Determine where the shmfs is mounted (if at all).  */
+void
+attribute_hidden
+__where_is_shmfs (void)
+{
+  char buf[512];
+  struct statfs f;
+  struct mntent resmem;
+  struct mntent *mp;
+  FILE *fp;
+
+  /* The canonical place is /dev/shm.  This is at least what the
+     documentation tells everybody to do.  */
+  if (__statfs (defaultmount, &f) == 0 && f.f_type == SHMFS_SUPER_MAGIC)
+    {
+      /* It is in the normal place.  */
+      mountpoint.dir = (char *) defaultdir;
+      mountpoint.dirlen = sizeof (defaultdir) - 1;
+
+      return;
+    }
+
+  /* OK, do it the hard way.  Look through the /proc/mounts file and if
+     this does not exist through /etc/fstab to find the mount point.  */
+  fp = __setmntent ("/proc/mounts", "r");
+  if (__builtin_expect (fp == NULL, 0))
+    {
+      fp = __setmntent (_PATH_MNTTAB, "r");
+      if (__builtin_expect (fp == NULL, 0))
+       /* There is nothing we can do.  Blind guesses are not helpful.  */
+       return;
+    }
+
+  /* Now read the entries.  */
+  while ((mp = __getmntent_r (fp, &resmem, buf, sizeof buf)) != NULL)
+    /* The original name is "shm" but this got changed in early Linux
+       2.4.x to "tmpfs".  */
+    if (strcmp (mp->mnt_type, "tmpfs") == 0
+       || strcmp (mp->mnt_type, "shm") == 0)
+      {
+       /* Found it.  There might be more than one place where the
+           filesystem is mounted but one is enough for us.  */
+       size_t namelen;
+
+       /* First make sure this really is the correct entry.  At least
+          some versions of the kernel give wrong information because
+          of the implicit mount of the shmfs for SysV IPC.  */
+       if (__statfs (mp->mnt_dir, &f) != 0 || f.f_type != SHMFS_SUPER_MAGIC)
+         continue;
+
+       namelen = strlen (mp->mnt_dir);
+
+       if (namelen == 0)
+         /* Hum, maybe some crippled entry.  Keep on searching.  */
+         continue;
+
+       mountpoint.dir = (char *) malloc (namelen + 4 + 2);
+       if (mountpoint.dir != NULL)
+         {
+           char *cp = __mempcpy (mountpoint.dir, mp->mnt_dir, namelen);
+           if (cp[-1] != '/')
+             *cp++ = '/';
+           cp = stpcpy (cp, "sem.");
+           mountpoint.dirlen = cp - mountpoint.dir;
+         }
+
+       break;
+      }
+
+  /* Close the stream.  */
+  __endmntent (fp);
+}
+
+
+/* Comparison function for search of existing mapping.  */
+int
+attribute_hidden
+__sem_search (const void *a, const void *b)
+{
+  const struct inuse_sem *as = (const struct inuse_sem *) a;
+  const struct inuse_sem *bs = (const struct inuse_sem *) b;
+
+  if (as->ino != bs->ino)
+    /* Cannot return the difference the type is larger than int.  */
+    return as->ino < bs->ino ? -1 : (as->ino == bs->ino ? 0 : 1);
+
+  if (as->dev != bs->dev)
+    /* Cannot return the difference the type is larger than int.  */
+    return as->dev < bs->dev ? -1 : (as->dev == bs->dev ? 0 : 1);
+
+  return strcmp (as->name, bs->name);
+}
+
+
+/* The search tree for existing mappings.  */
+void *__sem_mappings attribute_hidden;
+
+/* Lock to protect the search tree.  */
+lll_lock_t __sem_mappings_lock = LLL_LOCK_INITIALIZER;
+
+
+/* Search for existing mapping and if possible add the one provided.  */
+static sem_t *
+check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing)
+{
+  sem_t *result = SEM_FAILED;
+
+  /* Get the information about the file.  */
+  struct stat64 st;
+  if (__fxstat64 (_STAT_VER, fd, &st) == 0)
+    {
+      /* Get the lock.  */
+      lll_lock (__sem_mappings_lock);
+
+      /* Search for an existing mapping given the information we have.  */
+      struct inuse_sem *fake;
+      fake = (struct inuse_sem *) alloca (sizeof (*fake) + namelen);
+      memcpy (fake->name, name, namelen);
+      fake->dev = st.st_dev;
+      fake->ino = st.st_ino;
+
+      struct inuse_sem **foundp = tfind (fake, &__sem_mappings, __sem_search);
+      if (foundp != NULL)
+       {
+         /* There is already a mapping.  Use it.  */
+         result = (*foundp)->sem;
+         ++(*foundp)->refcnt;
+       }
+      else
+       {
+         /* We haven't found a mapping.  Install ione.  */
+         struct inuse_sem *newp;
+
+         newp = (struct inuse_sem *) malloc (sizeof (*newp) + namelen);
+         if (newp != NULL)
+           {
+             /* If the caller hasn't provided any map it now.  */
+             if (existing == SEM_FAILED)
+               existing = (sem_t *) mmap (NULL, sizeof (sem_t),
+                                          PROT_READ | PROT_WRITE, MAP_SHARED,
+                                          fd, 0);
+
+             newp->dev = st.st_dev;
+             newp->ino = st.st_ino;
+             newp->refcnt = 1;
+             newp->sem = existing;
+             memcpy (newp->name, name, namelen);
+
+             /* Insert the new value.  */
+             if (existing != MAP_FAILED
+                 && tsearch (newp, &__sem_mappings, __sem_search) != NULL)
+               /* Successful.  */
+               result = existing;
+             else
+               /* Something went wrong while inserting the new
+                  value.  We fail completely.  */
+               free (newp);
+           }
+       }
+
+      /* Release the lock.  */
+      lll_unlock (__sem_mappings_lock);
+    }
+
+  if (result != existing && existing != SEM_FAILED && existing != MAP_FAILED)
+    {
+      /* Do not disturb errno.  */
+      INTERNAL_SYSCALL_DECL (err);
+      INTERNAL_SYSCALL (munmap, err, 2, existing, sizeof (sem_t));
+    }
+
+  return result;
+}
+
+
+sem_t *
+sem_open (const char *name, int oflag, ...)
+{
+  char *finalname;
+  sem_t *result = SEM_FAILED;
+  int fd;
+
+  /* Determine where the shmfs is mounted.  */
+  INTUSE(__pthread_once) (&__namedsem_once, __where_is_shmfs);
+
+  /* If we don't know the mount points there is nothing we can do.  Ever.  */
+  if (mountpoint.dir == NULL)
+    {
+      __set_errno (ENOSYS);
+      return SEM_FAILED;
+    }
+
+  /* Construct the filename.  */
+  while (name[0] == '/')
+    ++name;
+
+  if (name[0] == '\0')
+    {
+      /* The name "/" is not supported.  */
+      __set_errno (EINVAL);
+      return SEM_FAILED;
+    }
+  size_t namelen = strlen (name) + 1;
+
+  /* Create the name of the final file.  */
+  finalname = (char *) alloca (mountpoint.dirlen + namelen);
+  __mempcpy (__mempcpy (finalname, mountpoint.dir, mountpoint.dirlen),
+            name, namelen);
+
+  /* If the semaphore object has to exist simply open it.  */
+  if ((oflag & O_CREAT) == 0 || (oflag & O_EXCL) == 0)
+    {
+    try_again:
+      fd = __libc_open (finalname,
+                       (oflag & ~(O_CREAT|O_ACCMODE)) | O_NOFOLLOW | O_RDWR);
+
+      if (fd == -1)
+       {
+         /* If we are supposed to create the file try this next.  */
+         if ((oflag & O_CREAT) != 0 && errno == ENOENT)
+           goto try_create;
+
+         /* Return.  errno is already set.  */
+       }
+      else
+       /* Check whether we already have this semaphore mapped and
+          create one if necessary.  */
+       result = check_add_mapping (name, namelen, fd, SEM_FAILED);
+    }
+  else
+    {
+      /* We have to open a temporary file first since it must have the
+        correct form before we can start using it.  */
+      char *tmpfname;
+      mode_t mode;
+      unsigned int value;
+      va_list ap;
+
+    try_create:
+      va_start (ap, oflag);
+
+      mode = va_arg (ap, mode_t);
+      value = va_arg (ap, unsigned int);
+
+      va_end (ap);
+
+      if (value > SEM_VALUE_MAX)
+       {
+         __set_errno (EINVAL);
+         return SEM_FAILED;
+       }
+
+      /* Create the initial file content.  */
+      sem_t initsem;
+
+      struct sem *iinitsem = (struct sem *) &initsem;
+      iinitsem->count = value;
+
+      /* Initialize the remaining bytes as well.  */
+      memset ((char *) &initsem + sizeof (struct sem), '\0',
+             sizeof (sem_t) - sizeof (struct sem));
+
+      tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
+      char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
+
+      int retries = 0;
+#define NRETRIES 50
+      while (1)
+       {
+         /* Add the suffix for mktemp.  */
+         strcpy (xxxxxx, "XXXXXX");
+
+         /* We really want to use mktemp here.  We cannot use mkstemp
+            since the file must be opened with a specific mode.  The
+            mode cannot later be set since then we cannot apply the
+            file create mask.  */
+         if (mktemp (tmpfname) == NULL)
+           return SEM_FAILED;
+
+         /* Open the file.  Make sure we do not overwrite anything.  */
+         fd = __libc_open (tmpfname, O_RDWR | O_CREAT | O_EXCL, mode);
+         if (fd == -1)
+           {
+             if (errno == EEXIST)
+               {
+                 if (++retries < NRETRIES)
+                   continue;
+
+                 __set_errno (EAGAIN);
+               }
+
+             return SEM_FAILED;
+           }
+
+         /* We got a file.  */
+         break;
+       }
+
+      if (TEMP_FAILURE_RETRY (__libc_write (fd, &initsem, sizeof (sem_t)))
+         == sizeof (sem_t)
+         /* Map the sem_t structure from the file.  */
+         && (result = (sem_t *) mmap (NULL, sizeof (sem_t),
+                                      PROT_READ | PROT_WRITE, MAP_SHARED,
+                                      fd, 0)) != MAP_FAILED)
+       {
+         /* Create the file.  Don't overwrite an existing file.  */
+         if (link (tmpfname, finalname) != 0)
+           {
+             /* Undo the mapping.  */
+             (void) munmap (result, sizeof (sem_t));
+
+             /* Reinitialize 'result'.  */
+             result = SEM_FAILED;
+
+             /* This failed.  If O_EXCL is not set and the problem was
+                that the file exists, try again.  */
+             if ((oflag & O_EXCL) == 0 && errno == EEXIST)
+               {
+                 /* Remove the file.  */
+                 (void) unlink (tmpfname);
+
+                 /* Close the file.  */
+                 (void) __libc_close (fd);
+
+                 goto try_again;
+               }
+           }
+         else
+           /* Insert the mapping into the search tree.  This also
+              determines whether another thread sneaked by and already
+              added such a mapping despite the fact that we created it.  */
+           result = check_add_mapping (name, namelen, fd, result);
+       }
+
+      /* Now remove the temporary name.  This should never fail.  If
+        it fails we leak a file name.  Better fix the kernel.  */
+      (void) unlink (tmpfname);
+    }
+
+  /* Map the mmap error to the error we need.  */
+  if (MAP_FAILED != (void *) SEM_FAILED && result == MAP_FAILED)
+    result = SEM_FAILED;
+
+  /* We don't need the file descriptor anymore.  */
+  if (fd != -1)
+    {
+      /* Do not disturb errno.  */
+      INTERNAL_SYSCALL_DECL (err);
+      INTERNAL_SYSCALL (close, err, 1, fd);
+    }
+
+  return result;
+}
diff --git a/libpthread/nptl/sem_unlink.c b/libpthread/nptl/sem_unlink.c
new file mode 100644 (file)
index 0000000..1707477
--- /dev/null
@@ -0,0 +1,67 @@
+/* Copyright (C) 2002, 2004 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.  */
+
+#include <errno.h>
+#include <semaphore.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "semaphoreP.h"
+
+
+int
+sem_unlink (name)
+     const char *name;
+{
+  char *fname;
+  size_t namelen;
+
+  /* Determine where the shmfs is mounted.  */
+  INTUSE(__pthread_once) (&__namedsem_once, __where_is_shmfs);
+
+  /* If we don't know the mount points there is nothing we can do.  Ever.  */
+  if (mountpoint.dir == NULL)
+    {
+      __set_errno (ENOSYS);
+      return -1;
+    }
+
+  /* Construct the filename.  */
+  while (name[0] == '/')
+    ++name;
+
+  if (name[0] == '\0')
+    {
+      /* The name "/" is not supported.  */
+      __set_errno (ENOENT);
+      return -1;
+    }
+  namelen = strlen (name);
+
+  /* Create the name of the file.  */
+  fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
+  __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
+            name, namelen + 1);
+
+  /* Now try removing it.  */
+  int ret = unlink (fname);
+  if (ret < 0 && errno == EPERM)
+    __set_errno (EACCES);
+  return ret;
+}
diff --git a/libpthread/nptl/semaphore.h b/libpthread/nptl/semaphore.h
new file mode 100644 (file)
index 0000000..4f13725
--- /dev/null
@@ -0,0 +1,79 @@
+/* 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.  */
+
+#ifndef _SEMAPHORE_H
+#define _SEMAPHORE_H   1
+
+#include <features.h>
+#include <sys/types.h>
+#ifdef __USE_XOPEN2K
+# define __need_timespec
+# include <time.h>
+#endif
+
+/* Get the definition for sem_t.  */
+#include <bits/semaphore.h>
+
+
+__BEGIN_DECLS
+
+/* Initialize semaphore object SEM to VALUE.  If PSHARED then share it
+   with other processes.  */
+extern int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
+     __THROW;
+/* Free resources associated with semaphore object SEM.  */
+extern int sem_destroy (sem_t *__sem) __THROW;
+
+/* Open a named semaphore NAME with open flags OFLAG.  */
+extern sem_t *sem_open (__const char *__name, int __oflag, ...) __THROW;
+
+/* Close descriptor for named semaphore SEM.  */
+extern int sem_close (sem_t *__sem) __THROW;
+
+/* Remove named semaphore NAME.  */
+extern int sem_unlink (__const char *__name) __THROW;
+
+/* Wait for SEM being posted.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int sem_wait (sem_t *__sem);
+
+#ifdef __USE_XOPEN2K
+/* Similar to `sem_wait' but wait only until ABSTIME.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int sem_timedwait (sem_t *__restrict __sem,
+                         __const struct timespec *__restrict __abstime);
+#endif
+
+/* Test whether SEM is posted.  */
+extern int sem_trywait (sem_t *__sem) __THROW;
+
+/* Post SEM.  */
+extern int sem_post (sem_t *__sem) __THROW;
+
+/* Get current value of SEM and store it in *SVAL.  */
+extern int sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval)
+     __THROW;
+
+
+__END_DECLS
+
+#endif /* semaphore.h */
diff --git a/libpthread/nptl/semaphoreP.h b/libpthread/nptl/semaphoreP.h
new file mode 100644 (file)
index 0000000..d14ea92
--- /dev/null
@@ -0,0 +1,67 @@
+/* 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.  */
+
+#include <semaphore.h>
+#include "pthreadP.h"
+
+
+/* Mount point of the shared memory filesystem.  */
+struct mountpoint_info
+{
+  char *dir;
+  size_t dirlen;
+};
+
+/* Keeping track of currently used mappings.  */
+struct inuse_sem
+{
+  dev_t dev;
+  ino_t ino;
+  int refcnt;
+  sem_t *sem;
+  char name[0];
+};
+
+
+/* Variables used in multiple interfaces.  */
+extern struct mountpoint_info mountpoint attribute_hidden;
+
+extern pthread_once_t __namedsem_once attribute_hidden;
+
+/* The search tree for existing mappings.  */
+extern void *__sem_mappings attribute_hidden;
+
+/* Lock to protect the search tree.  */
+extern lll_lock_t __sem_mappings_lock;
+
+
+/* Initializer for mountpoint.  */
+extern void __where_is_shmfs (void) attribute_hidden;
+
+/* Comparison function for search in tree with existing mappings.  */
+extern int __sem_search (const void *a, const void *b) attribute_hidden;
+
+
+/* Prototypes of functions with multiple interfaces.  */
+extern int __new_sem_init (sem_t *sem, int pshared, unsigned int value);
+extern int __new_sem_destroy (sem_t *sem);
+extern int __new_sem_post (sem_t *sem);
+extern int __new_sem_wait (sem_t *sem);
+extern int __new_sem_trywait (sem_t *sem);
+extern int __new_sem_getvalue (sem_t *sem, int *sval);
diff --git a/libpthread/nptl/sockperf.c b/libpthread/nptl/sockperf.c
new file mode 100644 (file)
index 0000000..d29a6ee
--- /dev/null
@@ -0,0 +1,594 @@
+#define _GNU_SOURCE
+#include <argp.h>
+#include <complex.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gd.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+
+#define size_x 320
+#define size_y 240
+
+
+#define PATH "/tmp/s.sockperf"
+
+
+struct thread_param
+{
+  unsigned int from;
+  unsigned int to;
+  unsigned int nserv;
+};
+
+struct coord
+{
+  unsigned int x;
+  unsigned int y;
+  complex double z;
+};
+
+
+/* We use 64bit values for the times.  */
+typedef unsigned long long int hp_timing_t;
+
+
+static unsigned int nclients = 2;
+static unsigned int nservers = 2;
+
+static bool timing;
+static int points;
+
+
+static complex double top_left = -0.7 + 0.2i;
+static complex double bottom_right = -0.5 - 0.0i;
+
+
+static int colors[256];
+static gdImagePtr image;
+static pthread_mutex_t image_lock;
+
+static int sock;
+
+
+static void *
+client (void *arg)
+{
+  struct thread_param *param = arg;
+  unsigned int cnt;
+  unsigned int nserv = param->nserv;
+  int clisock[nserv];
+  struct pollfd servpoll[nserv];
+  struct sockaddr_un servaddr;
+  socklen_t servlen;
+  struct coord c;
+
+  bool new_coord (void)
+    {
+      if (cnt >= param->to)
+       return false;
+
+      unsigned int row = cnt / size_x;
+      unsigned int col = cnt % size_x;
+
+      c.x = col;
+      c.y = row;
+      c.z = (top_left
+            + ((col
+                * (creal (bottom_right) - creal (top_left))) / size_x)
+            + (_Complex_I * (row * (cimag (bottom_right) - cimag (top_left)))
+               / size_y));
+
+      ++cnt;
+
+      return true;
+    }
+
+
+  for (cnt = 0; cnt < nserv; ++cnt)
+    {
+      servpoll[cnt].fd = socket (AF_UNIX, SOCK_STREAM, 0);
+      if (clisock < 0)
+       {
+         puts ("cannot create socket in client");
+         return NULL;
+       }
+
+      memset (&servaddr, '\0', sizeof (servaddr));
+      servaddr.sun_family = AF_UNIX;
+      strncpy (servaddr.sun_path, PATH, sizeof (servaddr.sun_path));
+      servlen = offsetof (struct sockaddr_un, sun_path) + strlen (PATH) + 1;
+
+
+      int err;
+      while (1)
+       {
+         err = TEMP_FAILURE_RETRY (connect (servpoll[cnt].fd, &servaddr,
+                                            servlen));
+         if (err != -1 || errno != ECONNREFUSED)
+           break;
+
+         pthread_yield ();
+       }
+
+      if (err == -1)
+       {
+         printf ("cannot connect: %m (%d)\n", errno);
+         exit (1);
+       }
+
+      servpoll[cnt].events = POLLOUT;
+      servpoll[cnt].revents = 0;
+    }
+
+  cnt = param->from;
+
+  new_coord ();
+  bool z_valid = true;
+
+  while (1)
+    {
+      int i;
+      int n = poll (servpoll, nserv, -1);
+      if (n == -1)
+       {
+         puts ("poll returned error");
+         break;
+       }
+
+      bool cont = false;
+      for (i = 0; i < nserv && n > 0; ++i)
+       if (servpoll[i].revents != 0)
+         {
+           if (servpoll[i].revents == POLLIN)
+             {
+               unsigned int vals[3];
+               if (TEMP_FAILURE_RETRY (read (servpoll[i].fd, &vals,
+                                             sizeof (vals)))
+                   != sizeof (vals))
+                 {
+                   puts ("read error in client");
+                   return NULL;
+                 }
+
+               pthread_mutex_lock (&image_lock);
+
+               gdImageSetPixel (image, vals[0], vals[1], vals[2]);
+               ++points;
+
+               pthread_mutex_unlock (&image_lock);
+
+               servpoll[i].events = POLLOUT;
+             }
+           else
+             {
+               if (servpoll[i].revents != POLLOUT)
+                 printf ("revents: %hd != POLLOUT ???\n",
+                         servpoll[i].revents);
+
+               if (z_valid)
+                 {
+                   if (TEMP_FAILURE_RETRY (write (servpoll[i].fd, &c,
+                                                  sizeof (c))) != sizeof (c))
+                     {
+                       puts ("write error in client");
+                       return NULL;
+                     }
+                   cont = true;
+                   servpoll[i].events = POLLIN;
+
+                   z_valid = new_coord ();
+                   if (! z_valid)
+                     /* No more to do.  Clear the event fields.  */
+                     for (i = 0; i < nserv; ++i)
+                       if (servpoll[i].events == POLLOUT)
+                         servpoll[i].events = servpoll[i].revents = 0;
+                 }
+               else
+                 servpoll[i].events = servpoll[i].revents = 0;
+             }
+
+           --n;
+         }
+       else if (servpoll[i].events != 0)
+         cont = true;
+
+      if (! cont && ! z_valid)
+       break;
+    }
+
+  c.x = 0xffffffff;
+  c.y = 0xffffffff;
+  for (cnt = 0; cnt < nserv; ++cnt)
+    {
+      TEMP_FAILURE_RETRY (write (servpoll[cnt].fd, &c, sizeof (c)));
+      close (servpoll[cnt].fd);
+    }
+
+  return NULL;
+}
+
+
+static void *
+server (void *arg)
+{
+  struct sockaddr_un cliaddr;
+  socklen_t clilen;
+  int clisock = TEMP_FAILURE_RETRY (accept (sock, &cliaddr, &clilen));
+
+  if (clisock == -1)
+    {
+      puts ("accept failed");
+      return NULL;
+    }
+
+  while (1)
+    {
+      struct coord c;
+
+      if (TEMP_FAILURE_RETRY (read (clisock, &c, sizeof (c))) != sizeof (c))
+       {
+         printf ("server read failed: %m (%d)\n", errno);
+         break;
+       }
+
+      if (c.x == 0xffffffff && c.y == 0xffffffff)
+       break;
+
+      unsigned int rnds = 0;
+      complex double z = c.z;
+      while (cabs (z) < 4.0)
+       {
+         z = z * z - 1;
+         if (++rnds == 255)
+           break;
+       }
+
+      unsigned int vals[3] = { c.x, c.y, rnds };
+      if (TEMP_FAILURE_RETRY (write (clisock, vals, sizeof (vals)))
+         != sizeof (vals))
+       {
+         puts ("server write error");
+         return NULL;
+       }
+    }
+
+  close (clisock);
+
+  return NULL;
+}
+
+
+static const char *outfilename = "test.png";
+
+
+static const struct argp_option options[] =
+  {
+    { "clients", 'c', "NUMBER", 0, "Number of client threads" },
+    { "servers", 's', "NUMBER", 0, "Number of server threads per client" },
+    { "timing", 'T', NULL, 0,
+      "Measure time from startup to the last thread finishing" },
+    { NULL, 0, NULL, 0, NULL }
+  };
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt
+};
+
+
+int
+main (int argc, char *argv[])
+{
+  int cnt;
+  FILE *outfile;
+  struct sockaddr_un servaddr;
+  socklen_t servlen;
+  int remaining;
+
+  /* Parse and process arguments.  */
+  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+
+  pthread_t servth[nservers * nclients];
+  pthread_t clntth[nclients];
+  struct thread_param clntparam[nclients];
+
+
+  image = gdImageCreate (size_x, size_y);
+  if (image == NULL)
+    {
+      puts ("gdImageCreate failed");
+      return 1;
+    }
+
+  for (cnt = 0; cnt < 255; ++cnt)
+    colors[cnt] = gdImageColorAllocate (image, 256 - cnt, 256 - cnt,
+                                       256 - cnt);
+  /* Black.  */
+  colors[cnt] = gdImageColorAllocate (image, 0, 0, 0);
+
+
+  sock = socket (AF_UNIX, SOCK_STREAM, 0);
+  if (sock < 0)
+    error (EXIT_FAILURE, errno, "cannot create socket");
+
+  memset (&servaddr, '\0', sizeof (servaddr));
+  servaddr.sun_family = AF_UNIX;
+  strncpy (servaddr.sun_path, PATH, sizeof (servaddr.sun_path));
+  servlen = offsetof (struct sockaddr_un, sun_path) + strlen (PATH) + 1;
+
+  if (bind (sock, &servaddr, servlen) == -1)
+    error (EXIT_FAILURE, errno, "bind failed");
+
+  listen (sock, SOMAXCONN);
+
+  pthread_mutex_init (&image_lock, NULL);
+
+
+  struct sigaction sa;
+  sa.sa_handler = SIG_IGN;
+  sigemptyset (&sa.sa_mask);
+  sa.sa_flags = 0;
+
+  clockid_t cl;
+  struct timespec start_time;
+  if (timing)
+    {
+      if (clock_getcpuclockid (0, &cl) != 0
+         || clock_gettime (cl, &start_time) != 0)
+       timing = false;
+    }
+
+  /* Start the servers.  */
+  for (cnt = 0; cnt < nservers * nclients; ++cnt)
+    {
+      if (pthread_create (&servth[cnt], NULL, server, NULL) != 0)
+       {
+         puts ("pthread_create for server failed");
+         exit (1);
+       }
+    }
+
+  for (cnt = 0; cnt < nclients; ++cnt)
+    {
+      clntparam[cnt].from = cnt * (size_x * size_y) / nclients;
+      clntparam[cnt].to = MIN ((cnt + 1) * (size_x * size_y) / nclients,
+                              size_x * size_y);
+      clntparam[cnt].nserv = nservers;
+
+      if (pthread_create (&clntth[cnt], NULL, client, &clntparam[cnt]) != 0)
+       {
+         puts ("pthread_create for client failed");
+         exit (1);
+       }
+    }
+
+
+  /* Wait for the clients.  */
+  for (cnt = 0; cnt < nclients; ++cnt)
+    if (pthread_join (clntth[cnt], NULL) != 0)
+      {
+       puts ("client pthread_join failed");
+       exit (1);
+      }
+
+  /* Wait for the servers.  */
+  for (cnt = 0; cnt < nclients * nservers; ++cnt)
+    if (pthread_join (servth[cnt], NULL) != 0)
+      {
+       puts ("server pthread_join failed");
+       exit (1);
+      }
+
+
+  if (timing)
+    {
+      struct timespec end_time;
+
+      if (clock_gettime (cl, &end_time) == 0)
+       {
+         end_time.tv_sec -= start_time.tv_sec;
+         end_time.tv_nsec -= start_time.tv_nsec;
+         if (end_time.tv_nsec < 0)
+           {
+             end_time.tv_nsec += 1000000000;
+             --end_time.tv_sec;
+           }
+
+         printf ("\nRuntime: %lu.%09lu seconds\n%d points computed\n",
+                 (unsigned long int) end_time.tv_sec,
+                 (unsigned long int) end_time.tv_nsec,
+                 points);
+       }
+    }
+
+
+  outfile = fopen (outfilename, "w");
+  if (outfile == NULL)
+    error (EXIT_FAILURE, errno, "cannot open output file '%s'", outfilename);
+
+  gdImagePng (image, outfile);
+
+  fclose (outfile);
+
+  unlink (PATH);
+
+  return 0;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case 'c':
+      nclients = strtoul (arg, NULL, 0);
+      break;
+
+    case 's':
+      nservers = strtoul (arg, NULL, 0);
+      break;
+
+    case 'T':
+      timing = true;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+
+  return 0;
+}
+
+
+static hp_timing_t
+get_clockfreq (void)
+{
+  /* We read the information from the /proc filesystem.  It contains at
+     least one line like
+       cpu MHz         : 497.840237
+     or also
+       cpu MHz         : 497.841
+     We search for this line and convert the number in an integer.  */
+  static hp_timing_t result;
+  int fd;
+
+  /* If this function was called before, we know the result.  */
+  if (result != 0)
+    return result;
+
+  fd = open ("/proc/cpuinfo", O_RDONLY);
+  if (__builtin_expect (fd != -1, 1))
+    {
+      /* XXX AFAIK the /proc filesystem can generate "files" only up
+         to a size of 4096 bytes.  */
+      char buf[4096];
+      ssize_t n;
+
+      n = read (fd, buf, sizeof buf);
+      if (__builtin_expect (n, 1) > 0)
+       {
+         char *mhz = memmem (buf, n, "cpu MHz", 7);
+
+         if (__builtin_expect (mhz != NULL, 1))
+           {
+             char *endp = buf + n;
+             int seen_decpoint = 0;
+             int ndigits = 0;
+
+             /* Search for the beginning of the string.  */
+             while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
+               ++mhz;
+
+             while (mhz < endp && *mhz != '\n')
+               {
+                 if (*mhz >= '0' && *mhz <= '9')
+                   {
+                     result *= 10;
+                     result += *mhz - '0';
+                     if (seen_decpoint)
+                       ++ndigits;
+                   }
+                 else if (*mhz == '.')
+                   seen_decpoint = 1;
+
+                 ++mhz;
+               }
+
+             /* Compensate for missing digits at the end.  */
+             while (ndigits++ < 6)
+               result *= 10;
+           }
+       }
+
+      close (fd);
+    }
+
+  return result;
+}
+
+
+int
+clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
+{
+  /* We don't allow any process ID but our own.  */
+  if (pid != 0 && pid != getpid ())
+    return EPERM;
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+  /* Store the number.  */
+  *clock_id = CLOCK_PROCESS_CPUTIME_ID;
+
+  return 0;
+#else
+  /* We don't have a timer for that.  */
+  return ENOENT;
+#endif
+}
+
+
+#define HP_TIMING_NOW(Var)     __asm__ __volatile__ ("rdtsc" : "=A" (Var))
+
+/* Get current value of CLOCK and store it in TP.  */
+int
+clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+  int retval = -1;
+
+  switch (clock_id)
+    {
+    case CLOCK_PROCESS_CPUTIME_ID:
+      {
+
+       static hp_timing_t freq;
+       hp_timing_t tsc;
+
+       /* Get the current counter.  */
+       HP_TIMING_NOW (tsc);
+
+       if (freq == 0)
+         {
+           freq = get_clockfreq ();
+           if (freq == 0)
+             return EINVAL;
+         }
+
+       /* Compute the seconds.  */
+       tp->tv_sec = tsc / freq;
+
+       /* And the nanoseconds.  This computation should be stable until
+          we get machines with about 16GHz frequency.  */
+       tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
+
+       retval = 0;
+      }
+    break;
+
+    default:
+      errno = EINVAL;
+      break;
+    }
+
+  return retval;
+}
diff --git a/libpthread/nptl/sysdeps/alpha/Makefile b/libpthread/nptl/sysdeps/alpha/Makefile
new file mode 100644 (file)
index 0000000..88c106b
--- /dev/null
@@ -0,0 +1,21 @@
+# 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
diff --git a/libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c b/libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c
new file mode 100644 (file)
index 0000000..ba2e419
--- /dev/null
@@ -0,0 +1,89 @@
+/* Special .init and .fini section support for Alpha.  NPTL 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.  */
+
+/* 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.
+
+   This differs from what would be generated by the generic code in that
+   we save and restore the GP within the function.  In order for linker
+   relaxation to work, the value in the GP register on exit from a function
+   must be valid for the function entry point.  Normally, a function is
+   contained within one object file and this is not an issue, provided
+   that the function reloads the gp after making any function calls.
+   However, _init and _fini are constructed from pieces of many object
+   files, all of which may have different GP values.  So we must reload
+   the GP value from crti.o in crtn.o.  */
+
+__asm__ ("                                             \n\
+#include \"defs.h\"                                    \n\
+                                                       \n\
+/*@HEADER_ENDS*/                                       \n\
+                                                       \n\
+/*@_init_PROLOG_BEGINS*/                               \n\
+       .section .init, \"ax\", @progbits               \n\
+       .globl  _init                                   \n\
+       .type   _init,@function                         \n\
+       .usepv  _init,std                               \n\
+_init:                                                 \n\
+       ldgp    $29, 0($27)                             \n\
+       subq    $30, 16, $30                            \n\
+       stq     $26, 0($30)                             \n\
+       stq     $29, 8($30)                             \n\
+       bsr     $26, __pthread_initialize_minimal_internal !samegp \n\
+       .align 3                                        \n\
+/*@_init_PROLOG_ENDS*/                                 \n\
+                                                       \n\
+/*@_init_EPILOG_BEGINS*/                               \n\
+       .section .init, \"ax\", @progbits               \n\
+       ldq     $26, 0($30)                             \n\
+       ldq     $29, 8($30)                             \n\
+       addq    $30, 16, $30                            \n\
+       ret                                             \n\
+/*@_init_EPILOG_ENDS*/                                 \n\
+                                                       \n\
+/*@_fini_PROLOG_BEGINS*/                               \n\
+       .section .fini, \"ax\", @progbits               \n\
+       .globl  _fini                                   \n\
+       .type   _fini,@function                         \n\
+       .usepv  _fini,std                               \n\
+_fini:                                                 \n\
+       ldgp    $29, 0($27)                             \n\
+       subq    $30, 16, $30                            \n\
+       stq     $26, 0($30)                             \n\
+       stq     $29, 8($30)                             \n\
+       .align 3                                        \n\
+/*@_fini_PROLOG_ENDS*/                                 \n\
+                                                       \n\
+/*@_fini_EPILOG_BEGINS*/                               \n\
+       .section .fini, \"ax\", @progbits               \n\
+       ldq     $26, 0($30)                             \n\
+       ldq     $29, 8($30)                             \n\
+       addq    $30, 16, $30                            \n\
+       ret                                             \n\
+/*@_fini_EPILOG_ENDS*/                                 \n\
+                                                       \n\
+/*@TRAILER_BEGINS*/                                    \n\
+");
diff --git a/libpthread/nptl/sysdeps/alpha/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/alpha/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..5cef8b1
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/alpha/pthread_spin_lock.S b/libpthread/nptl/sysdeps/alpha/pthread_spin_lock.S
new file mode 100644 (file)
index 0000000..ce6cd41
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson  <rth@twiddle.net>, 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.  */
+
+
+       .text
+       .align  4
+
+       .globl  pthread_spin_lock
+       .ent    pthread_spin_lock
+pthread_spin_lock:
+       .frame  $sp, 0, $26, 0
+       .prologue 0
+
+0:     ldl_l   $1, 0($16)
+       lda     $2, 1
+       lda     $0, 0
+       bne     $1, 1f
+
+       stl_c   $2, 0($16)
+       beq     $2, 1f
+       mb
+       ret
+
+1:     ldl     $1, 0($16)
+       bne     $1, 1b
+       unop
+       br      0b
+
+       .end    pthread_spin_lock
diff --git a/libpthread/nptl/sysdeps/alpha/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/alpha/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..0948da6
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson  <rth@twiddle.net>, 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.  */
+
+
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+       .text
+       .align  4
+
+       .globl  pthread_spin_trylock
+       .ent    pthread_spin_trylock
+pthread_spin_trylock:
+       .frame  $sp, 0, $26, 0
+       .prologue 0
+
+0:     ldl_l   $1, 0($16)
+       lda     $2, 1
+       lda     $0, EBUSY
+       bne     $1, 1f
+
+       stl_c   $2, 0($16)
+       beq     $2, 2f
+       mb
+       lda     $0, 0
+
+1:     ret
+2:     br      0b
+
+       .end    pthread_spin_trylock
diff --git a/libpthread/nptl/sysdeps/alpha/pthreaddef.h b/libpthread/nptl/sysdeps/alpha/pthreaddef.h
new file mode 100644 (file)
index 0000000..26c4daf
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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.  */
+#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
+
+/* 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 --git a/libpthread/nptl/sysdeps/alpha/tcb-offsets.sym b/libpthread/nptl/sysdeps/alpha/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..c21a791
--- /dev/null
@@ -0,0 +1,14 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+-- # define __builtin_thread_pointer()  ((void *) 0)
+-- # define thread_offsetof(mem)     ((void *) &THREAD_SELF->mem - (void *) 0)
+-- Ho hum, this doesn't work in gcc4, so Know Things about THREAD_SELF
+#define thread_offsetof(mem)   (long)(offsetof(struct pthread, mem) - sizeof(struct pthread))
+
+MULTIPLE_THREADS_OFFSET                thread_offsetof (header.multiple_threads)
+PID_OFFSET                     thread_offsetof (pid)
+TID_OFFSET                     thread_offsetof (tid)
diff --git a/libpthread/nptl/sysdeps/alpha/tls.h b/libpthread/nptl/sysdeps/alpha/tls.h
new file mode 100644 (file)
index 0000000..fa3c832
--- /dev/null
@@ -0,0 +1,129 @@
+/* Definition for thread-local data handling.  NPTL/Alpha version.
+   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H 1
+
+# include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+/* 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
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE     sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN    16
+
+/* 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         16
+
+/* 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) \
+  (__builtin_set_thread_pointer ((void *)(tcbp)), NULL)
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  (((tcbhead_t *) __builtin_thread_pointer ())->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+ ((struct pthread *)__builtin_thread_pointer () - 1)
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  REGISTER (64, 64, 32 * 8, -sizeof (struct pthread))
+
+/* 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/libpthread/nptl/sysdeps/i386/Makefile b/libpthread/nptl/sysdeps/i386/Makefile
new file mode 100644 (file)
index 0000000..2f0d88f
--- /dev/null
@@ -0,0 +1,27 @@
+# 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
+
+ifeq ($(subdir),nptl)
+CFLAGS-pthread_create.c += -mpreferred-stack-boundary=4
+CFLAGS-tst-align.c += -mpreferred-stack-boundary=4
+CFLAGS-tst-align2.c += -mpreferred-stack-boundary=4
+endif
diff --git a/libpthread/nptl/sysdeps/i386/i486/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/i386/i486/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..e30072c
--- /dev/null
@@ -0,0 +1,47 @@
+/* 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.  */
+
+#include <pthread-errnos.h>
+
+
+#ifdef UP
+# define LOCK
+#else
+# define LOCK lock
+#endif
+
+       .globl  pthread_spin_trylock
+       .type   pthread_spin_trylock,@function
+       .align  16
+pthread_spin_trylock:
+       movl    4(%esp), %edx
+       movl    $1, %eax
+       xorl    %ecx, %ecx
+       LOCK
+       cmpxchgl %ecx, (%edx)
+       movl    $EBUSY, %eax
+#ifdef HAVE_CMOV
+       cmovel  %ecx, %eax
+#else
+       jne     0f
+       movl    %ecx, %eax
+0:
+#endif
+       ret
+       .size   pthread_spin_trylock,.-pthread_spin_trylock
diff --git a/libpthread/nptl/sysdeps/i386/i586/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/i386/i586/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..ffe3d45
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 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.  */
+
+#include "../i486/pthread_spin_trylock.S"
diff --git a/libpthread/nptl/sysdeps/i386/i686/Makefile b/libpthread/nptl/sysdeps/i386/i686/Makefile
new file mode 100644 (file)
index 0000000..137c0a2
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (C) 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.
+
+ifeq ($(subdir),nptl)
+# It turns out that stack coloring is in general not good on P4s.  Some
+# applications will benefit.  We will probably have a configuration option
+# at some point.  Enabling coloring can be done with
+#
+#   -DCOLORING_INCREMENT=128
+#
+# What is useful is to avoid the 64k aliasing problem which reliably
+# happens if all stacks use sizes which are a multiple of 64k.  Tell
+# the stack allocator to disturb this by allocation one more page if
+# necessary.
+CFLAGS-pthread_create.c += -DMULTI_PAGE_ALIASING=65536
+endif
diff --git a/libpthread/nptl/sysdeps/i386/i686/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/i386/i686/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..a5d861f
--- /dev/null
@@ -0,0 +1,21 @@
+/* Copyright (C) 2002 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.  */
+
+#define HAVE_CMOV      1
+#include "../i486/pthread_spin_trylock.S"
diff --git a/libpthread/nptl/sysdeps/i386/i686/tls.h b/libpthread/nptl/sysdeps/i386/i686/tls.h
new file mode 100644 (file)
index 0000000..4025ed8
--- /dev/null
@@ -0,0 +1,36 @@
+/* Copyright (C) 2002 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 _TLS_H
+
+/* Additional definitions for <tls.h> on i686 and up.  */
+
+
+/* Macros to load from and store into segment registers.  We can use
+   the 32-bit instructions.  */
+#define TLS_GET_GS() \
+  ({ int __seg; __asm ("movl %%gs, %0" : "=q" (__seg)); __seg; })
+#define TLS_SET_GS(val) \
+  __asm ("movl %0, %%gs" :: "q" (val))
+
+
+/* Get the full set of definitions.  */
+#include "../tls.h"
+
+#endif /* tls.h */
diff --git a/libpthread/nptl/sysdeps/i386/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/i386/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..5cef8b1
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/i386/pthread_spin_init.c b/libpthread/nptl/sysdeps/i386/pthread_spin_init.c
new file mode 100644 (file)
index 0000000..0a47981
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 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.  */
+
+/* Not needed.  pthread_spin_init is an alias for pthread_spin_unlock.  */
diff --git a/libpthread/nptl/sysdeps/i386/pthread_spin_lock.c b/libpthread/nptl/sysdeps/i386/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..b41174e
--- /dev/null
@@ -0,0 +1,49 @@
+/* Copyright (C) 2002,2003,2004 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.  */
+
+#include "pthreadP.h"
+
+#ifndef LOCK_PREFIX
+# ifdef UP
+#  define LOCK_PREFIX  /* nothing */
+# else
+#  define LOCK_PREFIX  "lock;"
+# endif
+#endif
+
+
+int
+pthread_spin_lock (lock)
+     pthread_spinlock_t *lock;
+{
+  asm ("\n"
+       "1:\t" LOCK_PREFIX "decl %0\n\t"
+       "jne 2f\n\t"
+       ".subsection 1\n\t"
+       ".align 16\n"
+       "2:\trep; nop\n\t"
+       "cmpl $0, %0\n\t"
+       "jg 1b\n\t"
+       "jmp 2b\n\t"
+       ".previous"
+       : "=m" (*lock)
+       : "m" (*lock));
+
+  return 0;
+}
diff --git a/libpthread/nptl/sysdeps/i386/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/i386/pthread_spin_unlock.S
new file mode 100644 (file)
index 0000000..d94f1e7
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002 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.  */
+
+       .globl  pthread_spin_unlock
+       .type   pthread_spin_unlock,@function
+       .align  16
+pthread_spin_unlock:
+       movl    4(%esp), %eax
+       movl    $1, (%eax)
+       xorl    %eax, %eax
+       ret
+       .size   pthread_spin_unlock,.-pthread_spin_unlock
+
+       /* The implementation of pthread_spin_init is identical.  */
+       .globl  pthread_spin_init
+pthread_spin_init = pthread_spin_unlock
diff --git a/libpthread/nptl/sysdeps/i386/pthreaddef.h b/libpthread/nptl/sysdeps/i386/pthreaddef.h
new file mode 100644 (file)
index 0000000..43b771c
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  SSE requires 16
+   bytes.  */
+#define STACK_ALIGN            16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK     2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT          16
+
+
+/* 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) \
+  while (1) {                                                                \
+    if (__builtin_constant_p (val) && (val) == 0)                            \
+      asm volatile ("xorl %%ebx, %%ebx; int $0x80" :: "a" (__NR_exit));              \
+    else                                                                     \
+      asm volatile ("movl %1, %%ebx; int $0x80"                                      \
+                   :: "a" (__NR_exit), "r" (val));                           \
+  }
diff --git a/libpthread/nptl/sysdeps/i386/tcb-offsets.sym b/libpthread/nptl/sysdeps/i386/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..4e0444b
--- /dev/null
@@ -0,0 +1,13 @@
+#include <sysdep.h>
+#include <tls.h>
+
+RESULT                 offsetof (struct pthread, result)
+TID                    offsetof (struct pthread, tid)
+PID                    offsetof (struct pthread, pid)
+CANCELHANDLING         offsetof (struct pthread, cancelhandling)
+CLEANUP_JMP_BUF                offsetof (struct pthread, cleanup_jmp_buf)
+MULTIPLE_THREADS_OFFSET        offsetof (tcbhead_t, multiple_threads)
+SYSINFO_OFFSET         offsetof (tcbhead_t, sysinfo)
+CLEANUP                        offsetof (struct pthread, cleanup)
+CLEANUP_PREV           offsetof (struct _pthread_cleanup_buffer, __prev)
+MUTEX_FUTEX            offsetof (pthread_mutex_t, __data.__lock)
diff --git a/libpthread/nptl/sysdeps/i386/tls.h b/libpthread/nptl/sysdeps/i386/tls.h
new file mode 100644 (file)
index 0000000..06def42
--- /dev/null
@@ -0,0 +1,419 @@
+/* Definition for thread-local data handling.  nptl/i386 version.
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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 <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <list.h>
+
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+
+typedef struct
+{
+  void *tcb;           /* Pointer to the TCB.  Not necessarily the
+                          thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;          /* Pointer to the thread descriptor.  */
+  int multiple_threads;
+  uintptr_t sysinfo;
+} 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.  For IA-32 this is governed by
+   the SSE memory functions.  */
+#define STACK_ALIGN    16
+
+#ifndef __ASSEMBLER__
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* The old way: using LDT.  */
+
+/* Structure passed to `modify_ldt', 'set_thread_area', and 'clone' calls.  */
+struct user_desc
+{
+  unsigned int entry_number;
+  unsigned long int base_addr;
+  unsigned int limit;
+  unsigned int seg_32bit:1;
+  unsigned int contents:2;
+  unsigned int read_exec_only:1;
+  unsigned int limit_in_pages:1;
+  unsigned int seg_not_present:1;
+  unsigned int useable:1;
+  unsigned int empty:25;
+};
+
+/* Initializing bit fields is slow.  We speed it up by using a union.  */
+union user_desc_init
+{
+  struct user_desc desc;
+  unsigned int vals[4];
+};
+
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+/* 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 (struct pthread)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+# define TLS_TCB_AT_TP 1
+
+
+/* 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(dtvp) \
+  ({ struct pthread *__pd;                                                   \
+     THREAD_SETMEM (__pd, header.dtv, (dtvp)); })
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(descr) \
+  (((tcbhead_t *) (descr))->dtv)
+
+#define THREAD_SELF_SYSINFO    THREAD_GETMEM (THREAD_SELF, header.sysinfo)
+#define THREAD_SYSINFO(pd)     ((pd)->header.sysinfo)
+
+/* Macros to load from and store into segment registers.  */
+# ifndef TLS_GET_GS
+#  define TLS_GET_GS() \
+  ({ int __seg; __asm ("movw %%gs, %w0" : "=q" (__seg)); __seg & 0xffff; })
+# endif
+# ifndef TLS_SET_GS
+#  define TLS_SET_GS(val) \
+  __asm ("movw %w0, %%gs" :: "q" (val))
+# endif
+
+
+# ifndef __NR_set_thread_area
+#  define __NR_set_thread_area 243
+# endif
+# ifndef TLS_FLAG_WRITABLE
+#  define TLS_FLAG_WRITABLE            0x00000001
+# endif
+
+// XXX Enable for the real world.
+#if 0
+# ifndef __ASSUME_SET_THREAD_AREA
+#  error "we need set_thread_area"
+# endif
+#endif
+
+# ifdef __PIC__
+#  define TLS_EBX_ARG "r"
+#  define TLS_LOAD_EBX "xchgl %3, %%ebx\n\t"
+# else
+#  define TLS_EBX_ARG "b"
+#  define TLS_LOAD_EBX
+# endif
+
+#if defined NEED_DL_SYSINFO
+# define INIT_SYSINFO \
+  _head->sysinfo = GLRO(dl_sysinfo)
+#else
+# define INIT_SYSINFO
+#endif
+
+#ifndef LOCK_PREFIX
+# ifdef UP
+#  define LOCK_PREFIX  /* nothing */
+# else
+#  define LOCK_PREFIX "lock;"
+# endif
+#endif
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(thrdescr, secondcall) \
+  ({ void *_thrdescr = (thrdescr);                                           \
+     tcbhead_t *_head = _thrdescr;                                           \
+     union user_desc_init _segdescr;                                         \
+     int _result;                                                            \
+                                                                             \
+     _head->tcb = _thrdescr;                                                 \
+     /* For now the thread descriptor is at the same address.  */            \
+     _head->self = _thrdescr;                                                \
+     /* New syscall handling support.  */                                    \
+     INIT_SYSINFO;                                                           \
+                                                                             \
+     /* The 'entry_number' field.  Let the kernel pick a value.  */          \
+     if (secondcall)                                                         \
+       _segdescr.vals[0] = TLS_GET_GS () >> 3;                               \
+     else                                                                    \
+       _segdescr.vals[0] = -1;                                               \
+     /* The 'base_addr' field.  Pointer to the TCB.  */                              \
+     _segdescr.vals[1] = (unsigned long int) _thrdescr;                              \
+     /* The 'limit' field.  We use 4GB which is 0xfffff pages.  */           \
+     _segdescr.vals[2] = 0xfffff;                                            \
+     /* Collapsed value of the bitfield:                                     \
+         .seg_32bit = 1                                                      \
+         .contents = 0                                                       \
+         .read_exec_only = 0                                                 \
+         .limit_in_pages = 1                                                 \
+         .seg_not_present = 0                                                \
+         .useable = 1 */                                                     \
+     _segdescr.vals[3] = 0x51;                                               \
+                                                                             \
+     /* Install the TLS.  */                                                 \
+     asm volatile (TLS_LOAD_EBX                                                      \
+                  "int $0x80\n\t"                                            \
+                  TLS_LOAD_EBX                                               \
+                  : "=a" (_result), "=m" (_segdescr.desc.entry_number)       \
+                  : "0" (__NR_set_thread_area),                              \
+                    TLS_EBX_ARG (&_segdescr.desc), "m" (_segdescr.desc));    \
+                                                                             \
+     if (_result == 0)                                                       \
+       /* We know the index in the GDT, now load the segment register.       \
+         The use of the GDT is described by the value 3 in the lower         \
+         three bits of the segment descriptor value.                         \
+                                                                             \
+         Note that we have to do this even if the numeric value of           \
+         the descriptor does not change.  Loading the segment register       \
+         causes the segment information from the GDT to be loaded            \
+         which is necessary since we have changed it.   */                   \
+       TLS_SET_GS (_segdescr.desc.entry_number * 8 + 3);                     \
+                                                                             \
+     _result == 0 ? NULL                                                     \
+     : "set_thread_area failed when setting up thread-local storage\n"; })
+
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  ({ struct pthread *__pd;                                                   \
+     THREAD_GETMEM (__pd, header.dtv); })
+
+
+/* Return the thread descriptor for the current thread.
+
+   The contained asm must *not* be marked volatile since otherwise
+   assignments like
+        pthread_descr self = thread_self();
+   do not get optimized away.  */
+# define THREAD_SELF \
+  ({ struct pthread *__self;                                                 \
+     asm ("movl %%gs:%c1,%0" : "=r" (__self)                                 \
+         : "i" (offsetof (struct pthread, header.self)));                    \
+     __self;})
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  REGISTER_THREAD_AREA (32, offsetof (struct user_regs_struct, xgs), 3) \
+  REGISTER_THREAD_AREA (64, 26 * 8, 3) /* x86-64's user_regs_struct->gs */
+
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) \
+  ({ __typeof (descr->member) __value;                                       \
+     if (sizeof (__value) == 1)                                                      \
+       asm volatile ("movb %%gs:%P2,%b0"                                     \
+                    : "=q" (__value)                                         \
+                    : "0" (0), "i" (offsetof (struct pthread, member)));     \
+     else if (sizeof (__value) == 4)                                         \
+       asm volatile ("movl %%gs:%P1,%0"                                              \
+                    : "=r" (__value)                                         \
+                    : "i" (offsetof (struct pthread, member)));              \
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (__value) != 8)                                           \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile ("movl %%gs:%P1,%%eax\n\t"                              \
+                      "movl %%gs:%P2,%%edx"                                  \
+                      : "=A" (__value)                                       \
+                      : "i" (offsetof (struct pthread, member)),             \
+                        "i" (offsetof (struct pthread, member) + 4));        \
+       }                                                                     \
+     __value; })
+
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) \
+  ({ __typeof (descr->member[0]) __value;                                    \
+     if (sizeof (__value) == 1)                                                      \
+       asm volatile ("movb %%gs:%P2(%3),%b0"                                 \
+                    : "=q" (__value)                                         \
+                    : "0" (0), "i" (offsetof (struct pthread, member[0])),   \
+                    "r" (idx));                                              \
+     else if (sizeof (__value) == 4)                                         \
+       asm volatile ("movl %%gs:%P1(,%2,4),%0"                               \
+                    : "=r" (__value)                                         \
+                    : "i" (offsetof (struct pthread, member[0])),            \
+                      "r" (idx));                                            \
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (__value) != 8)                                           \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile  ("movl %%gs:%P1(,%2,8),%%eax\n\t"                      \
+                       "movl %%gs:4+%P1(,%2,8),%%edx"                        \
+                       : "=&A" (__value)                                     \
+                       : "i" (offsetof (struct pthread, member[0])),         \
+                         "r" (idx));                                         \
+       }                                                                     \
+     __value; })
+
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM(descr, member, value) \
+  ({ if (sizeof (descr->member) == 1)                                        \
+       asm volatile ("movb %b0,%%gs:%P1" :                                   \
+                    : "iq" (value),                                          \
+                      "i" (offsetof (struct pthread, member)));              \
+     else if (sizeof (descr->member) == 4)                                   \
+       asm volatile ("movl %0,%%gs:%P1" :                                    \
+                    : "ir" (value),                                          \
+                      "i" (offsetof (struct pthread, member)));              \
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (descr->member) != 8)                                     \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile ("movl %%eax,%%gs:%P1\n\t"                              \
+                      "movl %%edx,%%gs:%P2" :                                \
+                      : "A" (value),                                         \
+                        "i" (offsetof (struct pthread, member)),             \
+                        "i" (offsetof (struct pthread, member) + 4));        \
+       }})
+
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+  ({ if (sizeof (descr->member[0]) == 1)                                     \
+       asm volatile ("movb %b0,%%gs:%P1(%2)" :                               \
+                    : "iq" (value),                                          \
+                      "i" (offsetof (struct pthread, member)),               \
+                      "r" (idx));                                            \
+     else if (sizeof (descr->member[0]) == 4)                                \
+       asm volatile ("movl %0,%%gs:%P1(,%2,4)" :                             \
+                    : "ir" (value),                                          \
+                      "i" (offsetof (struct pthread, member)),               \
+                      "r" (idx));                                            \
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (descr->member[0]) != 8)                                  \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t"                       \
+                      "movl %%edx,%%gs:4+%P1(,%2,8)" :                       \
+                      : "A" (value),                                         \
+                        "i" (offsetof (struct pthread, member)),             \
+                        "r" (idx));                                          \
+       }})
+
+
+/* Atomic compare and exchange on TLS, returning old value.  */
+#define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
+  ({ __typeof (descr->member) __ret;                                         \
+     __typeof (oldval) __old = (oldval);                                     \
+     if (sizeof (descr->member) == 4)                                        \
+       asm volatile (LOCK_PREFIX "cmpxchgl %2, %%gs:%P3"                     \
+                    : "=a" (__ret)                                           \
+                    : "0" (__old), "r" (newval),                             \
+                      "i" (offsetof (struct pthread, member)));              \
+     else                                                                    \
+       /* Not necessary for other sizes in the moment.  */                   \
+       abort ();                                                             \
+     __ret; })
+
+
+/* Atomic set bit.  */
+#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
+  (void) ({ if (sizeof ((descr)->member) == 4)                               \
+             asm volatile (LOCK_PREFIX "orl %1, %%gs:%P0"                    \
+                           :: "i" (offsetof (struct pthread, member)),       \
+                              "ir" (1 << (bit)));                            \
+           else                                                              \
+             /* Not necessary for other sizes in the moment.  */             \
+             abort (); })
+
+
+/* Call the user-provided thread function.  */
+#define CALL_THREAD_FCT(descr) \
+  ({ void *__res;                                                            \
+     int __ignore1, __ignore2;                                               \
+     asm volatile ("pushl %%eax\n\t"                                         \
+                  "pushl %%eax\n\t"                                          \
+                  "pushl %%eax\n\t"                                          \
+                  "pushl %%gs:%P4\n\t"                                       \
+                  "call *%%gs:%P3\n\t"                                       \
+                  "addl $16, %%esp"                                          \
+                  : "=a" (__res), "=c" (__ignore1), "=d" (__ignore2)         \
+                  : "i" (offsetof (struct pthread, start_routine)),          \
+                    "i" (offsetof (struct pthread, arg)));                   \
+     __res; })
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/libpthread/nptl/sysdeps/mips/Makefile b/libpthread/nptl/sysdeps/mips/Makefile
new file mode 100644 (file)
index 0000000..d0c59a5
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright (C) 2005 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
+
+ifeq ($(subdir),nptl)
+libpthread-sysdep_routines += nptl-sysdep
+endif
diff --git a/libpthread/nptl/sysdeps/mips/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/mips/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..67cc969
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[0].__sp - (_adj))
+
+/* We use the normal longjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/mips/nptl-sysdep.S b/libpthread/nptl/sysdeps/mips/nptl-sysdep.S
new file mode 100644 (file)
index 0000000..3f5c2a3
--- /dev/null
@@ -0,0 +1,2 @@
+/* Pull in __syscall_error.  */
+#include <sysdep.S>
diff --git a/libpthread/nptl/sysdeps/mips/pthread_spin_lock.S b/libpthread/nptl/sysdeps/mips/pthread_spin_lock.S
new file mode 100644 (file)
index 0000000..d5f2a72
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sys/asm.h>
+#include <sysdep.h>
+#include <sgidefs.h>
+
+ENTRY (pthread_spin_lock)
+       .set    push
+#if _MIPS_SIM == _ABIO32
+       .set    mips2
+#endif
+1:     ll      a2, 0(a0)
+       li      a1, 1
+       bnez    a2, 1b
+       sc      a1, 0(a0)
+       beqz    a1, 1b
+       MIPS_SYNC
+       .set    pop
+       li      v0, 0
+       ret
+PSEUDO_END (pthread_spin_lock)
diff --git a/libpthread/nptl/sysdeps/mips/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/mips/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..9c6e740
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sys/asm.h>
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <sgidefs.h>
+
+ENTRY (pthread_spin_trylock)
+       .set    push
+#if _MIPS_SIM == _ABIO32
+       .set    mips2
+#endif
+       ll      a2, 0(a0)
+       li      a1, 1
+       bnez    a2, 1f
+       sc      a1, 0(a0)
+       beqz    a1, 1f
+       MIPS_SYNC
+       .set    pop
+       li      v0, 0
+       ret
+1:     li      v0, EBUSY
+       ret
+PSEUDO_END (pthread_spin_trylock)
diff --git a/libpthread/nptl/sysdeps/mips/pthreaddef.h b/libpthread/nptl/sysdeps/mips/pthreaddef.h
new file mode 100644 (file)
index 0000000..e72b4bc
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  */
+#define STACK_ALIGN            16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK     2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT          16
+
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME    __builtin_frame_address (0)
+
+
+/* XXX Until we have a better place keep the definitions here.  */
+
+#define __exit_thread_inline(val) \
+  INLINE_SYSCALL (exit, 1, (val))
diff --git a/libpthread/nptl/sysdeps/mips/tcb-offsets.sym b/libpthread/nptl/sysdeps/mips/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..e0e71dc
--- /dev/null
@@ -0,0 +1,11 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+#define thread_offsetof(mem)   (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
+
+MULTIPLE_THREADS_OFFSET                thread_offsetof (header.multiple_threads)
+PID_OFFSET                     thread_offsetof (pid)
+TID_OFFSET                     thread_offsetof (tid)
diff --git a/libpthread/nptl/sysdeps/mips/tls.h b/libpthread/nptl/sysdeps/mips/tls.h
new file mode 100644 (file)
index 0000000..1cef161
--- /dev/null
@@ -0,0 +1,161 @@
+/* Definition for thread-local data handling.  NPTL/MIPS version.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H 1
+
+#include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+/* Note: rd must be $v1 to be ABI-conformant.  */
+# define READ_THREAD_POINTER() \
+    ({ void *__result;                                                       \
+       asm volatile (".set\tpush\n\t.set\tmips32r2\n\t"                              \
+                    "rdhwr\t%0, $29\n\t.set\tpop" : "=v" (__result));        \
+       __result; })
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+
+# define READ_THREAD_POINTER(rd) \
+       .set    push;                                                         \
+       .set    mips32r2;                                                     \
+       rdhwr   rd, $29;                                                      \
+       .set    pop
+#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
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  Because our TCB is before the thread
+   pointer, we don't need this.  */
+# define TLS_INIT_TCB_SIZE     0
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN    __alignof__ (struct pthread)
+
+/* This is the size of the TCB.  Because our TCB is before the thread
+   pointer, we don't need this.  */
+# define TLS_TCB_SIZE          0
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN         __alignof__ (struct pthread)
+
+/* This is the size we need before TCB - actually, it includes the TCB.  */
+# define TLS_PRE_TCB_SIZE \
+  (sizeof (struct pthread)                                                   \
+   + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+
+/* The thread pointer (in hardware register $29) points to the end of
+   the TCB + 0x7000, as for PowerPC.  The pthread_descr structure is
+   immediately in front of the TCB.  */
+# 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))[-1].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))[-1].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) \
+  ({ INTERNAL_SYSCALL_DECL (err);                                      \
+     long result_var;                                                  \
+     result_var = INTERNAL_SYSCALL (set_thread_area, err, 1,           \
+                                   (char *) (tcbp) + TLS_TCB_OFFSET);  \
+     INTERNAL_SYSCALL_ERROR_P (result_var, err)                                \
+       ? "unknown error" : NULL; })
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  (((tcbhead_t *) (READ_THREAD_POINTER () - TLS_TCB_OFFSET))[-1].dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+ ((struct pthread *) (READ_THREAD_POINTER ()                        \
+                     - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
+
+/* 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)
+
+/* l_tls_offset == 0 is perfectly valid on MIPS, so we have to use some
+   different value to mean unset l_tls_offset.  */
+# define NO_TLS_OFFSET         -1
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/libpthread/nptl/sysdeps/powerpc/Makefile b/libpthread/nptl/sysdeps/powerpc/Makefile
new file mode 100644 (file)
index 0000000..3af2456
--- /dev/null
@@ -0,0 +1,21 @@
+# 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
diff --git a/libpthread/nptl/sysdeps/powerpc/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/powerpc/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..0b81716
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_GPR1] - (_adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/powerpc/pthread_spin_lock.c b/libpthread/nptl/sysdeps/powerpc/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..e2293fd
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#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 --git a/libpthread/nptl/sysdeps/powerpc/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/powerpc/pthread_spin_trylock.c
new file mode 100644 (file)
index 0000000..d8e1dbc
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#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 --git a/libpthread/nptl/sysdeps/powerpc/pthreaddef.h b/libpthread/nptl/sysdeps/powerpc/pthreaddef.h
new file mode 100644 (file)
index 0000000..342c15c
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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
+
+
+/* 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 --git a/libpthread/nptl/sysdeps/powerpc/tcb-offsets.sym b/libpthread/nptl/sysdeps/powerpc/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..3962edb
--- /dev/null
@@ -0,0 +1,16 @@
+#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)  ((ptrdiff_t) THREAD_SELF + offsetof (struct pthread, mem))
+
+
+#if TLS_MULTIPLE_THREADS_IN_TCB
+MULTIPLE_THREADS_OFFSET                thread_offsetof (header.multiple_threads)
+#endif
+PID                            thread_offsetof (pid)
+TID                            thread_offsetof (tid)
diff --git a/libpthread/nptl/sysdeps/powerpc/tls.h b/libpthread/nptl/sysdeps/powerpc/tls.h
new file mode 100644 (file)
index 0000000..a7f6907
--- /dev/null
@@ -0,0 +1,165 @@
+/* Definition for thread-local data handling.  NPTL/PowerPC version.
+   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H 1
+
+# include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+/* 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
+
+/* We use the multiple_threads field in the pthread struct */
+#define TLS_MULTIPLE_THREADS_IN_TCB    1
+
+/* 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     0
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN    __alignof__ (struct pthread)
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE          0
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN         __alignof__ (struct pthread)
+
+/* This is the size we need before TCB.  */
+# define TLS_PRE_TCB_SIZE \
+  (sizeof (struct pthread)                                                   \
+   + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+
+# 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 - 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 + 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))[-1].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))[-1].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, NULL)
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+     (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET))[-1].dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+    ((struct pthread *) (__thread_register \
+                        - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF                                                              \
+  REGISTER (32, 32, PT_THREAD_POINTER * 4,                                           \
+           - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)                              \
+  REGISTER (64, 64, PT_THREAD_POINTER * 8,                                           \
+           - TLS_TCB_OFFSET - 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))
+
+/* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some
+   different value to mean unset l_tls_offset.  */
+# define NO_TLS_OFFSET         -1
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/libpthread/nptl/sysdeps/pthread/bits/libc-lock.h b/libpthread/nptl/sysdeps/pthread/bits/libc-lock.h
new file mode 100644 (file)
index 0000000..795caa7
--- /dev/null
@@ -0,0 +1,568 @@
+/* libc-internal interface for mutex locks.  NPTL version.
+   Copyright (C) 1996-2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _BITS_LIBC_LOCK_H
+#define _BITS_LIBC_LOCK_H 1
+
+#include <pthread.h>
+#define __need_NULL
+#include <stddef.h>
+
+
+/* Fortunately Linux now has a mean to do locking which is realtime
+   safe without the aid of the thread library.  We also need no fancy
+   options like error checking mutexes etc.  We only need simple
+   locks, maybe recursive.  This can be easily and cheaply implemented
+   using futexes.  We will use them everywhere except in ld.so since
+   ld.so might be used on old kernels with a different libc.so.  */
+#ifdef _LIBC
+# include <lowlevellock.h>
+# include <tls.h>
+# include <pthread-functions.h>
+#endif
+
+/* Mutex type.  */
+#if defined _LIBC || defined _IO_MTSAFE_IO
+# if (defined NOT_IN_libc && !defined IS_IN_libpthread) || !defined _LIBC
+typedef pthread_mutex_t __libc_lock_t;
+typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t;
+# else
+typedef int __libc_lock_t;
+typedef struct { int lock; int cnt; void *owner; } __libc_lock_recursive_t;
+# endif
+typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t;
+# ifdef __USE_UNIX98
+typedef pthread_rwlock_t __libc_rwlock_t;
+# else
+typedef struct __libc_rwlock_opaque__ __libc_rwlock_t;
+# endif
+#else
+typedef struct __libc_lock_opaque__ __libc_lock_t;
+typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+typedef struct __libc_rwlock_opaque__ __libc_rwlock_t;
+#endif
+
+/* Type for key to thread-specific data.  */
+typedef pthread_key_t __libc_key_t;
+
+/* Define a lock variable NAME with storage class CLASS.  The lock must be
+   initialized with __libc_lock_init before it can be used (or define it
+   with __libc_lock_define_initialized, below).  Use `extern' for CLASS to
+   declare a lock defined in another module.  In public structure
+   definitions you must use a pointer to the lock structure (i.e., NAME
+   begins with a `*'), because its storage size will not be known outside
+   of libc.  */
+#define __libc_lock_define(CLASS,NAME) \
+  CLASS __libc_lock_t NAME;
+#define __libc_rwlock_define(CLASS,NAME) \
+  CLASS __libc_rwlock_t NAME;
+#define __libc_lock_define_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME;
+#define __rtld_lock_define_recursive(CLASS,NAME) \
+  CLASS __rtld_lock_recursive_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS.
+
+   For the C library we take a deeper look at the initializer.  For
+   this implementation all fields are initialized to zero.  Therefore
+   we don't initialize the variable which allows putting it into the
+   BSS section.  (Except on PA-RISC and other odd architectures, where
+   initialized locks must be set to one due to the lack of normal
+   atomic operations.) */
+
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if LLL_LOCK_INITIALIZER == 0
+#  define __libc_lock_define_initialized(CLASS,NAME) \
+  CLASS __libc_lock_t NAME;
+# else
+#  define __libc_lock_define_initialized(CLASS,NAME) \
+  CLASS __libc_lock_t NAME = LLL_LOCK_INITIALIZER;
+# endif
+#else
+# if __LT_SPINLOCK_INIT == 0
+#  define __libc_lock_define_initialized(CLASS,NAME) \
+  CLASS __libc_lock_t NAME;
+# else
+#  define __libc_lock_define_initialized(CLASS,NAME) \
+  CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER;
+# endif
+#endif
+
+#define __libc_rwlock_define_initialized(CLASS,NAME) \
+  CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER;
+
+/* Define an initialized recursive lock variable NAME with storage
+   class CLASS.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if LLL_LOCK_INITIALIZER == 0
+#  define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME;
+# else
+#  define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+# endif
+# define _LIBC_LOCK_RECURSIVE_INITIALIZER \
+  { LLL_LOCK_INITIALIZER, 0, NULL }
+#else
+# define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+# define _LIBC_LOCK_RECURSIVE_INITIALIZER \
+  {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
+#endif
+
+#define __rtld_lock_define_initialized_recursive(CLASS,NAME) \
+  CLASS __rtld_lock_recursive_t NAME = _RTLD_LOCK_RECURSIVE_INITIALIZER;
+#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
+  {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
+
+#define __rtld_lock_initialize(NAME) \
+  (void) ((NAME) = (__rtld_lock_recursive_t) _RTLD_LOCK_RECURSIVE_INITIALIZER)
+
+/* If we check for a weakly referenced symbol and then perform a
+   normal jump to it te code generated for some platforms in case of
+   PIC is unnecessarily slow.  What would happen is that the function
+   is first referenced as data and then it is called indirectly
+   through the PLT.  We can make this a direct jump.  */
+#ifdef __PIC__
+# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+  (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
+                    _fn != NULL ? (*_fn) ARGS : ELSE; }))
+#else
+# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+  (FUNC != NULL ? FUNC ARGS : ELSE)
+#endif
+
+/* Call thread functions through the function pointer table.  */
+#if defined SHARED && !defined NOT_IN_libc
+# define PTF(NAME) __libc_pthread_functions.ptr_##NAME
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+  (PTF(FUNC) != NULL ? PTF(FUNC) ARGS : ELSE)
+#else
+# define PTF(NAME) NAME
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+  __libc_maybe_call (FUNC, ARGS, ELSE)
+#endif
+
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+   state.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_init(NAME) ((NAME) = LLL_LOCK_INITIALIZER, 0)
+#else
+# define __libc_lock_init(NAME) \
+  __libc_maybe_call (__pthread_mutex_init, (&(NAME), NULL), 0)
+#endif
+#define __libc_rwlock_init(NAME) \
+  __libc_maybe_call (__pthread_rwlock_init, (&(NAME), NULL), 0)
+
+/* Same as last but this time we initialize a recursive mutex.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_init_recursive(NAME) \
+  ((NAME) = (__libc_lock_recursive_t) _LIBC_LOCK_RECURSIVE_INITIALIZER, 0)
+#else
+# define __libc_lock_init_recursive(NAME) \
+  do {                                                                       \
+    if (__pthread_mutex_init != NULL)                                        \
+      {                                                                              \
+       pthread_mutexattr_t __attr;                                           \
+       __pthread_mutexattr_init (&__attr);                                   \
+       __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP);    \
+       __pthread_mutex_init (&(NAME).mutex, &__attr);                        \
+       __pthread_mutexattr_destroy (&__attr);                                \
+      }                                                                              \
+  } while (0)
+#endif
+
+#define __rtld_lock_init_recursive(NAME) \
+  do {                                                                       \
+    if (__pthread_mutex_init != NULL)                                        \
+      {                                                                              \
+       pthread_mutexattr_t __attr;                                           \
+       __pthread_mutexattr_init (&__attr);                                   \
+       __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP);    \
+       __pthread_mutex_init (&(NAME).mutex, &__attr);                        \
+       __pthread_mutexattr_destroy (&__attr);                                \
+      }                                                                              \
+  } while (0)
+
+/* Finalize the named lock variable, which must be locked.  It cannot be
+   used again until __libc_lock_init is called again on it.  This must be
+   called on a lock variable before the containing storage is reused.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_fini(NAME) ((void) 0)
+#else
+# define __libc_lock_fini(NAME) \
+  __libc_maybe_call (__pthread_mutex_destroy, (&(NAME)), 0)
+#endif
+#define __libc_rwlock_fini(NAME) \
+  __libc_maybe_call (__pthread_rwlock_destroy, (&(NAME)), 0)
+
+/* Finalize recursive named lock.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_fini_recursive(NAME) ((void) 0)
+#else
+# define __libc_lock_fini_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_destroy, (&(NAME)), 0)
+#endif
+
+/* Lock the named lock variable.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_lock(NAME) \
+  ({ lll_lock (NAME); 0; })
+#else
+# define __libc_lock_lock(NAME) \
+  __libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0)
+#endif
+#define __libc_rwlock_rdlock(NAME) \
+  __libc_ptf_call (__pthread_rwlock_rdlock, (&(NAME)), 0)
+#define __libc_rwlock_wrlock(NAME) \
+  __libc_ptf_call (__pthread_rwlock_wrlock, (&(NAME)), 0)
+
+/* Lock the recursive named lock variable.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_lock_recursive(NAME) \
+  do {                                                                       \
+    void *self = THREAD_SELF;                                                \
+    if ((NAME).owner != self)                                                \
+      {                                                                              \
+       lll_lock ((NAME).lock);                                               \
+       (NAME).owner = self;                                                  \
+      }                                                                              \
+    ++(NAME).cnt;                                                            \
+  } while (0)
+#else
+# define __libc_lock_lock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+#endif
+
+/* Try to lock the named lock variable.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_trylock(NAME) \
+  lll_trylock (NAME)
+#else
+# define __libc_lock_trylock(NAME) \
+  __libc_maybe_call (__pthread_mutex_trylock, (&(NAME)), 0)
+#endif
+#define __libc_rwlock_tryrdlock(NAME) \
+  __libc_maybe_call (__pthread_rwlock_tryrdlock, (&(NAME)), 0)
+#define __libc_rwlock_trywrlock(NAME) \
+  __libc_maybe_call (__pthread_rwlock_trywrlock, (&(NAME)), 0)
+
+/* Try to lock the recursive named lock variable.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_trylock_recursive(NAME) \
+  ({                                                                         \
+    int result = 0;                                                          \
+    void *self = THREAD_SELF;                                                \
+    if ((NAME).owner != self)                                                \
+      {                                                                              \
+       if (lll_trylock ((NAME).lock) == 0)                                   \
+         {                                                                   \
+           (NAME).owner = self;                                              \
+           (NAME).cnt = 1;                                                   \
+         }                                                                   \
+       else                                                                  \
+         result = EBUSY;                                                     \
+      }                                                                              \
+    else                                                                     \
+      ++(NAME).cnt;                                                          \
+    result;                                                                  \
+  })
+#else
+# define __libc_lock_trylock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_trylock, (&(NAME)), 0)
+#endif
+
+#define __rtld_lock_trylock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
+
+/* Unlock the named lock variable.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define __libc_lock_unlock(NAME) \
+  lll_unlock (NAME)
+#else
+# define __libc_lock_unlock(NAME) \
+  __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
+#endif
+#define __libc_rwlock_unlock(NAME) \
+  __libc_ptf_call (__pthread_rwlock_unlock, (&(NAME)), 0)
+
+/* Unlock the recursive named lock variable.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+/* We do no error checking here.  */
+# define __libc_lock_unlock_recursive(NAME) \
+  do {                                                                       \
+    if (--(NAME).cnt == 0)                                                   \
+      {                                                                              \
+       (NAME).owner = NULL;                                                  \
+       lll_unlock ((NAME).lock);                                             \
+      }                                                                              \
+  } while (0)
+#else
+# define __libc_lock_unlock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
+#endif
+
+#if defined _LIBC && defined SHARED
+# define __rtld_lock_default_lock_recursive(lock) \
+  ++((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_default_unlock_recursive(lock) \
+  --((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_lock_recursive(NAME) \
+  GL(dl_rtld_lock_recursive) (&(NAME).mutex)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+  GL(dl_rtld_unlock_recursive) (&(NAME).mutex)
+#else
+# define __rtld_lock_lock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+#endif
+
+/* Define once control variable.  */
+#if PTHREAD_ONCE_INIT == 0
+/* Special case for static variables where we can avoid the initialization
+   if it is zero.  */
+# define __libc_once_define(CLASS, NAME) \
+  CLASS pthread_once_t NAME
+#else
+# define __libc_once_define(CLASS, NAME) \
+  CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT
+#endif
+
+/* Call handler iff the first call.  */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+  do {                                                                       \
+    if (PTF(__pthread_once) != NULL)                                         \
+      PTF(__pthread_once) (&(ONCE_CONTROL), INIT_FUNCTION);                  \
+    else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) {                          \
+      INIT_FUNCTION ();                                                              \
+      (ONCE_CONTROL) |= 2;                                                   \
+    }                                                                        \
+  } while (0)
+
+
+/* Note that for I/O cleanup handling we are using the old-style
+   cancel handling.  It does not have to be integrated with C++ snce
+   no C++ code is called in the middle.  The old-style handling is
+   faster and the support is not going away.  */
+extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
+                                   void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
+                                  int execute);
+extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
+                                         void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
+                                          int execute);
+
+/* Start critical region with cleanup.  */
+#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
+  { struct _pthread_cleanup_buffer _buffer;                                  \
+    int _avail;                                                                      \
+    if (DOIT) {                                                                      \
+      _avail = PTF(_pthread_cleanup_push_defer) != NULL;                     \
+      if (_avail) {                                                          \
+       PTF(_pthread_cleanup_push_defer) (&_buffer, FCT, ARG);                \
+      } else {                                                               \
+       _buffer.__routine = (FCT);                                            \
+       _buffer.__arg = (ARG);                                                \
+      }                                                                              \
+    } else {                                                                 \
+      _avail = 0;                                                            \
+    }
+
+/* End critical region with cleanup.  */
+#define __libc_cleanup_region_end(DOIT) \
+    if (_avail) {                                                            \
+      PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT);                    \
+    } else if (DOIT)                                                         \
+      _buffer.__routine (_buffer.__arg);                                     \
+  }
+
+/* Sometimes we have to exit the block in the middle.  */
+#define __libc_cleanup_end(DOIT) \
+    if (_avail) {                                                            \
+      PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT);                    \
+    } else if (DOIT)                                                         \
+      _buffer.__routine (_buffer.__arg)
+
+
+/* Normal cleanup handling, based on C cleanup attribute.  */
+extern __inline void
+__libc_cleanup_routine (struct __pthread_cleanup_frame *f)
+{
+  if (f->__do_it)
+    f->__cancel_routine (f->__cancel_arg);
+}
+
+#define __libc_cleanup_push(fct, arg) \
+  do {                                                                       \
+    struct __pthread_cleanup_frame __clframe                                 \
+      __attribute__ ((__cleanup__ (__libc_cleanup_routine)))                 \
+      = { .__cancel_routine = (fct), .__cancel_arg = (arg),                  \
+          .__do_it = 1 };
+
+#define __libc_cleanup_pop(execute) \
+    __clframe.__do_it = (execute);                                           \
+  } while (0)
+
+
+/* Create thread-specific key.  */
+#define __libc_key_create(KEY, DESTRUCTOR) \
+  __libc_ptf_call (__pthread_key_create, (KEY, DESTRUCTOR), 1)
+
+/* Get thread-specific data.  */
+#define __libc_getspecific(KEY) \
+  __libc_ptf_call (__pthread_getspecific, (KEY), NULL)
+
+/* Set thread-specific data.  */
+#define __libc_setspecific(KEY, VALUE) \
+  __libc_ptf_call (__pthread_setspecific, (KEY, VALUE), 0)
+
+
+/* Register handlers to execute before and after `fork'.  Note that the
+   last parameter is NULL.  The handlers registered by the libc are
+   never removed so this is OK.  */
+#define __libc_atfork(PREPARE, PARENT, CHILD) \
+  __register_atfork (PREPARE, PARENT, CHILD, NULL)
+extern int __register_atfork (void (*__prepare) (void),
+                             void (*__parent) (void),
+                             void (*__child) (void),
+                             void *__dso_handle);
+
+/* Functions that are used by this file and are internal to the GNU C
+   library.  */
+
+extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
+                                __const pthread_mutexattr_t *__mutex_attr);
+
+extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr,
+                                       int __kind);
+
+#ifdef __USE_UNIX98
+extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock,
+                                 __const pthread_rwlockattr_t *__attr);
+
+extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
+#endif
+
+extern int __pthread_key_create (pthread_key_t *__key,
+                                void (*__destr_function) (void *));
+
+extern int __pthread_setspecific (pthread_key_t __key,
+                                 __const void *__pointer);
+
+extern void *__pthread_getspecific (pthread_key_t __key);
+
+extern int __pthread_once (pthread_once_t *__once_control,
+                          void (*__init_routine) (void));
+
+extern int __pthread_atfork (void (*__prepare) (void),
+                            void (*__parent) (void),
+                            void (*__child) (void));
+
+
+
+/* Make the pthread functions weak so that we can elide them from
+   single-threaded processes.  */
+#ifndef __NO_WEAK_PTHREAD_ALIASES
+# ifdef weak_extern
+#  if _LIBC
+#   include <bp-sym.h>
+#  else
+#   define BP_SYM (sym) sym
+#  endif
+weak_extern (BP_SYM (__pthread_mutex_init))
+weak_extern (BP_SYM (__pthread_mutex_destroy))
+weak_extern (BP_SYM (__pthread_mutex_lock))
+weak_extern (BP_SYM (__pthread_mutex_trylock))
+weak_extern (BP_SYM (__pthread_mutex_unlock))
+weak_extern (BP_SYM (__pthread_mutexattr_init))
+weak_extern (BP_SYM (__pthread_mutexattr_destroy))
+weak_extern (BP_SYM (__pthread_mutexattr_settype))
+weak_extern (BP_SYM (__pthread_rwlock_init))
+weak_extern (BP_SYM (__pthread_rwlock_destroy))
+weak_extern (BP_SYM (__pthread_rwlock_rdlock))
+weak_extern (BP_SYM (__pthread_rwlock_tryrdlock))
+weak_extern (BP_SYM (__pthread_rwlock_wrlock))
+weak_extern (BP_SYM (__pthread_rwlock_trywrlock))
+weak_extern (BP_SYM (__pthread_rwlock_unlock))
+weak_extern (BP_SYM (__pthread_key_create))
+weak_extern (BP_SYM (__pthread_setspecific))
+weak_extern (BP_SYM (__pthread_getspecific))
+weak_extern (BP_SYM (__pthread_once))
+weak_extern (__pthread_initialize)
+weak_extern (__pthread_atfork)
+weak_extern (BP_SYM (_pthread_cleanup_push_defer))
+weak_extern (BP_SYM (_pthread_cleanup_pop_restore))
+weak_extern (BP_SYM (pthread_setcancelstate))
+# else
+#  pragma weak __pthread_mutex_init
+#  pragma weak __pthread_mutex_destroy
+#  pragma weak __pthread_mutex_lock
+#  pragma weak __pthread_mutex_trylock
+#  pragma weak __pthread_mutex_unlock
+#  pragma weak __pthread_mutexattr_init
+#  pragma weak __pthread_mutexattr_destroy
+#  pragma weak __pthread_mutexattr_settype
+#  pragma weak __pthread_rwlock_destroy
+#  pragma weak __pthread_rwlock_rdlock
+#  pragma weak __pthread_rwlock_tryrdlock
+#  pragma weak __pthread_rwlock_wrlock
+#  pragma weak __pthread_rwlock_trywrlock
+#  pragma weak __pthread_rwlock_unlock
+#  pragma weak __pthread_key_create
+#  pragma weak __pthread_setspecific
+#  pragma weak __pthread_getspecific
+#  pragma weak __pthread_once
+#  pragma weak __pthread_initialize
+#  pragma weak __pthread_atfork
+#  pragma weak _pthread_cleanup_push_defer
+#  pragma weak _pthread_cleanup_pop_restore
+#  pragma weak pthread_setcancelstate
+# endif
+#endif
+
+#endif /* bits/libc-lock.h */
diff --git a/libpthread/nptl/sysdeps/pthread/bits/sigthread.h b/libpthread/nptl/sysdeps/pthread/bits/sigthread.h
new file mode 100644 (file)
index 0000000..960bde1
--- /dev/null
@@ -0,0 +1,38 @@
+/* Signal handling function for threaded programs.
+   Copyright (C) 1998, 1999, 2000, 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _BITS_SIGTHREAD_H
+#define _BITS_SIGTHREAD_H      1
+
+#if !defined _SIGNAL_H && !defined _PTHREAD_H
+# error "Never include this file directly.  Use <pthread.h> instead"
+#endif
+
+/* Functions for handling signals. */
+
+/* Modify the signal mask for the calling thread.  The arguments have
+   the same meaning as for sigprocmask(2). */
+extern int pthread_sigmask (int __how,
+                           __const __sigset_t *__restrict __newmask,
+                           __sigset_t *__restrict __oldmask)__THROW;
+
+/* Send signal SIGNO to the given thread. */
+extern int pthread_kill (pthread_t __threadid, int __signo) __THROW;
+
+#endif /* bits/sigthread.h */
diff --git a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
new file mode 100644 (file)
index 0000000..cd64bc3
--- /dev/null
@@ -0,0 +1,105 @@
+/* Thread package specific definitions of stream lock type.  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.
+
+   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_STDIO_LOCK_H
+#define _BITS_STDIO_LOCK_H 1
+
+#include <bits/libc-lock.h>
+#include <lowlevellock.h>
+
+
+/* The locking here is very inexpensive, even for inlining.  */
+#define _IO_lock_inexpensive   1
+
+typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
+
+#define _IO_lock_initializer { LLL_LOCK_INITIALIZER, 0, NULL }
+
+#define _IO_lock_init(_name) \
+  ((_name) = (_IO_lock_t) _IO_lock_initializer , 0)
+
+#define _IO_lock_fini(_name) \
+  ((void) 0)
+
+#define _IO_lock_lock(_name) \
+  do {                                                                       \
+    void *__self = THREAD_SELF;                                                      \
+    if ((_name).owner != __self)                                             \
+      {                                                                              \
+        lll_lock ((_name).lock);                                             \
+        (_name).owner = __self;                                                      \
+      }                                                                              \
+    ++(_name).cnt;                                                           \
+  } while (0)
+
+#define _IO_lock_trylock(_name) \
+  ({                                                                         \
+    int __result = 0;                                                        \
+    void *__self = THREAD_SELF;                                                      \
+    if ((_name).owner != __self)                                             \
+      {                                                                              \
+        if (lll_trylock ((_name).lock) == 0)                                 \
+          {                                                                  \
+            (_name).owner = __self;                                          \
+            (_name).cnt = 1;                                                 \
+          }                                                                  \
+        else                                                                 \
+          __result = EBUSY;                                                  \
+      }                                                                              \
+    else                                                                     \
+      ++(_name).cnt;                                                         \
+    __result;                                                                \
+  })
+
+#define _IO_lock_unlock(_name) \
+  do {                                                                       \
+    if (--(_name).cnt == 0)                                                  \
+      {                                                                              \
+        (_name).owner = NULL;                                                \
+        lll_unlock ((_name).lock);                                           \
+      }                                                                              \
+  } while (0)
+
+
+
+#define _IO_cleanup_region_start(_fct, _fp) \
+  __libc_cleanup_region_start (((_fp)->_flags & _IO_USER_LOCK) == 0, _fct, _fp)
+#define _IO_cleanup_region_start_noarg(_fct) \
+  __libc_cleanup_region_start (1, _fct, NULL)
+#define _IO_cleanup_region_end(_doit) \
+  __libc_cleanup_region_end (_doit)
+
+#if defined _LIBC && !defined NOT_IN_libc
+
+# ifdef __EXCEPTIONS
+#  define _IO_acquire_lock(_fp) \
+  do {                                                                       \
+    _IO_FILE *_IO_acquire_lock_file                                          \
+       __attribute__((cleanup (_IO_acquire_lock_fct)))                       \
+       = (_fp);                                                              \
+    _IO_flockfile (_IO_acquire_lock_file);
+
+# else
+#  define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled
+# endif
+# define _IO_release_lock(_fp) ; } while (0)
+
+#endif
+
+#endif /* bits/stdio-lock.h */
diff --git a/libpthread/nptl/sysdeps/sh/Makefile b/libpthread/nptl/sysdeps/sh/Makefile
new file mode 100644 (file)
index 0000000..81bddf6
--- /dev/null
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/sh/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..cf6d25f
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(jmpbuf, address, adj) \
+  ((uintptr_t) (address) - (adj) < (uintptr_t) (jmpbuf)[0].__regs[7] - (adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_init.c b/libpthread/nptl/sysdeps/sh/pthread_spin_init.c
new file mode 100644 (file)
index 0000000..0a47981
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 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.  */
+
+/* Not needed.  pthread_spin_init is an alias for pthread_spin_unlock.  */
diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_lock.c b/libpthread/nptl/sysdeps/sh/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..e732641
--- /dev/null
@@ -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 "pthreadP.h"
+
+int
+pthread_spin_lock (lock)
+     pthread_spinlock_t *lock;
+{
+  unsigned int val;
+
+  do
+    asm volatile ("tas.b @%1; movt %0"
+                 : "=&r" (val)
+                 : "r" (lock)
+                 : "memory");
+  while (val == 0);
+
+  return 0;
+}
diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/sh/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..18112ba
--- /dev/null
@@ -0,0 +1,32 @@
+/* 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 <pthread-errnos.h>
+
+       .globl  pthread_spin_trylock
+       .type   pthread_spin_trylock,@function
+       .align  5
+pthread_spin_trylock:
+       tas.b   @r4
+       bf/s    1f
+       mov     #EBUSY, r0
+       mov     #0, r0
+1:
+       rts
+        nop
+       .size   pthread_spin_trylock,.-pthread_spin_trylock
diff --git a/libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/sh/pthread_spin_unlock.S
new file mode 100644 (file)
index 0000000..c77acaf
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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.  */
+
+       .globl  pthread_spin_unlock
+       .type   pthread_spin_unlock,@function
+       .align  5
+pthread_spin_unlock:
+       mov     #0,r0
+       rts
+        mov.l  r0,@r4
+       .size   pthread_spin_unlock,.-pthread_spin_unlock
+
+       /* The implementation of pthread_spin_init is identical.  */
+       .globl  pthread_spin_init
+pthread_spin_init = pthread_spin_unlock
diff --git a/libpthread/nptl/sysdeps/sh/pthreaddef.h b/libpthread/nptl/sysdeps/sh/pthreaddef.h
new file mode 100644 (file)
index 0000000..70c6a85
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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.h>
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  */
+#define STACK_ALIGN            8
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK     2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT          8
+
+
+/* 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) \
+  while (1) {                                                                \
+    if (__builtin_constant_p (val) && (val) == 0)                            \
+      asm volatile ("mov #0,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD  \
+                  :: "i" (__NR_exit));  \
+    else                                                                     \
+      asm volatile ("mov %1,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD  \
+                   :: "i" (__NR_exit), "r" (val));                           \
+  }
diff --git a/libpthread/nptl/sysdeps/sh/tcb-offsets.sym b/libpthread/nptl/sysdeps/sh/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..539789a
--- /dev/null
@@ -0,0 +1,11 @@
+#include <sysdep.h>
+#include <tls.h>
+
+RESULT                 offsetof (struct pthread, result)
+TID                    offsetof (struct pthread, tid)
+PID                    offsetof (struct pthread, pid)
+CANCELHANDLING         offsetof (struct pthread, cancelhandling)
+CLEANUP_JMP_BUF                offsetof (struct pthread, cleanup_jmp_buf)
+MULTIPLE_THREADS_OFFSET        offsetof (struct pthread, header.multiple_threads)
+TLS_PRE_TCB_SIZE       sizeof (struct pthread)
+MUTEX_FUTEX            offsetof (pthread_mutex_t, __data.__lock)
diff --git a/libpthread/nptl/sysdeps/sh/tls.h b/libpthread/nptl/sysdeps/sh/tls.h
new file mode 100644 (file)
index 0000000..e883bae
--- /dev/null
@@ -0,0 +1,145 @@
+/* Definition for thread-local data handling.  NPTL/SH version.
+   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H
+
+# include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } 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 /* __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>
+
+/* 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 TLS blocks start right after the TCB.  */
+# 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(tcbp, dtvp) \
+  ((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) \
+  ({ tcbhead_t *__tcbp;                                                              \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                        \
+     __tcbp->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) \
+  ({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; })
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  ({ tcbhead_t *__tcbp;                                                              \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                        \
+     __tcbp->dtv;})
+
+/* Return the thread descriptor for the current thread.
+   The contained asm must *not* be marked volatile since otherwise
+   assignments like
+        struct pthread *self = thread_self();
+   do not get optimized away.  */
+# define THREAD_SELF \
+  ({ struct pthread *__self;                                                 \
+     __asm ("stc gbr,%0" : "=r" (__self));                                   \
+     __self - 1;})
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  REGISTER (32, 32, REG_GBR * 4, -sizeof (struct pthread))
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) (descr->member)
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) (descr->member[idx])
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+    descr->member = (value)
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+    descr->member[idx] = (value)
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/libpthread/nptl/sysdeps/sparc/Makefile b/libpthread/nptl/sysdeps/sparc/Makefile
new file mode 100644 (file)
index 0000000..81bddf6
--- /dev/null
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/libpthread/nptl/sysdeps/sparc/sparc32/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/sparc/sparc32/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..5cef8b1
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/sparc/sparc32/pthread_spin_lock.c b/libpthread/nptl/sysdeps/sparc/sparc32/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..d3c6e30
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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 (pthread_spinlock_t *lock)
+{
+  __asm __volatile
+    ("1: ldstub [%0], %%g2\n"
+     "   orcc   %%g2, 0x0, %%g0\n"
+     "   bne,a  2f\n"
+     "   ldub   [%0], %%g2\n"
+     ".subsection 2\n"
+     "2: orcc   %%g2, 0x0, %%g0\n"
+     "   bne,a  2b\n"
+     "   ldub   [%0], %%g2\n"
+     "   b,a    1b\n"
+     ".previous"
+     : /* no outputs */
+     : "r" (lock)
+     : "g2", "memory", "cc");
+  return 0;
+}
diff --git a/libpthread/nptl/sysdeps/sparc/sparc32/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/sparc/sparc32/pthread_spin_trylock.c
new file mode 100644 (file)
index 0000000..bcc3158
--- /dev/null
@@ -0,0 +1,29 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int res;
+  __asm __volatile ("ldstub [%1], %0" : "=r" (res) : "r" (lock) : "memory");
+  return res == 0 ? 0 : EBUSY;
+}
diff --git a/libpthread/nptl/sysdeps/sparc/sparc32/pthreaddef.h b/libpthread/nptl/sysdeps/sparc/sparc32/pthreaddef.h
new file mode 100644 (file)
index 0000000..9908df9
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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        (2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  */
+#define STACK_ALIGN            16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK     2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT          16
+
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME  (stack_pointer + (2 * 64))
+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/libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_lock.c b/libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..8880f53
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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 (pthread_spinlock_t *lock)
+{
+  __asm __volatile
+    ("1: ldstub  [%0], %%g2\n"
+     "   brnz,pn %%g2, 2f\n"
+     "    membar #StoreLoad | #StoreStore\n"
+     ".subsection 2\n"
+     "2: ldub    [%0], %%g2\n"
+     "   brnz,pt %%g2, 2b\n"
+     "    membar #LoadLoad\n"
+     "   b,a,pt  %%xcc, 1b\n"
+     ".previous"
+     : /* no outputs */
+     : "r" (lock)
+     : "g2", "memory");
+  return 0;
+}
diff --git a/libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_trylock.c
new file mode 100644 (file)
index 0000000..3b20a21
--- /dev/null
@@ -0,0 +1 @@
+#include <sparc64/pthread_spin_trylock.c>
diff --git a/libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_unlock.c b/libpthread/nptl/sysdeps/sparc/sparc32/sparcv9/pthread_spin_unlock.c
new file mode 100644 (file)
index 0000000..482cbe3
--- /dev/null
@@ -0,0 +1 @@
+#include <sparc64/pthread_spin_unlock.c>
diff --git a/libpthread/nptl/sysdeps/sparc/sparc64/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/sparc/sparc64/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..77321aa
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by David S. Miller <davem@davemloft.net>, 2005.
+
+   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 <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[0].uc_mcontext.mc_fp - (_adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_lock.c b/libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..77171d9
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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 (pthread_spinlock_t *lock)
+{
+  __asm __volatile
+    ("1: ldstub  [%0], %%g5\n"
+     "   brnz,pn %%g5, 2f\n"
+     "    membar #StoreLoad | #StoreStore\n"
+     ".subsection 2\n"
+     "2: ldub    [%0], %%g5\n"
+     "   brnz,pt %%g5, 2b\n"
+     "    membar #LoadLoad\n"
+     "   b,a,pt  %%xcc, 1b\n"
+     ".previous"
+     : /* no outputs */
+     : "r" (lock)
+     : "g5", "memory");
+  return 0;
+}
diff --git a/libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_trylock.c
new file mode 100644 (file)
index 0000000..2bda809
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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 (pthread_spinlock_t *lock)
+{
+  int res;
+  __asm __volatile
+    ("ldstub [%1], %0\n"
+     "membar #StoreLoad | #StoreStore"
+     : "=r" (res)
+     : "r" (lock)
+     : "memory");
+  return res == 0 ? 0 : EBUSY;
+}
diff --git a/libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_unlock.c b/libpthread/nptl/sysdeps/sparc/sparc64/pthread_spin_unlock.c
new file mode 100644 (file)
index 0000000..7037675
--- /dev/null
@@ -0,0 +1,30 @@
+/* pthread_spin_unlock -- unlock a spin lock.  Generic version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "pthreadP.h"
+#include <atomic.h>
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  __asm __volatile ("membar #StoreStore | #LoadStore");
+  *lock = 0;
+  return 0;
+}
diff --git a/libpthread/nptl/sysdeps/sparc/sparc64/pthreaddef.h b/libpthread/nptl/sysdeps/sparc/sparc64/pthreaddef.h
new file mode 100644 (file)
index 0000000..ec76512
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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.  */
+#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
+
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME  (stack_pointer + (2 * 128))
+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/libpthread/nptl/sysdeps/sparc/tcb-offsets.sym b/libpthread/nptl/sysdeps/sparc/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..237f975
--- /dev/null
@@ -0,0 +1,6 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET                offsetof (tcbhead_t, multiple_threads)
+PID                            offsetof (struct pthread, pid)
+TID                            offsetof (struct pthread, tid)
diff --git a/libpthread/nptl/sysdeps/sparc/tls.h b/libpthread/nptl/sysdeps/sparc/tls.h
new file mode 100644 (file)
index 0000000..8f54a0b
--- /dev/null
@@ -0,0 +1,129 @@
+/* Definitions for thread-local data handling.  NPTL/sparc version.
+   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H
+
+#include <dl-sysdep.h>
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <list.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+typedef struct
+{
+  void *tcb;           /* Pointer to the TCB.  Not necessary the
+                          thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;
+  int multiple_threads;
+} tcbhead_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>
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+register struct pthread *__thread_self __asm__("%g7");
+
+/* 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 (struct pthread)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+# define TLS_TCB_AT_TP 1
+
+/* 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.  */
+# define TLS_INIT_TP(descr, secondcall) \
+  (__thread_self = (__typeof (__thread_self)) (descr), 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
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF_INCLUDE <sys/ucontext.h>
+# define DB_THREAD_SELF \
+  REGISTER (32, 32, REG_G7 * 4, 0) REGISTER (64, 64, REG_G7 * 8, 0)
+
+/* 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/libpthread/nptl/sysdeps/x86_64/Makefile b/libpthread/nptl/sysdeps/x86_64/Makefile
new file mode 100644 (file)
index 0000000..6e24a26
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; 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)
+# P4s have problems with 4M aliasing.  We disturb the allocation of stacks
+# just enough so the subsequent allocations do not use stack address
+# (mod 4M) == 0.
+CFLAGS-pthread_create.c += -DMULTI_PAGE_ALIASING=65536
+endif
diff --git a/libpthread/nptl/sysdeps/x86_64/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/x86_64/jmpbuf-unwind.h
new file mode 100644 (file)
index 0000000..345ed55
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_RSP] - (_adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/x86_64/pthread_spin_init.c b/libpthread/nptl/sysdeps/x86_64/pthread_spin_init.c
new file mode 100644 (file)
index 0000000..5569620
--- /dev/null
@@ -0,0 +1 @@
+#include "../i386/pthread_spin_init.c"
diff --git a/libpthread/nptl/sysdeps/x86_64/pthread_spin_lock.c b/libpthread/nptl/sysdeps/x86_64/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..7cf0e0e
--- /dev/null
@@ -0,0 +1 @@
+#include "../i386/pthread_spin_lock.c"
diff --git a/libpthread/nptl/sysdeps/x86_64/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/x86_64/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..9b51335
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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.  */
+
+#include <pthread-errnos.h>
+
+
+#ifdef UP
+# define LOCK
+#else
+# define LOCK lock
+#endif
+
+       .globl  pthread_spin_trylock
+       .type   pthread_spin_trylock,@function
+       .align  16
+pthread_spin_trylock:
+       movl    $1, %eax
+       xorl    %ecx, %ecx
+       LOCK
+       cmpxchgl %ecx, (%rdi)
+       movl    $EBUSY, %eax
+       cmovel  %ecx, %eax
+       retq
+       .size   pthread_spin_trylock,.-pthread_spin_trylock
diff --git a/libpthread/nptl/sysdeps/x86_64/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/x86_64/pthread_spin_unlock.S
new file mode 100644 (file)
index 0000000..d3e13bd
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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.  */
+
+       .globl  pthread_spin_unlock
+       .type   pthread_spin_unlock,@function
+       .align  16
+pthread_spin_unlock:
+       movl    $1, (%rdi)
+       xorl    %eax, %eax
+       retq
+       .size   pthread_spin_unlock,.-pthread_spin_unlock
+
+       /* The implementation of pthread_spin_init is identical.  */
+       .globl  pthread_spin_init
+pthread_spin_init = pthread_spin_unlock
diff --git a/libpthread/nptl/sysdeps/x86_64/pthreaddef.h b/libpthread/nptl/sysdeps/x86_64/pthreaddef.h
new file mode 100644 (file)
index 0000000..27896a4
--- /dev/null
@@ -0,0 +1,54 @@
+/* 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.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  SSE requires 16
+   bytes.  */
+#define STACK_ALIGN            16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK     2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT          16
+
+
+/* Location of current stack frame.  The frame pointer is not usable.  */
+#define CURRENT_STACK_FRAME \
+  ({ char *frame; asm ("movq %%rsp, %0" : "=r" (frame)); frame; })
+
+
+/* We prefer to have the stack allocated in the low 4GB since this
+   allows faster context switches.  */
+#define ARCH_MAP_FLAGS MAP_32BIT
+
+/* If it is not possible to allocate memory there retry without that
+   flag.  */
+#define ARCH_RETRY_MMAP(size) \
+  mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,                              \
+       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
+
+
+/* XXX Until we have a better place keep the definitions here.  */
+
+/* While there is no such syscall.  */
+#define __exit_thread_inline(val) \
+  asm volatile ("syscall" :: "a" (__NR_exit), "D" (val))
diff --git a/libpthread/nptl/sysdeps/x86_64/tcb-offsets.sym b/libpthread/nptl/sysdeps/x86_64/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..8118d2d
--- /dev/null
@@ -0,0 +1,12 @@
+#include <sysdep.h>
+#include <tls.h>
+
+RESULT                 offsetof (struct pthread, result)
+TID                    offsetof (struct pthread, tid)
+PID                    offsetof (struct pthread, pid)
+CANCELHANDLING         offsetof (struct pthread, cancelhandling)
+CLEANUP_JMP_BUF                offsetof (struct pthread, cleanup_jmp_buf)
+CLEANUP                        offsetof (struct pthread, cleanup)
+CLEANUP_PREV           offsetof (struct _pthread_cleanup_buffer, __prev)
+MUTEX_FUTEX            offsetof (pthread_mutex_t, __data.__lock)
+MULTIPLE_THREADS_OFFSET        offsetof (tcbhead_t, multiple_threads)
diff --git a/libpthread/nptl/sysdeps/x86_64/tls.h b/libpthread/nptl/sysdeps/x86_64/tls.h
new file mode 100644 (file)
index 0000000..12da9dc
--- /dev/null
@@ -0,0 +1,323 @@
+/* Definition for thread-local data handling.  nptl/x86_64 version.
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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 <asm/prctl.h> /* For ARCH_SET_FS.  */
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+# include <stdlib.h>
+
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+
+typedef struct
+{
+  void *tcb;           /* Pointer to the TCB.  Not necessary the
+                          thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;          /* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+
+#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>
+
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+#ifndef LOCK_PREFIX
+# ifdef UP
+#  define LOCK_PREFIX  /* nothing */
+# else
+#  define LOCK_PREFIX  "lock;"
+# endif
+#endif
+
+/* 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 (struct pthread)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+# define TLS_TCB_AT_TP 1
+
+
+/* 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(dtvp) \
+  ({ struct pthread *__pd;                                                   \
+     THREAD_SETMEM (__pd, header.dtv, (dtvp)); })
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(descr) \
+  (((tcbhead_t *) (descr))->dtv)
+
+
+/* Macros to load from and store into segment registers.  */
+# define TLS_GET_FS() \
+  ({ int __seg; __asm ("movl %%fs, %0" : "=q" (__seg)); __seg; })
+# define TLS_SET_FS(val) \
+  __asm ("movl %0, %%fs" :: "q" (val))
+
+
+/* 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.
+
+   We have to make the syscall for both uses of the macro since the
+   address might be (and probably is) different.  */
+# define TLS_INIT_TP(thrdescr, secondcall) \
+  ({ void *_thrdescr = (thrdescr);                                           \
+     tcbhead_t *_head = _thrdescr;                                           \
+     int _result;                                                            \
+                                                                             \
+     _head->tcb = _thrdescr;                                                 \
+     /* For now the thread descriptor is at the same address.  */            \
+     _head->self = _thrdescr;                                                \
+                                                                             \
+     /* It is a simple syscall to set the %fs value for the thread.  */              \
+     asm volatile ("syscall"                                                 \
+                  : "=a" (_result)                                           \
+                  : "0" ((unsigned long int) __NR_arch_prctl),               \
+                    "D" ((unsigned long int) ARCH_SET_FS),                   \
+                    "S" (_thrdescr)                                          \
+                  : "memory", "cc", "r11", "cx");                            \
+                                                                             \
+    _result ? "cannot set %fs base address for thread-local storage" : 0;     \
+  })
+
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  ({ struct pthread *__pd;                                                   \
+     THREAD_GETMEM (__pd, header.dtv); })
+
+
+/* Return the thread descriptor for the current thread.
+
+   The contained asm must *not* be marked volatile since otherwise
+   assignments like
+        pthread_descr self = thread_self();
+   do not get optimized away.  */
+# define THREAD_SELF \
+  ({ struct pthread *__self;                                                 \
+     asm ("movq %%fs:%c1,%q0" : "=r" (__self)                                \
+         : "i" (offsetof (struct pthread, header.self)));                    \
+     __self;})
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF_INCLUDE  <sys/reg.h> /* For the FS constant.  */
+# define DB_THREAD_SELF CONST_THREAD_AREA (64, FS)
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) \
+  ({ __typeof (descr->member) __value;                                       \
+     if (sizeof (__value) == 1)                                                      \
+       asm volatile ("movb %%fs:%P2,%b0"                                     \
+                    : "=q" (__value)                                         \
+                    : "0" (0), "i" (offsetof (struct pthread, member)));     \
+     else if (sizeof (__value) == 4)                                         \
+       asm volatile ("movl %%fs:%P1,%0"                                              \
+                    : "=r" (__value)                                         \
+                    : "i" (offsetof (struct pthread, member)));              \
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (__value) != 8)                                           \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile ("movq %%fs:%P1,%q0"                                    \
+                      : "=r" (__value)                                       \
+                      : "i" (offsetof (struct pthread, member)));            \
+       }                                                                     \
+     __value; })
+
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) \
+  ({ __typeof (descr->member[0]) __value;                                    \
+     if (sizeof (__value) == 1)                                                      \
+       asm volatile ("movb %%fs:%P2(%q3),%b0"                                \
+                    : "=q" (__value)                                         \
+                    : "0" (0), "i" (offsetof (struct pthread, member[0])),   \
+                      "r" (idx));                                            \
+     else if (sizeof (__value) == 4)                                         \
+       asm volatile ("movl %%fs:%P1(,%q2,4),%0"                                      \
+                    : "=r" (__value)                                         \
+                    : "i" (offsetof (struct pthread, member[0])), "r" (idx));\
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (__value) != 8)                                           \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile ("movq %%fs:%P1(,%q2,8),%q0"                            \
+                      : "=r" (__value)                                       \
+                      : "i" (offsetof (struct pthread, member[0])),          \
+                        "r" (idx));                                          \
+       }                                                                     \
+     __value; })
+
+
+/* Loading addresses of objects on x86-64 needs to be treated special
+   when generating PIC code.  */
+#ifdef __pic__
+# define IMM_MODE "nr"
+#else
+# define IMM_MODE "ir"
+#endif
+
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM(descr, member, value) \
+  ({ if (sizeof (descr->member) == 1)                                        \
+       asm volatile ("movb %b0,%%fs:%P1" :                                   \
+                    : "iq" (value),                                          \
+                      "i" (offsetof (struct pthread, member)));              \
+     else if (sizeof (descr->member) == 4)                                   \
+       asm volatile ("movl %0,%%fs:%P1" :                                    \
+                    : IMM_MODE (value),                                      \
+                      "i" (offsetof (struct pthread, member)));              \
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (descr->member) != 8)                                     \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile ("movq %q0,%%fs:%P1" :                                  \
+                      : IMM_MODE ((unsigned long int) value),                \
+                        "i" (offsetof (struct pthread, member)));            \
+       }})
+
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+  ({ if (sizeof (descr->member[0]) == 1)                                     \
+       asm volatile ("movb %b0,%%fs:%P1(%q2)" :                                      \
+                    : "iq" (value),                                          \
+                      "i" (offsetof (struct pthread, member[0])),            \
+                      "r" (idx));                                            \
+     else if (sizeof (descr->member[0]) == 4)                                \
+       asm volatile ("movl %0,%%fs:%P1(,%q2,4)" :                            \
+                    : IMM_MODE (value),                                      \
+                      "i" (offsetof (struct pthread, member[0])),            \
+                      "r" (idx));                                            \
+     else                                                                    \
+       {                                                                     \
+        if (sizeof (descr->member[0]) != 8)                                  \
+          /* There should not be any value with a size other than 1,         \
+             4 or 8.  */                                                     \
+          abort ();                                                          \
+                                                                             \
+        asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" :                          \
+                      : IMM_MODE ((unsigned long int) value),                \
+                        "i" (offsetof (struct pthread, member[0])),          \
+                        "r" (idx));                                          \
+       }})
+
+
+/* Atomic compare and exchange on TLS, returning old value.  */
+#define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
+  ({ __typeof (descr->member) __ret;                                         \
+     __typeof (oldval) __old = (oldval);                                     \
+     if (sizeof (descr->member) == 4)                                        \
+       asm volatile (LOCK_PREFIX "cmpxchgl %2, %%fs:%P3"                     \
+                    : "=a" (__ret)                                           \
+                    : "0" (__old), "r" (newval),                             \
+                      "i" (offsetof (struct pthread, member)));              \
+     else                                                                    \
+       /* Not necessary for other sizes in the moment.  */                   \
+       abort ();                                                             \
+     __ret; })
+
+
+/* Atomic set bit.  */
+#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
+  (void) ({ if (sizeof ((descr)->member) == 4)                               \
+             asm volatile (LOCK_PREFIX "orl %1, %%fs:%P0"                    \
+                           :: "i" (offsetof (struct pthread, member)),       \
+                              "ir" (1 << (bit)));                            \
+           else                                                              \
+             /* Not necessary for other sizes in the moment.  */             \
+             abort (); })
+
+
+#define CALL_THREAD_FCT(descr) \
+  ({ void *__res;                                                            \
+     asm volatile ("movq %%fs:%P2, %%rdi\n\t"                                \
+                  "callq *%%fs:%P1"                                          \
+                  : "=a" (__res)                                             \
+                  : "i" (offsetof (struct pthread, start_routine)),          \
+                    "i" (offsetof (struct pthread, arg))                     \
+                  : "di", "si", "cx", "dx", "r8", "r9", "r10", "r11",        \
+                    "memory", "cc");                                         \
+     __res; })
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/libpthread/nptl/unwind.c b/libpthread/nptl/unwind.c
new file mode 100644 (file)
index 0000000..56a4238
--- /dev/null
@@ -0,0 +1,176 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>
+   and Richard Henderson <rth@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 <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "pthreadP.h"
+#include "jmpbuf-unwind.h"
+
+#ifdef HAVE_FORCED_UNWIND
+
+#ifdef _STACK_GROWS_DOWN
+# define FRAME_LEFT(frame, other, adj) \
+  ((uintptr_t) frame - adj >= (uintptr_t) other - adj)
+#elif _STACK_GROWS_UP
+# define FRAME_LEFT(frame, other, adj) \
+  ((uintptr_t) frame - adj <= (uintptr_t) other - adj)
+#else
+# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
+#endif
+
+static _Unwind_Reason_Code
+unwind_stop (int version, _Unwind_Action actions,
+            _Unwind_Exception_Class exc_class,
+            struct _Unwind_Exception *exc_obj,
+            struct _Unwind_Context *context, void *stop_parameter)
+{
+  struct pthread_unwind_buf *buf = stop_parameter;
+  struct pthread *self = THREAD_SELF;
+  struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup);
+  int do_longjump = 0;
+
+  /* Adjust all pointers used in comparisons, so that top of thread's
+     stack is at the top of address space.  Without that, things break
+     if stack is allocated above the main stack.  */
+  uintptr_t adj = (uintptr_t) self->stackblock + self->stackblock_size;
+
+  /* Do longjmp if we're at "end of stack", aka "end of unwind data".
+     We assume there are only C frame without unwind data in between
+     here and the jmp_buf target.  Otherwise simply note that the CFA
+     of a function is NOT within it's stack frame; it's the SP of the
+     previous frame.  */
+  if ((actions & _UA_END_OF_STACK)
+      || ! _JMPBUF_CFA_UNWINDS_ADJ (buf->cancel_jmp_buf[0].jmp_buf, context,
+                                   adj))
+    do_longjump = 1;
+
+  if (__builtin_expect (curp != NULL, 0))
+    {
+      /* Handle the compatibility stuff.  Execute all handlers
+        registered with the old method which would be unwound by this
+        step.  */
+      struct _pthread_cleanup_buffer *oldp = buf->priv.data.cleanup;
+      void *cfa = (void *) _Unwind_GetCFA (context);
+
+      if (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp, adj)))
+       {
+         do
+           {
+             /* Pointer to the next element.  */
+             struct _pthread_cleanup_buffer *nextp = curp->__prev;
+
+             /* Call the handler.  */
+             curp->__routine (curp->__arg);
+
+             /* To the next.  */
+             curp = nextp;
+           }
+         while (curp != oldp
+                && (do_longjump || FRAME_LEFT (cfa, curp, adj)));
+
+         /* Mark the current element as handled.  */
+         THREAD_SETMEM (self, cleanup, curp);
+       }
+    }
+
+  if (do_longjump)
+    __libc_unwind_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1);
+
+  return _URC_NO_REASON;
+}
+
+
+static void
+unwind_cleanup (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc)
+{
+  /* When we get here a C++ catch block didn't rethrow the object.  We
+     cannot handle this case and therefore abort.  */
+# define STR_N_LEN(str) str, strlen (str)
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (write, err, 3, STDERR_FILENO,
+                   STR_N_LEN ("FATAL: exception not rethrown\n"));
+  abort ();
+}
+
+#endif /* have forced unwind */
+
+
+void
+__cleanup_fct_attribute __attribute ((noreturn))
+__pthread_unwind (__pthread_unwind_buf_t *buf)
+{
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+  struct pthread *self = THREAD_SELF;
+
+#ifdef HAVE_FORCED_UNWIND
+  /* This is not a catchable exception, so don't provide any details about
+     the exception type.  We do need to initialize the field though.  */
+  THREAD_SETMEM (self, exc.exception_class, 0);
+  THREAD_SETMEM (self, exc.exception_cleanup, unwind_cleanup);
+
+  _Unwind_ForcedUnwind (&self->exc, unwind_stop, ibuf);
+#else
+  /* Handle the compatibility stuff first.  Execute all handlers
+     registered with the old method.  We don't execute them in order,
+     instead, they will run first.  */
+  struct _pthread_cleanup_buffer *oldp = ibuf->priv.data.cleanup;
+  struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup);
+
+  if (curp != oldp)
+    {
+      do
+       {
+         /* Pointer to the next element.  */
+         struct _pthread_cleanup_buffer *nextp = curp->__prev;
+
+         /* Call the handler.  */
+         curp->__routine (curp->__arg);
+
+         /* To the next.  */
+         curp = nextp;
+       }
+      while (curp != oldp);
+
+      /* Mark the current element as handled.  */
+      THREAD_SETMEM (self, cleanup, curp);
+    }
+
+  /* We simply jump to the registered setjmp buffer.  */
+  __libc_unwind_longjmp ((struct __jmp_buf_tag *) ibuf->cancel_jmp_buf, 1);
+#endif
+  /* NOTREACHED */
+
+  /* We better do not get here.  */
+  abort ();
+}
+hidden_def (__pthread_unwind)
+
+
+void
+__cleanup_fct_attribute __attribute ((noreturn))
+__pthread_unwind_next (__pthread_unwind_buf_t *buf)
+{
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+
+  __pthread_unwind ((__pthread_unwind_buf_t *) ibuf->priv.data.prev);
+}
+hidden_def (__pthread_unwind_next)
diff --git a/libpthread/nptl/vars.c b/libpthread/nptl/vars.c
new file mode 100644 (file)
index 0000000..1e1a3cf
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <pthreadP.h>
+#include <stdlib.h>
+#include <tls.h>
+#include <unistd.h>
+
+/* Default stack size.  */
+size_t __default_stacksize attribute_hidden
+#ifdef SHARED
+;
+#else
+  = PTHREAD_STACK_MIN;
+#endif
+
+/* Flag whether the machine is SMP or not.  */
+int __is_smp attribute_hidden;
+
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+/* Variable set to a nonzero value if more than one thread runs or ran.  */
+int __pthread_multiple_threads attribute_hidden;
+#endif
+
+/* Table of the key information.  */
+struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX]
+  __attribute__ ((nocommon));
+hidden_data_def (__pthread_keys)
diff --git a/libpthread/nptl_db/Makefile b/libpthread/nptl_db/Makefile
new file mode 100644 (file)
index 0000000..5c73ff2
--- /dev/null
@@ -0,0 +1,60 @@
+# 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.
+
+# Makefile for NPTL debug library subdirectory of GNU C Library.
+
+subdir          := nptl_db
+
+nptl_db-version = 1.0
+
+extra-libs = libthread_db
+extra-libs-others := $(extra-libs)
+
+headers         = thread_db.h
+
+libthread_db-routines = td_init td_log td_ta_new td_ta_delete \
+                       td_ta_get_nthreads td_ta_get_ph \
+                       td_ta_map_id2thr td_ta_map_lwp2thr \
+                       td_ta_thr_iter td_ta_tsd_iter \
+                       td_thr_get_info td_thr_getfpregs td_thr_getgregs \
+                       td_thr_getxregs td_thr_getxregsize td_thr_setfpregs \
+                       td_thr_setgregs td_thr_setprio td_thr_setsigpending \
+                       td_thr_setxregs td_thr_sigsetmask td_thr_tsd \
+                       td_thr_validate td_thr_dbsuspend td_thr_dbresume \
+                       td_ta_setconcurrency td_ta_enable_stats \
+                       td_ta_reset_stats td_ta_get_stats td_ta_event_addr \
+                       td_thr_event_enable td_thr_set_event \
+                       td_thr_clear_event td_thr_event_getmsg \
+                       td_ta_set_event td_ta_event_getmsg \
+                       td_ta_clear_event td_symbol_list \
+                       td_thr_tlsbase td_thr_tls_get_addr \
+                       fetch-value
+
+libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes))
+
+# The ps_* callback functions are not defined.
+libthread_db.so-no-z-defs = yes
+
+distribute = thread_dbP.h shlib-versions proc_service.h db_info.c structs.def
+include ../Rules
+
+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
+# This ensures they will load libc.so for needed symbols if loaded by
+# a statically-linked program that hasn't already loaded it.
+$(objpfx)libthread_db.so: $(common-objpfx)libc.so \
+                         $(common-objpfx)libc_nonshared.a
diff --git a/libpthread/nptl_db/Versions b/libpthread/nptl_db/Versions
new file mode 100644 (file)
index 0000000..063493c
--- /dev/null
@@ -0,0 +1,24 @@
+libthread_db {
+  GLIBC_2.1.3 {
+    # t*
+    td_init; td_log; td_ta_clear_event; td_ta_delete; td_ta_enable_stats;
+    td_ta_event_addr; td_ta_event_getmsg; td_ta_get_nthreads; td_ta_get_ph;
+    td_ta_get_stats; td_ta_map_id2thr; td_ta_map_lwp2thr; td_ta_new;
+    td_ta_reset_stats; td_ta_set_event; td_ta_setconcurrency;
+    td_ta_thr_iter; td_ta_tsd_iter; td_thr_clear_event; td_thr_dbresume;
+    td_thr_dbsuspend; td_thr_event_enable; td_thr_event_getmsg;
+    td_thr_get_info; td_thr_getfpregs; td_thr_getgregs; td_thr_getxregs;
+    td_thr_getxregsize; td_thr_set_event; td_thr_setfpregs; td_thr_setgregs;
+    td_thr_setprio; td_thr_setsigpending; td_thr_setxregs; td_thr_sigsetmask;
+    td_thr_tsd; td_thr_validate;
+  }
+  GLIBC_2.2.3 {
+    td_symbol_list;
+  }
+  GLIBC_2.3 {
+    td_thr_tls_get_addr;
+  }
+  GLIBC_2.3.3 {
+    td_thr_tlsbase;
+  }
+}
diff --git a/libpthread/nptl_db/db_info.c b/libpthread/nptl_db/db_info.c
new file mode 100644 (file)
index 0000000..5000b99
--- /dev/null
@@ -0,0 +1,103 @@
+/* This file is included by pthread_create.c to define in libpthread
+   all the magic symbols required by libthread_db.
+
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+typedef struct pthread pthread;
+typedef struct pthread_key_struct pthread_key_struct;
+typedef struct pthread_key_data pthread_key_data;
+typedef struct
+{
+  struct pthread_key_data data[PTHREAD_KEY_2NDLEVEL_SIZE];
+}
+pthread_key_data_level2;
+
+typedef struct
+{
+  union dtv dtv[UINT32_MAX / 2 / sizeof (union dtv)]; /* No constant bound.  */
+} dtv;
+
+typedef struct link_map link_map;
+
+
+#define schedparam_sched_priority schedparam.sched_priority
+
+#define eventbuf_eventmask eventbuf.eventmask
+#define eventbuf_eventmask_event_bits eventbuf.eventmask.event_bits
+
+#define DESC(name, offset, obj) \
+  DB_DEFINE_DESC (name, 8 * sizeof (obj), 1, offset);
+#define ARRAY_DESC(name, offset, obj) \
+  DB_DEFINE_DESC (name, \
+                 8 * sizeof (obj)[0], sizeof (obj) / sizeof (obj)[0], \
+                 offset);
+
+#if TLS_TCB_AT_TP
+# define dtvp header.dtv
+#elif TLS_DTV_AT_TP
+/* Special case hack.  If TLS_TCB_SIZE == 0 (on PowerPC), there is no TCB
+   containing the DTV at the TP, but actually the TCB lies behind the TP,
+   i.e. at the very end of the area covered by TLS_PRE_TCB_SIZE.  */
+DESC (_thread_db_pthread_dtvp,
+      TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv)
+      - (TLS_TCB_SIZE == 0 ? sizeof (tcbhead_t) : 0), union dtv)
+#endif
+
+
+#define DB_STRUCT(type) \
+  const uint32_t _thread_db_sizeof_##type = sizeof (type);
+#define DB_STRUCT_FIELD(type, field) \
+  DESC (_thread_db_##type##_##field, \
+       offsetof (type, field), ((type *) 0)->field)
+#define DB_STRUCT_ARRAY_FIELD(type, field) \
+  ARRAY_DESC (_thread_db_##type##_##field, \
+             offsetof (type, field), ((type *) 0)->field)
+#define DB_VARIABLE(name) DESC (_thread_db_##name, 0, name)
+#define DB_ARRAY_VARIABLE(name) ARRAY_DESC (_thread_db_##name, 0, name)
+#define DB_SYMBOL(name)        /* Nothing.  */
+#define DB_FUNCTION(name) /* Nothing.  */
+#include "structs.def"
+#undef DB_STRUCT
+#undef DB_STRUCT_FIELD
+#undef DB_SYMBOL
+#undef DB_FUNCTION
+#undef DB_VARIABLE
+#undef DESC
+
+
+
+#ifdef DB_THREAD_SELF
+# ifdef DB_THREAD_SELF_INCLUDE
+#  include DB_THREAD_SELF_INCLUDE
+# endif
+
+/* This macro is defined in the machine's tls.h using the three below.  */
+# define CONST_THREAD_AREA(bits, value) \
+  const uint32_t _thread_db_const_thread_area = (value);
+# define REGISTER_THREAD_AREA(bits, regofs, scale) \
+  DB_DEFINE_DESC (_thread_db_register##bits##_thread_area, \
+                 bits, (scale), (regofs));
+# define REGISTER(bits, size, regofs, bias) \
+  DB_DEFINE_DESC (_thread_db_register##bits, size, (uint32_t)(bias), (regofs));
+
+DB_THREAD_SELF
+#endif
diff --git a/libpthread/nptl_db/fetch-value.c b/libpthread/nptl_db/fetch-value.c
new file mode 100644 (file)
index 0000000..0d9bb0e
--- /dev/null
@@ -0,0 +1,284 @@
+/* Helper routines for libthread_db.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "thread_dbP.h"
+#include <byteswap.h>
+#include <assert.h>
+
+td_err_e
+_td_check_sizeof (td_thragent_t *ta, uint32_t *sizep, int sizep_name)
+{
+  if (*sizep == 0)
+    {
+      psaddr_t descptr;
+      ps_err_e err = td_lookup (ta->ph, sizep_name, &descptr);
+      if (err == PS_NOSYM)
+       return TD_NOCAPAB;
+      if (err == PS_OK)
+       err = ps_pdread (ta->ph, descptr, sizep, sizeof *sizep);
+      if (err != PS_OK)
+       return TD_ERR;
+      if (*sizep & 0xff000000U)
+       *sizep = bswap_32 (*sizep);
+    }
+  return TD_OK;
+}
+
+td_err_e
+_td_locate_field (td_thragent_t *ta,
+                 db_desc_t desc, int descriptor_name,
+                 psaddr_t idx, psaddr_t *address)
+{
+  uint32_t elemsize;
+
+  if (DB_DESC_SIZE (desc) == 0)
+    {
+      /* Read the information about this field from the inferior.  */
+      psaddr_t descptr;
+      ps_err_e err = td_lookup (ta->ph, descriptor_name, &descptr);
+      if (err == PS_NOSYM)
+       return TD_NOCAPAB;
+      if (err == PS_OK)
+       err = ps_pdread (ta->ph, descptr, desc, DB_SIZEOF_DESC);
+      if (err != PS_OK)
+       return TD_ERR;
+      if (DB_DESC_SIZE (desc) == 0)
+       return TD_DBERR;
+      if (DB_DESC_SIZE (desc) & 0xff000000U)
+       {
+         /* Byte-swap these words, though we leave the size word
+            in native order as the handy way to distinguish.  */
+         DB_DESC_OFFSET (desc) = bswap_32 (DB_DESC_OFFSET (desc));
+         DB_DESC_NELEM (desc) = bswap_32 (DB_DESC_NELEM (desc));
+       }
+    }
+
+  if (idx != 0 && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
+    /* This is an internal indicator to callers with nonzero IDX
+       that the IDX value is too big.  */
+    return TD_NOAPLIC;
+
+  elemsize = DB_DESC_SIZE (desc);
+  if (elemsize & 0xff000000U)
+    elemsize = bswap_32 (elemsize);
+
+  *address += (int32_t) DB_DESC_OFFSET (desc);
+  *address += (elemsize / 8 * (idx - (psaddr_t) 0));
+  return TD_OK;
+}
+
+td_err_e
+_td_fetch_value (td_thragent_t *ta,
+                db_desc_t desc, int descriptor_name,
+                psaddr_t idx, psaddr_t address,
+                psaddr_t *result)
+{
+  ps_err_e err;
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      value = bswap_32 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      value = bswap_64 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else
+    return TD_DBERR;
+
+  return err == PS_OK ? TD_OK : TD_ERR;
+}
+
+
+td_err_e
+_td_store_value (td_thragent_t *ta,
+                uint32_t desc[2], int descriptor_name, psaddr_t idx,
+                psaddr_t address, psaddr_t widened_value)
+{
+  ps_err_e err;
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value = widened_value - (psaddr_t) 0;
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      value = bswap_32 (value);
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      value = bswap_64 (value);
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else
+    return TD_DBERR;
+
+  return err == PS_OK ? TD_OK : TD_ERR;
+}
+
+td_err_e
+_td_fetch_value_local (td_thragent_t *ta,
+                      db_desc_t desc, int descriptor_name, psaddr_t idx,
+                      void *address,
+                      psaddr_t *result)
+{
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value;
+      memcpy (&value, address, sizeof value);
+      value = bswap_32 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      memcpy (&value, address, sizeof value);
+      value = bswap_64 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else
+    return TD_DBERR;
+
+  return TD_OK;
+}
+
+
+td_err_e
+_td_store_value_local (td_thragent_t *ta,
+                      uint32_t desc[2], int descriptor_name, psaddr_t idx,
+                      void *address, psaddr_t widened_value)
+{
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value = widened_value - (psaddr_t) 0;
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      value = bswap_32 (value);
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+       return TD_NOCAPAB;
+      value = bswap_64 (value);
+      memcpy (address, &value, sizeof value);
+    }
+  else
+    return TD_DBERR;
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/proc_service.h b/libpthread/nptl_db/proc_service.h
new file mode 100644 (file)
index 0000000..d49e87a
--- /dev/null
@@ -0,0 +1,87 @@
+/* Callback interface for libthread_db, functions users must define.
+   Copyright (C) 1999,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.  */
+
+/* The definitions in this file must correspond to those in the debugger.  */
+#include <sys/procfs.h>
+
+/* Functions in this interface return one of these status codes.  */
+typedef enum
+{
+  PS_OK,               /* Generic "call succeeded".  */
+  PS_ERR,              /* Generic error. */
+  PS_BADPID,           /* Bad process handle.  */
+  PS_BADLID,           /* Bad LWP identifier.  */
+  PS_BADADDR,          /* Bad address.  */
+  PS_NOSYM,            /* Could not find given symbol.  */
+  PS_NOFREGS           /* FPU register set not available for given LWP.  */
+} ps_err_e;
+
+
+/* This type is opaque in this interface.
+   It's defined by the user of libthread_db.  */
+struct ps_prochandle;
+
+
+/* Read or write process memory at the given address.  */
+extern ps_err_e ps_pdread (struct ps_prochandle *,
+                          psaddr_t, void *, size_t);
+extern ps_err_e ps_pdwrite (struct ps_prochandle *,
+                           psaddr_t, const void *, size_t);
+extern ps_err_e ps_ptread (struct ps_prochandle *,
+                          psaddr_t, void *, size_t);
+extern ps_err_e ps_ptwrite (struct ps_prochandle *,
+                           psaddr_t, const void *, size_t);
+
+
+/* Get and set the given LWP's general or FPU register set.  */
+extern ps_err_e ps_lgetregs (struct ps_prochandle *,
+                            lwpid_t, prgregset_t);
+extern ps_err_e ps_lsetregs (struct ps_prochandle *,
+                            lwpid_t, const prgregset_t);
+extern ps_err_e ps_lgetfpregs (struct ps_prochandle *,
+                              lwpid_t, prfpregset_t *);
+extern ps_err_e ps_lsetfpregs (struct ps_prochandle *,
+                              lwpid_t, const prfpregset_t *);
+
+/* Return the PID of the process.  */
+extern pid_t ps_getpid (struct ps_prochandle *);
+
+/* Fetch the special per-thread address associated with the given LWP.
+   This call is only used on a few platforms (most use a normal register).
+   The meaning of the `int' parameter is machine-dependent.  */
+extern ps_err_e ps_get_thread_area (const struct ps_prochandle *,
+                                   lwpid_t, int, psaddr_t *);
+
+
+/* Look up the named symbol in the named DSO in the symbol tables
+   associated with the process being debugged, filling in *SYM_ADDR
+   with the corresponding run-time address.  */
+extern ps_err_e ps_pglobal_lookup (struct ps_prochandle *,
+                                  const char *object_name,
+                                  const char *sym_name,
+                                  psaddr_t *sym_addr);
+
+
+/* Stop or continue the entire process.  */
+extern ps_err_e ps_pstop (const struct ps_prochandle *);
+extern ps_err_e ps_pcontinue (const struct ps_prochandle *);
+
+/* Stop or continue the given LWP alone.  */
+extern ps_err_e ps_lstop (const struct ps_prochandle *, lwpid_t);
+extern ps_err_e ps_lcontinue (const struct ps_prochandle *, lwpid_t);
diff --git a/libpthread/nptl_db/structs.def b/libpthread/nptl_db/structs.def
new file mode 100644 (file)
index 0000000..b17a628
--- /dev/null
@@ -0,0 +1,86 @@
+/* List of types and symbols in libpthread examined by libthread_db.
+   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 DB_STRUCT_ARRAY_FIELD
+# define DB_STRUCT_ARRAY_FIELD(type, field) DB_STRUCT_FIELD (type, field)
+# define DB_ARRAY_VARIABLE(name) DB_VARIABLE (name)
+# define STRUCTS_DEF_DEFAULTS 1
+#endif
+
+DB_STRUCT (pthread)
+DB_STRUCT_FIELD (pthread, list)
+DB_STRUCT_FIELD (pthread, report_events)
+DB_STRUCT_FIELD (pthread, tid)
+DB_STRUCT_FIELD (pthread, start_routine)
+DB_STRUCT_FIELD (pthread, cancelhandling)
+DB_STRUCT_FIELD (pthread, schedpolicy)
+DB_STRUCT_FIELD (pthread, schedparam_sched_priority)
+DB_STRUCT_FIELD (pthread, specific)
+DB_STRUCT_FIELD (pthread, eventbuf)
+DB_STRUCT_FIELD (pthread, eventbuf_eventmask)
+DB_STRUCT_ARRAY_FIELD (pthread, eventbuf_eventmask_event_bits)
+DB_STRUCT_FIELD (pthread, nextevent)
+
+DB_STRUCT (list_t)
+DB_STRUCT_FIELD (list_t, next)
+DB_STRUCT_FIELD (list_t, prev)
+
+DB_STRUCT (td_thr_events_t)
+DB_STRUCT_ARRAY_FIELD (td_thr_events_t, event_bits)
+
+DB_STRUCT (td_eventbuf_t)
+DB_STRUCT_FIELD (td_eventbuf_t, eventnum)
+DB_STRUCT_FIELD (td_eventbuf_t, eventdata)
+
+DB_SYMBOL (stack_used)
+DB_SYMBOL (__stack_user)
+DB_SYMBOL (nptl_version)
+DB_FUNCTION (__nptl_create_event)
+DB_FUNCTION (__nptl_death_event)
+DB_SYMBOL (__nptl_threads_events)
+DB_VARIABLE (__nptl_nthreads)
+DB_VARIABLE (__nptl_last_event)
+
+DB_ARRAY_VARIABLE (__pthread_keys)
+DB_STRUCT (pthread_key_struct)
+DB_STRUCT_FIELD (pthread_key_struct, seq)
+DB_STRUCT_FIELD (pthread_key_struct, destr)
+
+DB_STRUCT (pthread_key_data)
+DB_STRUCT_FIELD (pthread_key_data, seq)
+DB_STRUCT_FIELD (pthread_key_data, data)
+DB_STRUCT (pthread_key_data_level2)
+DB_STRUCT_ARRAY_FIELD (pthread_key_data_level2, data)
+
+#if USE_TLS
+DB_STRUCT_FIELD (link_map, l_tls_modid)
+#endif
+
+#if !defined IS_IN_libpthread || USE_TLS
+DB_STRUCT_ARRAY_FIELD (dtv, dtv)
+#endif
+#if !defined IS_IN_libpthread || TLS_TCB_AT_TP
+DB_STRUCT_FIELD (pthread, dtvp)
+#endif
+
+#ifdef STRUCTS_DEF_DEFAULTS
+# undef DB_STRUCT_ARRAY_FIELD
+# undef DB_ARRAY_VARIABLE
+# undef STRUCTS_DEF_DEFAULTS
+#endif
diff --git a/libpthread/nptl_db/td_init.c b/libpthread/nptl_db/td_init.c
new file mode 100644 (file)
index 0000000..946ff72
--- /dev/null
@@ -0,0 +1,32 @@
+/* Initialization function of thread debugger support library.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+int __td_debug;
+
+
+td_err_e
+td_init (void)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_init");
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_log.c b/libpthread/nptl_db/td_log.c
new file mode 100644 (file)
index 0000000..52212a0
--- /dev/null
@@ -0,0 +1,32 @@
+/* Noop, left for historical reasons.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_log (void)
+{
+  /* This interface is deprecated in the Sun interface.  We provide it
+     for compatibility but don't do anything ourself.  We might in
+     future do some logging if this seems reasonable.  */
+  LOG ("td_log");
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_symbol_list.c b/libpthread/nptl_db/td_symbol_list.c
new file mode 100644 (file)
index 0000000..5d6c94e
--- /dev/null
@@ -0,0 +1,85 @@
+/* Return list of symbols the library can request.
+   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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 <assert.h>
+#include <gnu/lib-names.h>
+#include "thread_dbP.h"
+
+
+#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+# define DOT "."               /* PPC64 requires . prefix on code symbols.  */
+#else
+# define DOT                   /* No prefix.  */
+#endif
+
+static const char *symbol_list_arr[] =
+{
+# define DB_STRUCT(type) \
+  [SYM_SIZEOF_##type] = "_thread_db_sizeof_" #type,
+# define DB_STRUCT_FIELD(type, field) \
+  [SYM_##type##_FIELD_##field] = "_thread_db_" #type "_" #field,
+# define DB_SYMBOL(name) \
+  [SYM_##name] = #name,
+# define DB_FUNCTION(name) \
+  [SYM_##name] = DOT #name,
+# define DB_VARIABLE(name) \
+  [SYM_##name] = #name, \
+  [SYM_DESC_##name] = "_thread_db_" #name,
+# include "structs.def"
+# undef DB_STRUCT
+# undef DB_FUNCTION
+# undef DB_SYMBOL
+# undef DB_VARIABLE
+
+  [SYM_TH_UNIQUE_CONST_THREAD_AREA] = "_thread_db_const_thread_area",
+  [SYM_TH_UNIQUE_REGISTER64] = "_thread_db_register64",
+  [SYM_TH_UNIQUE_REGISTER32] = "_thread_db_register32",
+  [SYM_TH_UNIQUE_REGISTER32_THREAD_AREA] = "_thread_db_register32_thread_area",
+  [SYM_TH_UNIQUE_REGISTER64_THREAD_AREA] = "_thread_db_register64_thread_area",
+
+  [SYM_NUM_MESSAGES] = NULL
+};
+
+
+const char **
+td_symbol_list (void)
+{
+  return symbol_list_arr;
+}
+
+
+ps_err_e
+td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr)
+{
+  ps_err_e result;
+  assert (idx >= 0 && idx < SYM_NUM_MESSAGES);
+  result = ps_pglobal_lookup (ps, LIBPTHREAD_SO, symbol_list_arr[idx],
+                             sym_addr);
+
+#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+  /* For PowerPC, 64-bit uses dot symbols but 32-bit does not.
+     We could be a 64-bit libthread_db debugging a 32-bit libpthread.  */
+  if (result == PS_NOSYM && symbol_list_arr[idx][0] == '.')
+    result = ps_pglobal_lookup (ps, LIBPTHREAD_SO, &symbol_list_arr[idx][1],
+                               sym_addr);
+#endif
+
+  return result;
+}
diff --git a/libpthread/nptl_db/td_ta_clear_event.c b/libpthread/nptl_db/td_ta_clear_event.c
new file mode 100644 (file)
index 0000000..7a2850c
--- /dev/null
@@ -0,0 +1,79 @@
+/* Globally disable events.
+   Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_clear_event (ta_arg, event)
+     const td_thragent_t *ta_arg;
+     td_thr_events_t *event;
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t eventmask = 0;
+  void *copy = NULL;
+
+  LOG ("td_ta_clear_event");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_SYMBOL (eventmask, ta, __nptl_threads_events);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, ta, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+       {
+         psaddr_t word;
+         uint32_t mask;
+         err = DB_GET_FIELD_LOCAL (word, ta, copy,
+                                   td_thr_events_t, event_bits, idx);
+         if (err != TD_OK)
+           break;
+         mask = (uintptr_t) word;
+         mask &= ~event->event_bits[idx];
+         word = (psaddr_t) (uintptr_t) mask;
+         err = DB_PUT_FIELD_LOCAL (ta, copy,
+                                   td_thr_events_t, event_bits, idx, word);
+         if (err != TD_OK)
+           break;
+       }
+      if (err == TD_NOAPLIC)
+       {
+         err = TD_OK;
+         while (idx < TD_EVENTSIZE)
+           if (event->event_bits[idx++] != 0)
+             {
+               err = TD_NOEVENT;
+               break;
+             }
+       }
+      if (err == TD_OK)
+       /* Now write it back to the inferior.  */
+       err = DB_PUT_STRUCT (ta, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_ta_delete.c b/libpthread/nptl_db/td_ta_delete.c
new file mode 100644 (file)
index 0000000..57b90e5
--- /dev/null
@@ -0,0 +1,42 @@
+/* Detach to target process.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <stdlib.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_delete (td_thragent_t *ta)
+{
+  LOG ("td_ta_delete");
+
+  /* Safety check.  Note that the test will also fail for TA == NULL.  */
+  if (!ta_ok (ta))
+    return TD_BADTA;
+
+  /* Remove the handle from the list.  */
+  list_del (&ta->list);
+
+  /* The handle was allocated in `td_ta_new'.  */
+  free (ta);
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_enable_stats.c b/libpthread/nptl_db/td_ta_enable_stats.c
new file mode 100644 (file)
index 0000000..ec7014a
--- /dev/null
@@ -0,0 +1,35 @@
+/* Enable collection of statistics for process.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_enable_stats (const td_thragent_t *ta, int enable)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_ta_enable_stats");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_event_addr.c b/libpthread/nptl_db/td_ta_event_addr.c
new file mode 100644 (file)
index 0000000..37196e6
--- /dev/null
@@ -0,0 +1,61 @@
+/* Get event address.
+   Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_event_addr (const td_thragent_t *ta_arg,
+                 td_event_e event, td_notify_t *addr)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t taddr;
+
+  LOG ("td_ta_event_addr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  switch (event)
+    {
+    case TD_CREATE:
+      err = DB_GET_SYMBOL (taddr, ta, __nptl_create_event);
+      break;
+
+    case TD_DEATH:
+      err = DB_GET_SYMBOL (taddr, ta, __nptl_death_event);
+      break;
+
+    default:
+      /* Event cannot be handled.  */
+      return TD_NOEVENT;
+    }
+
+  if (err == TD_OK)
+    {
+      /* Success, we got the address.  */
+      addr->type = NOTIFY_BPT;
+      addr->u.bptaddr = taddr;
+    }
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_ta_event_getmsg.c b/libpthread/nptl_db/td_ta_event_getmsg.c
new file mode 100644 (file)
index 0000000..6e68ff4
--- /dev/null
@@ -0,0 +1,105 @@
+/* Retrieve event.
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <stddef.h>
+#include <string.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_event_getmsg (const td_thragent_t *ta_arg, td_event_msg_t *msg)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t eventbuf, eventnum, eventdata;
+  psaddr_t thp, next;
+  void *copy;
+
+  /* XXX I cannot think of another way but using a static variable.  */
+  /* XXX Use at least __thread once it is possible.  */
+  static td_thrhandle_t th;
+
+  LOG ("td_thr_event_getmsg");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Get the pointer to the thread descriptor with the last event.  */
+  err = DB_GET_VALUE (thp, ta, __nptl_last_event, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (thp == 0)
+    /* Nothing waiting.  */
+    return TD_NOMSG;
+
+  /* Copy the event message buffer in from the inferior.  */
+  err = DB_GET_FIELD_ADDRESS (eventbuf, ta, thp, pthread, eventbuf, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, ta, eventbuf, td_eventbuf_t);
+  if (err != TD_OK)
+    return err;
+
+  /* Read the event details from the target thread.  */
+  err = DB_GET_FIELD_LOCAL (eventnum, ta, copy, td_eventbuf_t, eventnum, 0);
+  if (err != TD_OK)
+    return err;
+  /* If the structure is on the list there better be an event recorded.  */
+  if ((int) (uintptr_t) eventnum == TD_EVENT_NONE)
+    return TD_DBERR;
+
+  /* Fill the user's data structure.  */
+  err = DB_GET_FIELD_LOCAL (eventdata, ta, copy, td_eventbuf_t, eventdata, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Generate the thread descriptor.  */
+  th.th_ta_p = (td_thragent_t *) ta;
+  th.th_unique = thp;
+
+  /* Fill the user's data structure.  */
+  msg->msg.data = (uintptr_t) eventdata;
+  msg->event = (uintptr_t) eventnum;
+  msg->th_p = &th;
+
+  /* And clear the event message in the target.  */
+  memset (copy, 0, ta->ta_sizeof_td_eventbuf_t);
+  err = DB_PUT_STRUCT (ta, eventbuf, td_eventbuf_t, copy);
+  if (err != TD_OK)
+    return err;
+
+  /* Get the pointer to the next descriptor with an event.  */
+  err = DB_GET_FIELD (next, ta, thp, pthread, nextevent, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Store the pointer in the list head variable.  */
+  err = DB_PUT_VALUE (ta, __nptl_last_event, 0, next);
+  if (err != TD_OK)
+    return err;
+
+  if (next != 0)
+    /* Clear the next pointer in the current descriptor.  */
+    err = DB_PUT_FIELD (ta, thp, pthread, nextevent, 0, 0);
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_ta_get_nthreads.c b/libpthread/nptl_db/td_ta_get_nthreads.c
new file mode 100644 (file)
index 0000000..ffe78bd
--- /dev/null
@@ -0,0 +1,42 @@
+/* Get the number of threads in the process.
+   Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+td_err_e
+td_ta_get_nthreads (const td_thragent_t *ta_arg, int *np)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t n;
+
+  LOG ("td_ta_get_nthreads");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Access the variable in the inferior that tells us.  */
+  err = DB_GET_VALUE (n, ta, __nptl_nthreads, 0);
+  if (err == TD_OK)
+    *np = (uintptr_t) n;
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_ta_get_ph.c b/libpthread/nptl_db/td_ta_get_ph.c
new file mode 100644 (file)
index 0000000..04e01fb
--- /dev/null
@@ -0,0 +1,36 @@
+/* Get external process handle.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_get_ph (const td_thragent_t *ta, struct ps_prochandle **ph)
+{
+  LOG ("td_ta_get_ph");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  *ph = ta->ph;
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_get_stats.c b/libpthread/nptl_db/td_ta_get_stats.c
new file mode 100644 (file)
index 0000000..d5d879c
--- /dev/null
@@ -0,0 +1,35 @@
+/* Retrieve statistics for process.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_get_stats (const td_thragent_t *ta, td_ta_stats_t *statsp)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_ta_get_stats");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_map_id2thr.c b/libpthread/nptl_db/td_ta_map_id2thr.c
new file mode 100644 (file)
index 0000000..189a671
--- /dev/null
@@ -0,0 +1,38 @@
+/* Map thread ID to thread handle.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
+{
+  LOG ("td_ta_map_id2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Create the `td_thrhandle_t' object.  */
+  th->th_ta_p = (td_thragent_t *) ta;
+  th->th_unique = (psaddr_t) pt;
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_map_lwp2thr.c b/libpthread/nptl_db/td_ta_map_lwp2thr.c
new file mode 100644 (file)
index 0000000..1e93210
--- /dev/null
@@ -0,0 +1,178 @@
+/* Which thread is running on an LWP?
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "thread_dbP.h"
+#include <stdlib.h>
+#include <byteswap.h>
+#include <sys/procfs.h>
+
+
+td_err_e
+td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
+                  lwpid_t lwpid, td_thrhandle_t *th)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  ps_err_e err;
+  td_err_e terr;
+  prgregset_t regs;
+  psaddr_t addr;
+
+  LOG ("td_ta_map_lwp2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  if (ta->ta_howto == ta_howto_unknown)
+    {
+      /* We need to read in from the inferior the instructions what to do.  */
+      psaddr_t howto;
+
+      err = td_lookup (ta->ph, SYM_TH_UNIQUE_CONST_THREAD_AREA, &howto);
+      if (err == PS_OK)
+       {
+         err = ps_pdread (ta->ph, howto,
+                          &ta->ta_howto_data.const_thread_area,
+                          sizeof ta->ta_howto_data.const_thread_area);
+         if (err != PS_OK)
+           return TD_ERR;
+         ta->ta_howto = ta_howto_const_thread_area;
+         if (ta->ta_howto_data.const_thread_area & 0xff000000U)
+           ta->ta_howto_data.const_thread_area
+             = bswap_32 (ta->ta_howto_data.const_thread_area);
+       }
+      else
+       {
+         switch (sizeof (regs[0]))
+           {
+           case 8:
+             err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER64, &howto);
+             if (err == PS_OK)
+               ta->ta_howto = ta_howto_reg;
+             else if (err == PS_NOSYM)
+               {
+                 err = td_lookup (ta->ph,
+                                  SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+                                  &howto);
+                 if (err == PS_OK)
+                   ta->ta_howto = ta_howto_reg_thread_area;
+               }
+             break;
+
+           case 4:
+             err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER32, &howto);
+             if (err == PS_OK)
+               ta->ta_howto = ta_howto_reg;
+             else if (err == PS_NOSYM)
+               {
+                 err = td_lookup (ta->ph,
+                                  SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+                                  &howto);
+                 if (err == PS_OK)
+                   ta->ta_howto = ta_howto_reg_thread_area;
+               }
+             break;
+
+           default:
+             abort ();
+             return TD_DBERR;
+           }
+
+         if (err != PS_OK)
+           return TD_DBERR;
+
+         /* For either of these methods we read in the same descriptor.  */
+         err = ps_pdread (ta->ph, howto,
+                          ta->ta_howto_data.reg, DB_SIZEOF_DESC);
+         if (err != PS_OK)
+           return TD_ERR;
+         if (DB_DESC_SIZE (ta->ta_howto_data.reg) == 0)
+           return TD_DBERR;
+         if (DB_DESC_SIZE (ta->ta_howto_data.reg) & 0xff000000U)
+           {
+             /* Byte-swap these words, though we leave the size word
+                in native order as the handy way to distinguish.  */
+             DB_DESC_OFFSET (ta->ta_howto_data.reg)
+               = bswap_32 (DB_DESC_OFFSET (ta->ta_howto_data.reg));
+             DB_DESC_NELEM (ta->ta_howto_data.reg)
+               = bswap_32 (DB_DESC_NELEM (ta->ta_howto_data.reg));
+           }
+       }
+    }
+
+  switch (ta->ta_howto)
+    {
+    case ta_howto_unknown:
+      return TD_DBERR;
+
+    default:
+      return TD_DBERR;
+
+    case ta_howto_reg:
+      /* On most machines, we are just looking at a register.  */
+      if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+       return TD_ERR;
+      terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg, -1,
+                                   0, regs, &addr);
+      if (terr != TD_OK)
+       return terr;
+      /* In this descriptor the nelem word is overloaded as the bias.  */
+      addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
+      th->th_unique = addr;
+      break;
+
+    case ta_howto_const_thread_area:
+      /* Some hosts don't have this call and this case won't be used.  */
+# pragma weak ps_get_thread_area
+      if (&ps_get_thread_area == NULL)
+       return TD_NOCAPAB;
+
+       /* A la x86-64, there is a constant magic index for get_thread_area.  */
+       if (ps_get_thread_area (ta->ph, lwpid,
+                              ta->ta_howto_data.const_thread_area,
+                              &th->th_unique) != PS_OK)
+        return TD_ERR; /* XXX Other error value?  */
+       break;
+
+     case ta_howto_reg_thread_area:
+      if (&ps_get_thread_area == NULL)
+       return TD_NOCAPAB;
+
+       /* A la i386, there is a register with an index for get_thread_area.  */
+       if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+        return TD_ERR;
+       terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area, -1,
+                                    0, regs, &addr);
+      if (terr != TD_OK)
+       return terr;
+      /* In this descriptor the nelem word is overloaded as scale factor.  */
+      if (ps_get_thread_area
+         (ta->ph, lwpid,
+          ((addr - (psaddr_t) 0)
+           >> DB_DESC_NELEM (ta->ta_howto_data.reg_thread_area)),
+          &th->th_unique) != PS_OK)
+       return TD_ERR;  /* XXX Other error value?  */
+      break;
+    }
+
+  /* Found it.  Now complete the `td_thrhandle_t' object.  */
+  th->th_ta_p = (td_thragent_t *) ta;
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_new.c b/libpthread/nptl_db/td_ta_new.c
new file mode 100644 (file)
index 0000000..f84049a
--- /dev/null
@@ -0,0 +1,65 @@
+/* Attach to target process.
+   Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <version.h>
+
+#include "thread_dbP.h"
+
+
+/* Datatype for the list of known thread agents.  Normally there will
+   be exactly one so we don't spend much though on making it fast.  */
+LIST_HEAD (__td_agent_list);
+
+
+td_err_e
+td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
+{
+  psaddr_t versaddr;
+  char versbuf[sizeof (VERSION)];
+
+  LOG ("td_ta_new");
+
+  /* Check whether the versions match.  */
+  if (td_lookup (ps, SYM_nptl_version, &versaddr) != PS_OK)
+    return TD_NOLIBTHREAD;
+  if (ps_pdread (ps, versaddr, versbuf, sizeof (versbuf)) != PS_OK)
+    return TD_ERR;
+
+  if (memcmp (versbuf, VERSION, sizeof VERSION) != 0)
+    /* Not the right version.  */
+    return TD_VERSION;
+
+  /* Fill in the appropriate information.  */
+  *ta = (td_thragent_t *) calloc (1, sizeof (td_thragent_t));
+  if (*ta == NULL)
+    return TD_MALLOC;
+
+  /* Store the proc handle which we will pass to the callback functions
+     back into the debugger.  */
+  (*ta)->ph = ps;
+
+  /* Now add the new agent descriptor to the list.  */
+  list_add (&(*ta)->list, &__td_agent_list);
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_reset_stats.c b/libpthread/nptl_db/td_ta_reset_stats.c
new file mode 100644 (file)
index 0000000..ea59d2c
--- /dev/null
@@ -0,0 +1,35 @@
+/* Reset statistics.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_reset_stats (const td_thragent_t *ta)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_ta_reset_stats");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_ta_set_event.c b/libpthread/nptl_db/td_ta_set_event.c
new file mode 100644 (file)
index 0000000..29fc14b
--- /dev/null
@@ -0,0 +1,79 @@
+/* Globally enable events.
+   Copyright (C) 1999,2001,2002,2003,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_set_event (ta_arg, event)
+     const td_thragent_t *ta_arg;
+     td_thr_events_t *event;
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t eventmask = 0;
+  void *copy = NULL;
+
+  LOG ("td_ta_set_event");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_SYMBOL (eventmask, ta, __nptl_threads_events);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, ta, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+       {
+         psaddr_t word;
+         uint32_t mask;
+         err = DB_GET_FIELD_LOCAL (word, ta, copy,
+                                   td_thr_events_t, event_bits, idx);
+         if (err != TD_OK)
+           break;
+         mask = (uintptr_t) word;
+         mask |= event->event_bits[idx];
+         word = (psaddr_t) (uintptr_t) mask;
+         err = DB_PUT_FIELD_LOCAL (ta, copy,
+                                   td_thr_events_t, event_bits, idx, word);
+         if (err != TD_OK)
+           break;
+       }
+      if (err == TD_NOAPLIC)
+       {
+         err = TD_OK;
+         while (idx < TD_EVENTSIZE)
+           if (event->event_bits[idx++] != 0)
+             {
+               err = TD_NOEVENT;
+               break;
+             }
+       }
+      if (err == TD_OK)
+       /* Now write it back to the inferior.  */
+       err = DB_PUT_STRUCT (ta, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_ta_setconcurrency.c b/libpthread/nptl_db/td_ta_setconcurrency.c
new file mode 100644 (file)
index 0000000..8552ffb
--- /dev/null
@@ -0,0 +1,35 @@
+/* Set suggested concurrency level for process.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_ta_setconcurrency (const td_thragent_t *ta, int level)
+{
+  /* This is something LinuxThreads does not need to support.  */
+  LOG ("td_ta_setconcurrency");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_NOCAPAB;
+}
diff --git a/libpthread/nptl_db/td_ta_thr_iter.c b/libpthread/nptl_db/td_ta_thr_iter.c
new file mode 100644 (file)
index 0000000..66e4376
--- /dev/null
@@ -0,0 +1,148 @@
+/* Iterate over a process's threads.
+   Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+static td_err_e
+iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback,
+                    void *cbdata_p, td_thr_state_e state, int ti_pri,
+                    psaddr_t head, int fake_empty)
+{
+  td_err_e err;
+  psaddr_t next, ofs;
+  void *copy;
+
+  /* Test the state.
+     XXX This is incomplete.  Normally this test should be in the loop.  */
+  if (state != TD_THR_ANY_STATE)
+    return TD_OK;
+
+  err = DB_GET_FIELD (next, ta, head, list_t, next, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (next == 0 && fake_empty)
+    {
+      /* __pthread_initialize_minimal has not run.
+        There is just the main thread to return.  */
+      td_thrhandle_t th;
+      err = td_ta_map_lwp2thr (ta, ps_getpid (ta->ph), &th);
+      if (err == TD_OK)
+       err = callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK;
+      return err;
+    }
+
+  /* Cache the offset from struct pthread to its list_t member.  */
+  err = DB_GET_FIELD_ADDRESS (ofs, ta, 0, pthread, list, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (ta->ta_sizeof_pthread == 0)
+    {
+      err = _td_check_sizeof (ta, &ta->ta_sizeof_pthread, SYM_SIZEOF_pthread);
+      if (err != TD_OK)
+       return err;
+    }
+  copy = __alloca (ta->ta_sizeof_pthread);
+
+  while (next != head)
+    {
+      psaddr_t addr, schedpolicy, schedprio;
+
+      addr = next - (ofs - (psaddr_t) 0);
+      if (next == 0 || addr == 0) /* Sanity check.  */
+       return TD_DBERR;
+
+      /* Copy the whole descriptor in once so we can access the several
+        fields locally.  Excess copying in one go is much better than
+        multiple ps_pdread calls.  */
+      if (ps_pdread (ta->ph, addr, copy, ta->ta_sizeof_pthread) != PS_OK)
+       return TD_ERR;
+
+      err = DB_GET_FIELD_LOCAL (schedpolicy, ta, copy, pthread,
+                               schedpolicy, 0);
+      if (err != TD_OK)
+       break;
+      err = DB_GET_FIELD_LOCAL (schedprio, ta, copy, pthread,
+                               schedparam_sched_priority, 0);
+      if (err != TD_OK)
+       break;
+
+      /* Now test whether this thread matches the specified conditions.  */
+
+      /* Only if the priority level is as high or higher.  */
+      int descr_pri = ((uintptr_t) schedpolicy == SCHED_OTHER
+                      ? 0 : (uintptr_t) schedprio);
+      if (descr_pri >= ti_pri)
+       {
+         /* Yep, it matches.  Call the callback function.  */
+         td_thrhandle_t th;
+         th.th_ta_p = (td_thragent_t *) ta;
+         th.th_unique = addr;
+         if (callback (&th, cbdata_p) != 0)
+           return TD_DBERR;
+       }
+
+      /* Get the pointer to the next element.  */
+      err = DB_GET_FIELD_LOCAL (next, ta, copy + (ofs - (psaddr_t) 0), list_t,
+                               next, 0);
+      if (err != TD_OK)
+       break;
+    }
+
+  return err;
+}
+
+
+td_err_e
+td_ta_thr_iter (const td_thragent_t *ta_arg, td_thr_iter_f *callback,
+               void *cbdata_p, td_thr_state_e state, int ti_pri,
+               sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t list = 0;
+
+  LOG ("td_ta_thr_iter");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* The thread library keeps two lists for the running threads.  One
+     list contains the thread which are using user-provided stacks
+     (this includes the main thread) and the other includes the
+     threads for which the thread library allocated the stacks.  We
+     have to iterate over both lists separately.  We start with the
+     list of threads with user-defined stacks.  */
+
+  err = DB_GET_SYMBOL (list, ta, __stack_user);
+  if (err == TD_OK)
+    err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri, list, 1);
+
+  /* And the threads with stacks allocated by the implementation.  */
+  if (err == TD_OK)
+    err = DB_GET_SYMBOL (list, ta, stack_used);
+  if (err == TD_OK)
+    err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri, list, 0);
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_ta_tsd_iter.c b/libpthread/nptl_db/td_ta_tsd_iter.c
new file mode 100644 (file)
index 0000000..9cfb1e8
--- /dev/null
@@ -0,0 +1,81 @@
+/* Iterate over a process's thread-specific data.
+   Copyright (C) 1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <alloca.h>
+
+td_err_e
+td_ta_tsd_iter (const td_thragent_t *ta_arg, td_key_iter_f *callback,
+               void *cbdata_p)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  void *keys;
+  size_t keys_nb, keys_elemsize;
+  psaddr_t addr;
+  uint32_t idx;
+
+  LOG ("td_ta_tsd_iter");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* This makes sure we have the size information on hand.  */
+  addr = 0;
+  err = _td_locate_field (ta,
+                         ta->ta_var___pthread_keys, SYM_DESC___pthread_keys,
+                         (psaddr_t) 0 + 1, &addr);
+  if (err != TD_OK)
+    return err;
+
+  /* Now copy in the entire array of key descriptors.  */
+  keys_elemsize = (addr - (psaddr_t) 0) / 8;
+  keys_nb = keys_elemsize * DB_DESC_NELEM (ta->ta_var___pthread_keys);
+  keys = __alloca (keys_nb);
+  err = DB_GET_SYMBOL (addr, ta, __pthread_keys);
+  if (err != TD_OK)
+    return err;
+  if (ps_pdread (ta->ph, addr, keys, keys_nb) != PS_OK)
+    return TD_ERR;
+
+  /* Now get all descriptors, one after the other.  */
+  for (idx = 0; idx < DB_DESC_NELEM (ta->ta_var___pthread_keys); ++idx)
+    {
+      psaddr_t seq, destr;
+      err = DB_GET_FIELD_LOCAL (seq, ta, keys, pthread_key_struct, seq, 0);
+      if (err != TD_OK)
+       return err;
+      if (((uintptr_t) seq) & 1)
+       {
+         err = DB_GET_FIELD_LOCAL (destr, ta, keys, pthread_key_struct,
+                                   destr, 0);
+         if (err != TD_OK)
+           return err;
+         /* Return with an error if the callback returns a nonzero value.  */
+         if (callback ((thread_key_t) idx, destr, cbdata_p) != 0)
+           return TD_DBERR;
+       }
+      /* Advance to the next element in the copied array.  */
+      keys += keys_elemsize;
+    }
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_clear_event.c b/libpthread/nptl_db/td_thr_clear_event.c
new file mode 100644 (file)
index 0000000..fc999df
--- /dev/null
@@ -0,0 +1,77 @@
+/* Disable specific event for thread.
+   Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <stddef.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_clear_event (th, event)
+     const td_thrhandle_t *th;
+     td_thr_events_t *event;
+{
+  td_err_e err;
+  psaddr_t eventmask;
+  void *copy;
+
+  LOG ("td_thr_clear_event");
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_FIELD_ADDRESS (eventmask, th->th_ta_p,
+                             th->th_unique, pthread, eventbuf_eventmask, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, th->th_ta_p, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+       {
+         psaddr_t word;
+         uint32_t mask;
+         err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy,
+                                   td_thr_events_t, event_bits, idx);
+         if (err != TD_OK)
+           break;
+         mask = (uintptr_t) word;
+         mask &= ~event->event_bits[idx];
+         word = (psaddr_t) (uintptr_t) mask;
+         err = DB_PUT_FIELD_LOCAL (th->th_ta_p, copy,
+                                   td_thr_events_t, event_bits, idx, word);
+         if (err != TD_OK)
+           break;
+       }
+      if (err == TD_NOAPLIC)
+       {
+         err = TD_OK;
+         while (idx < TD_EVENTSIZE)
+           if (event->event_bits[idx++] != 0)
+             {
+               err = TD_NOEVENT;
+               break;
+             }
+       }
+      if (err == TD_OK)
+       /* Now write it back to the inferior.  */
+       err = DB_PUT_STRUCT (th->th_ta_p, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_thr_dbresume.c b/libpthread/nptl_db/td_thr_dbresume.c
new file mode 100644 (file)
index 0000000..3fd7943
--- /dev/null
@@ -0,0 +1,30 @@
+/* Resume execution of given thread.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_dbresume (const td_thrhandle_t *th)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_dbresume");
+  return TD_NOCAPAB;
+}
diff --git a/libpthread/nptl_db/td_thr_dbsuspend.c b/libpthread/nptl_db/td_thr_dbsuspend.c
new file mode 100644 (file)
index 0000000..6ef82ad
--- /dev/null
@@ -0,0 +1,30 @@
+/* Suspend execution of given thread.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_dbsuspend (const td_thrhandle_t *th)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_dbsuspend");
+  return TD_NOCAPAB;
+}
diff --git a/libpthread/nptl_db/td_thr_event_enable.c b/libpthread/nptl_db/td_thr_event_enable.c
new file mode 100644 (file)
index 0000000..a02be5d
--- /dev/null
@@ -0,0 +1,34 @@
+/* Enable event process-wide.
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_event_enable (th, onoff)
+     const td_thrhandle_t *th;
+     int onoff;
+{
+  LOG ("td_thr_event_enable");
+
+  /* Write the new value into the thread data structure.  */
+  return DB_PUT_FIELD (th->th_ta_p, th->th_unique, pthread, report_events, 0,
+                      (psaddr_t) 0 + (onoff != 0));
+}
diff --git a/libpthread/nptl_db/td_thr_event_getmsg.c b/libpthread/nptl_db/td_thr_event_getmsg.c
new file mode 100644 (file)
index 0000000..70ea695
--- /dev/null
@@ -0,0 +1,119 @@
+/* Retrieve event.
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <assert.h>
+
+
+td_err_e
+td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg)
+{
+  td_err_e err;
+  psaddr_t eventbuf, eventnum, eventdata;
+  psaddr_t thp, prevp;
+  void *copy;
+
+  LOG ("td_thr_event_getmsg");
+
+  /* Copy the event message buffer in from the inferior.  */
+  err = DB_GET_FIELD_ADDRESS (eventbuf, th->th_ta_p, th->th_unique, pthread,
+                             eventbuf, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, th->th_ta_p, eventbuf, td_eventbuf_t);
+  if (err != TD_OK)
+    return err;
+
+  /* Check whether an event occurred.  */
+  err = DB_GET_FIELD_LOCAL (eventnum, th->th_ta_p, copy,
+                           td_eventbuf_t, eventnum, 0);
+  if (err != TD_OK)
+    return err;
+  if ((int) (uintptr_t) eventnum == TD_EVENT_NONE)
+    /* Nothing.  */
+    return TD_NOMSG;
+
+  /* Fill the user's data structure.  */
+  err = DB_GET_FIELD_LOCAL (eventdata, th->th_ta_p, copy,
+                           td_eventbuf_t, eventdata, 0);
+  if (err != TD_OK)
+    return err;
+
+  msg->msg.data = (uintptr_t) eventdata;
+  msg->event = (uintptr_t) eventnum;
+  msg->th_p = th;
+
+  /* And clear the event message in the target.  */
+  memset (copy, 0, th->th_ta_p->ta_sizeof_td_eventbuf_t);
+  err = DB_PUT_STRUCT (th->th_ta_p, eventbuf, td_eventbuf_t, copy);
+  if (err != TD_OK)
+    return err;
+
+  /* Get the pointer to the thread descriptor with the last event.
+     If it doesn't match TH, then walk down the list until we find it.
+     We must splice it out of the list so that there is no dangling
+     pointer to it later when it dies.  */
+  err = DB_GET_SYMBOL (prevp, th->th_ta_p, __nptl_last_event);
+  if (err != TD_OK)
+    return err;
+  err = DB_GET_VALUE (thp, th->th_ta_p, __nptl_last_event, 0);
+  if (err != TD_OK)
+    return err;
+
+  while (thp != 0)
+    {
+      psaddr_t next;
+      err = DB_GET_FIELD (next, th->th_ta_p, th->th_unique, pthread,
+                         nextevent, 0);
+      if (err != TD_OK)
+       return err;
+
+      if (next == thp)
+       return TD_DBERR;
+
+      if (thp == th->th_unique)
+       {
+         /* PREVP points at this thread, splice it out.  */
+         psaddr_t next_nextp;
+         err = DB_GET_FIELD_ADDRESS (next_nextp, th->th_ta_p, next, pthread,
+                                     nextevent, 0);
+         assert (err == TD_OK); /* We used this field before.  */
+         if (prevp == next_nextp)
+           return TD_DBERR;
+
+         err = _td_store_value (th->th_ta_p,
+                                th->th_ta_p->ta_var___nptl_last_event, -1,
+                                0, prevp, next);
+         if (err != TD_OK)
+           return err;
+
+         /* Now clear this thread's own next pointer so it's not dangling
+            when the thread resumes and then chains on for its next event.  */
+         return DB_PUT_FIELD (th->th_ta_p, thp, pthread, nextevent, 0, 0);
+       }
+
+      err = DB_GET_FIELD_ADDRESS (prevp, th->th_ta_p, thp, pthread,
+                                 nextevent, 0);
+      assert (err == TD_OK); /* We used this field before.  */
+      thp = next;
+    }
+
+  /* Ack!  This should not happen.  */
+  return TD_DBERR;
+}
diff --git a/libpthread/nptl_db/td_thr_get_info.c b/libpthread/nptl_db/td_thr_get_info.c
new file mode 100644 (file)
index 0000000..bb13888
--- /dev/null
@@ -0,0 +1,110 @@
+/* Get thread information.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <stddef.h>
+#include <string.h>
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
+{
+  td_err_e err;
+  void *copy;
+  psaddr_t tls, schedpolicy, schedprio, cancelhandling, tid, report_events;
+
+  LOG ("td_thr_get_info");
+
+  /* Copy the whole descriptor in once so we can access the several
+     fields locally.  Excess copying in one go is much better than
+     multiple ps_pdread calls.  */
+  err = DB_GET_STRUCT (copy, th->th_ta_p, th->th_unique, pthread);
+  if (err != TD_OK)
+    return err;
+
+  err = DB_GET_FIELD_ADDRESS (tls, th->th_ta_p, th->th_unique,
+                             pthread, specific, 0);
+  if (err != TD_OK)
+    return err;
+
+  err = DB_GET_FIELD_LOCAL (schedpolicy, th->th_ta_p, copy, pthread,
+                           schedpolicy, 0);
+  if (err != TD_OK)
+    return err;
+  err = DB_GET_FIELD_LOCAL (schedprio, th->th_ta_p, copy, pthread,
+                           schedparam_sched_priority, 0);
+  if (err != TD_OK)
+    return err;
+  err = DB_GET_FIELD_LOCAL (tid, th->th_ta_p, copy, pthread, tid, 0);
+  if (err != TD_OK)
+    return err;
+  err = DB_GET_FIELD_LOCAL (cancelhandling, th->th_ta_p, copy, pthread,
+                           cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+  err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread,
+                           report_events, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Fill in information.  Clear first to provide reproducable
+     results for the fields we do not fill in.  */
+  memset (infop, '\0', sizeof (td_thrinfo_t));
+
+  infop->ti_tid = (thread_t) th->th_unique;
+  infop->ti_tls = (char *) tls;
+  infop->ti_pri = ((uintptr_t) schedpolicy == SCHED_OTHER
+                  ? 0 : (uintptr_t) schedprio);
+  infop->ti_type = TD_THR_USER;
+
+  if ((((int) (uintptr_t) cancelhandling) & EXITING_BITMASK) == 0)
+    /* XXX For now there is no way to get more information.  */
+    infop->ti_state = TD_THR_ACTIVE;
+  else if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0)
+    infop->ti_state = TD_THR_ZOMBIE;
+  else
+    infop->ti_state = TD_THR_UNKNOWN;
+
+  /* Initialization which are the same in both cases.  */
+  infop->ti_ta_p = th->th_ta_p;
+  infop->ti_lid = tid == 0 ? ps_getpid (th->th_ta_p->ph) : (uintptr_t) tid;
+  infop->ti_traceme = report_events != 0;
+
+  err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread,
+                           start_routine, 0);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+       {
+         psaddr_t word;
+         err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy, pthread,
+                                   eventbuf_eventmask_event_bits, idx);
+         if (err != TD_OK)
+           break;
+         infop->ti_events.event_bits[idx] = (uintptr_t) word;
+       }
+      if (err == TD_NOAPLIC)
+       memset (&infop->ti_events.event_bits[idx], 0,
+               (TD_EVENTSIZE - idx) * sizeof infop->ti_events.event_bits[0]);
+    }
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_thr_getfpregs.c b/libpthread/nptl_db/td_thr_getfpregs.c
new file mode 100644 (file)
index 0000000..7760512
--- /dev/null
@@ -0,0 +1,53 @@
+/* Get a thread's floating-point register set.
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_getfpregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+                     cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* If the thread already terminated we return all zeroes.  */
+  if (((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK)
+    memset (regset, '\0', sizeof (*regset));
+  /* Otherwise get the register content through the callback.  */
+  else
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+       return err;
+
+      if (ps_lgetfpregs (th->th_ta_p->ph, (uintptr_t) tid, regset) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_getgregs.c b/libpthread/nptl_db/td_thr_getgregs.c
new file mode 100644 (file)
index 0000000..4c2373e
--- /dev/null
@@ -0,0 +1,53 @@
+/* Get a thread's general register set.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_getgregs (const td_thrhandle_t *th, prgregset_t regset)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_getgregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+                     cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* If the thread already terminated we return all zeroes.  */
+  if (((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK)
+    memset (regset, '\0', sizeof (*regset));
+  /* Otherwise get the register content through the callback.  */
+  else
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+       return err;
+
+      if (ps_lgetregs (th->th_ta_p->ph, (uintptr_t) tid, regset) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_getxregs.c b/libpthread/nptl_db/td_thr_getxregs.c
new file mode 100644 (file)
index 0000000..3c77ab6
--- /dev/null
@@ -0,0 +1,30 @@
+/* Get a thread's extra state register set.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_getxregs (const td_thrhandle_t *th, void *xregs)
+{
+  /* XXX This might be platform specific.  */
+  LOG ("td_thr_getxregs");
+  return TD_NOXREGS;
+}
diff --git a/libpthread/nptl_db/td_thr_getxregsize.c b/libpthread/nptl_db/td_thr_getxregsize.c
new file mode 100644 (file)
index 0000000..1704e4b
--- /dev/null
@@ -0,0 +1,30 @@
+/* Get the size of the extra state register set for this architecture.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_getxregsize (const td_thrhandle_t *th, int *sizep)
+{
+  /* XXX This might be platform specific.  */
+  LOG ("td_thr_getxregsize");
+  return TD_NOXREGS;
+}
diff --git a/libpthread/nptl_db/td_thr_set_event.c b/libpthread/nptl_db/td_thr_set_event.c
new file mode 100644 (file)
index 0000000..2bb0b9d
--- /dev/null
@@ -0,0 +1,77 @@
+/* Enable specific event for thread.
+   Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <stddef.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_set_event (th, event)
+     const td_thrhandle_t *th;
+     td_thr_events_t *event;
+{
+  td_err_e err;
+  psaddr_t eventmask;
+  void *copy;
+
+  LOG ("td_thr_set_event");
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_FIELD_ADDRESS (eventmask, th->th_ta_p,
+                             th->th_unique, pthread, eventbuf_eventmask, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, th->th_ta_p, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+       {
+         psaddr_t word;
+         uint32_t mask;
+         err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy,
+                                   td_thr_events_t, event_bits, idx);
+         if (err != TD_OK)
+           break;
+         mask = (uintptr_t) word;
+         mask |= event->event_bits[idx];
+         word = (psaddr_t) (uintptr_t) mask;
+         err = DB_PUT_FIELD_LOCAL (th->th_ta_p, copy,
+                                   td_thr_events_t, event_bits, idx, word);
+         if (err != TD_OK)
+           break;
+       }
+      if (err == TD_NOAPLIC)
+       {
+         err = TD_OK;
+         while (idx < TD_EVENTSIZE)
+           if (event->event_bits[idx++] != 0)
+             {
+               err = TD_NOEVENT;
+               break;
+             }
+       }
+      if (err == TD_OK)
+       /* Now write it back to the inferior.  */
+       err = DB_PUT_STRUCT (th->th_ta_p, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_thr_setfpregs.c b/libpthread/nptl_db/td_thr_setfpregs.c
new file mode 100644 (file)
index 0000000..01bdb53
--- /dev/null
@@ -0,0 +1,50 @@
+/* Set a thread's floating-point register set.
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_setfpregs (const td_thrhandle_t *th, const prfpregset_t *fpregs)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_setfpregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+                     cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Only set the registers if the thread hasn't yet terminated.  */
+  if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0)
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+       return err;
+
+      if (ps_lsetfpregs (th->th_ta_p->ph, (uintptr_t) tid, fpregs) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_setgregs.c b/libpthread/nptl_db/td_thr_setgregs.c
new file mode 100644 (file)
index 0000000..2a9ce7e
--- /dev/null
@@ -0,0 +1,50 @@
+/* Set a thread's general register set.
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_setgregs (const td_thrhandle_t *th, prgregset_t gregs)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_setgregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+                     cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Only set the registers if the thread hasn't yet terminated.  */
+  if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0)
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+       return err;
+
+      if (ps_lsetregs (th->th_ta_p->ph, tid - (psaddr_t) 0, gregs) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_setprio.c b/libpthread/nptl_db/td_thr_setprio.c
new file mode 100644 (file)
index 0000000..6032b0e
--- /dev/null
@@ -0,0 +1,30 @@
+/* Set a thread's priority.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_setprio (const td_thrhandle_t *th, int prio)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_setprio");
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_setsigpending.c b/libpthread/nptl_db/td_thr_setsigpending.c
new file mode 100644 (file)
index 0000000..e2c9d7a
--- /dev/null
@@ -0,0 +1,31 @@
+/* Raise a signal for a thread.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_setsigpending (const td_thrhandle_t *th, unsigned char n,
+                     const sigset_t *ss)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_setsigpending");
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_setxregs.c b/libpthread/nptl_db/td_thr_setxregs.c
new file mode 100644 (file)
index 0000000..f48877c
--- /dev/null
@@ -0,0 +1,30 @@
+/* Set a thread's extra state register set.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_setxregs (const td_thrhandle_t *ta, const void *addr)
+{
+  /* XXX This might have to be platform specific.  */
+  LOG ("td_thr_setxregs");
+  return TD_NOXREGS;
+}
diff --git a/libpthread/nptl_db/td_thr_sigsetmask.c b/libpthread/nptl_db/td_thr_sigsetmask.c
new file mode 100644 (file)
index 0000000..3a68aec
--- /dev/null
@@ -0,0 +1,30 @@
+/* Set a thread's signal mask.
+   Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_sigsetmask (const td_thrhandle_t *th, const sigset_t *ss)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_sigsetmask");
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_tls_get_addr.c b/libpthread/nptl_db/td_thr_tls_get_addr.c
new file mode 100644 (file)
index 0000000..e7d2322
--- /dev/null
@@ -0,0 +1,43 @@
+/* Get address of thread local variable.
+   Copyright (C) 2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.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 <link.h>
+#include "thread_dbP.h"
+
+td_err_e
+td_thr_tls_get_addr (const td_thrhandle_t *th,
+                    psaddr_t map_address, size_t offset, psaddr_t *address)
+{
+  td_err_e err;
+  psaddr_t modid;
+
+  /* Get the TLS module ID from the `struct link_map' in the inferior.  */
+  err = DB_GET_FIELD (modid, th->th_ta_p, map_address, link_map,
+                     l_tls_modid, 0);
+  if (err == TD_NOCAPAB)
+    return TD_NOAPLIC;
+  if (err == TD_OK)
+    {
+      err = td_thr_tlsbase (th, (uintptr_t) modid, address);
+      if (err == TD_OK)
+       *address += offset;
+    }
+  return err;
+}
diff --git a/libpthread/nptl_db/td_thr_tlsbase.c b/libpthread/nptl_db/td_thr_tlsbase.c
new file mode 100644 (file)
index 0000000..c57009a
--- /dev/null
@@ -0,0 +1,50 @@
+/* Locate TLS data for a thread.
+   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"
+
+td_err_e
+td_thr_tlsbase (const td_thrhandle_t *th,
+               unsigned long int modid,
+               psaddr_t *base)
+{
+  td_err_e err;
+  psaddr_t dtv, dtvptr;
+
+  if (modid < 1)
+    return TD_NOTLS;
+
+  /* Get the DTV pointer from the thread descriptor.  */
+  err = DB_GET_FIELD (dtv, th->th_ta_p, th->th_unique, pthread, dtvp, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Get the corresponding entry in the DTV.  */
+  err = DB_GET_FIELD (dtvptr, th->th_ta_p, dtv, dtv, dtv, modid);
+  if (err != TD_OK)
+    return err;
+
+  /* It could be that the memory for this module is not allocated for
+     the given thread.  */
+  if ((uintptr_t) dtvptr & 1)
+    return TD_TLSDEFER;
+
+  *base = dtvptr;
+  return TD_OK;
+}
diff --git a/libpthread/nptl_db/td_thr_tsd.c b/libpthread/nptl_db/td_thr_tsd.c
new file mode 100644 (file)
index 0000000..08f617b
--- /dev/null
@@ -0,0 +1,96 @@
+/* Get a thread-specific data pointer for a thread.
+   Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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"
+
+
+td_err_e
+td_thr_tsd (const td_thrhandle_t *th, const thread_key_t tk, void **data)
+{
+  td_err_e err;
+  psaddr_t tk_seq, level1, level2, seq, value;
+  void *copy;
+  uint32_t pthread_key_2ndlevel_size, idx1st, idx2nd;
+
+  LOG ("td_thr_tsd");
+
+  /* Get the key entry.  */
+  err = DB_GET_VALUE (tk_seq, th->th_ta_p, __pthread_keys, tk);
+  if (err == TD_NOAPLIC)
+    return TD_BADKEY;
+  if (err != TD_OK)
+    return err;
+
+  /* Fail if this key is not at all used.  */
+  if (((uintptr_t) tk_seq & 1) == 0)
+    return TD_BADKEY;
+
+  /* This makes sure we have the size information on hand.  */
+  err = DB_GET_FIELD_ADDRESS (level2, th->th_ta_p, 0, pthread_key_data_level2,
+                             data, 1);
+  if (err != TD_OK)
+    return err;
+
+  /* Compute the indeces.  */
+  pthread_key_2ndlevel_size
+    = DB_DESC_NELEM (th->th_ta_p->ta_field_pthread_key_data_level2_data);
+  idx1st = tk / pthread_key_2ndlevel_size;
+  idx2nd = tk % pthread_key_2ndlevel_size;
+
+  /* Now fetch the first level pointer.  */
+  err = DB_GET_FIELD (level1, th->th_ta_p, th->th_unique, pthread,
+                     specific, idx1st);
+  if (err == TD_NOAPLIC)
+    return TD_DBERR;
+  if (err != TD_OK)
+    return err;
+
+  /* Check the pointer to the second level array.  */
+  if (level1 == 0)
+    return TD_NOTSD;
+
+  /* Locate the element within the second level array.  */
+  err = DB_GET_FIELD_ADDRESS (level2, th->th_ta_p,
+                             level1, pthread_key_data_level2, data, idx2nd);
+  if (err == TD_NOAPLIC)
+    return TD_DBERR;
+  if (err != TD_OK)
+    return err;
+
+  /* Now copy in that whole structure.  */
+  err = DB_GET_STRUCT (copy, th->th_ta_p, level2, pthread_key_data);
+  if (err != TD_OK)
+    return err;
+
+  /* Check whether the data is valid.  */
+  err = DB_GET_FIELD_LOCAL (seq, th->th_ta_p, copy, pthread_key_data, seq, 0);
+  if (err != TD_OK)
+    return err;
+  if (seq != tk_seq)
+    return TD_NOTSD;
+
+  /* Finally, fetch the value.  */
+  err = DB_GET_FIELD_LOCAL (value, th->th_ta_p, copy, pthread_key_data,
+                           data, 0);
+  if (err == TD_OK)
+    *data = value;
+
+  return err;
+}
diff --git a/libpthread/nptl_db/td_thr_validate.c b/libpthread/nptl_db/td_thr_validate.c
new file mode 100644 (file)
index 0000000..3d560a6
--- /dev/null
@@ -0,0 +1,91 @@
+/* Validate a thread handle.
+   Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   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 <stdbool.h>
+
+static td_err_e
+check_thread_list (const td_thrhandle_t *th, psaddr_t head, bool *uninit)
+{
+  td_err_e err;
+  psaddr_t next, ofs;
+
+  err = DB_GET_FIELD (next, th->th_ta_p, head, list_t, next, 0);
+  if (err == TD_OK)
+    {
+      if (next == 0)
+       {
+         *uninit = true;
+         return TD_NOTHR;
+       }
+      err = DB_GET_FIELD_ADDRESS (ofs, th->th_ta_p, 0, pthread, list, 0);
+    }
+
+  while (err == TD_OK)
+    {
+      if (next == head)
+       return TD_NOTHR;
+
+      if (next - (ofs - (psaddr_t) 0) == th->th_unique)
+       return TD_OK;
+
+      err = DB_GET_FIELD (next, th->th_ta_p, next, list_t, next, 0);
+    }
+
+  return err;
+}
+
+
+td_err_e
+td_thr_validate (const td_thrhandle_t *th)
+{
+  td_err_e err;
+  psaddr_t list;
+
+  LOG ("td_thr_validate");
+
+  /* First check the list with threads using user allocated stacks.  */
+  bool uninit = false;
+  err = DB_GET_SYMBOL (list, th->th_ta_p, __stack_user);
+  if (err == TD_OK)
+    err = check_thread_list (th, list, &uninit);
+
+  /* If our thread is not on this list search the list with stack
+     using implementation allocated stacks.  */
+  if (err == TD_NOTHR)
+    {
+      err = DB_GET_SYMBOL (list, th->th_ta_p, stack_used);
+      if (err == TD_OK)
+       err = check_thread_list (th, list, &uninit);
+
+      if (err == TD_NOTHR && uninit)
+       {
+         /* __pthread_initialize_minimal has not run yet.
+            But the main thread still has a valid ID.  */
+         td_thrhandle_t main_th;
+         err = td_ta_map_lwp2thr (th->th_ta_p,
+                                  ps_getpid (th->th_ta_p->ph), &main_th);
+         if (err == TD_OK && th->th_unique != main_th.th_unique)
+           err = TD_NOTHR;
+       }
+    }
+
+  return err;
+}
diff --git a/libpthread/nptl_db/thread_db.h b/libpthread/nptl_db/thread_db.h
new file mode 100644 (file)
index 0000000..433b54f
--- /dev/null
@@ -0,0 +1,459 @@
+/* thread_db.h -- interface to libthread_db.so library for debugging -lpthread
+   Copyright (C) 1999,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.
+
+   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 _THREAD_DB_H
+#define _THREAD_DB_H   1
+
+/* This is the debugger interface for the NPTL library.  It is
+   modelled closely after the interface with same names in Solaris
+   with the goal to share the same code in the debugger.  */
+#include <pthread.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+
+
+/* Error codes of the library.  */
+typedef enum
+{
+  TD_OK,         /* No error.  */
+  TD_ERR,        /* No further specified error.  */
+  TD_NOTHR,      /* No matching thread found.  */
+  TD_NOSV,       /* No matching synchronization handle found.  */
+  TD_NOLWP,      /* No matching light-weighted process found.  */
+  TD_BADPH,      /* Invalid process handle.  */
+  TD_BADTH,      /* Invalid thread handle.  */
+  TD_BADSH,      /* Invalid synchronization handle.  */
+  TD_BADTA,      /* Invalid thread agent.  */
+  TD_BADKEY,     /* Invalid key.  */
+  TD_NOMSG,      /* No event available.  */
+  TD_NOFPREGS,   /* No floating-point register content available.  */
+  TD_NOLIBTHREAD, /* Application not linked with thread library.  */
+  TD_NOEVENT,    /* Requested event is not supported.  */
+  TD_NOCAPAB,    /* Capability not available.  */
+  TD_DBERR,      /* Internal debug library error.  */
+  TD_NOAPLIC,    /* Operation is not applicable.  */
+  TD_NOTSD,      /* No thread-specific data available.  */
+  TD_MALLOC,     /* Out of memory.  */
+  TD_PARTIALREG,  /* Not entire register set was read or written.  */
+  TD_NOXREGS,    /* X register set not available for given thread.  */
+  TD_TLSDEFER,   /* Thread has not yet allocated TLS for given module.  */
+  TD_NOTALLOC = TD_TLSDEFER,
+  TD_VERSION,    /* Version if libpthread and libthread_db do not match.  */
+  TD_NOTLS       /* There is no TLS segment in the given module.  */
+} td_err_e;
+
+
+/* Possible thread states.  TD_THR_ANY_STATE is a pseudo-state used to
+   select threads regardless of state in td_ta_thr_iter().  */
+typedef enum
+{
+  TD_THR_ANY_STATE,
+  TD_THR_UNKNOWN,
+  TD_THR_STOPPED,
+  TD_THR_RUN,
+  TD_THR_ACTIVE,
+  TD_THR_ZOMBIE,
+  TD_THR_SLEEP,
+  TD_THR_STOPPED_ASLEEP
+} td_thr_state_e;
+
+/* Thread type: user or system.  TD_THR_ANY_TYPE is a pseudo-type used
+   to select threads regardless of type in td_ta_thr_iter().  */
+typedef enum
+{
+  TD_THR_ANY_TYPE,
+  TD_THR_USER,
+  TD_THR_SYSTEM
+} td_thr_type_e;
+
+
+/* Types of the debugging library.  */
+
+/* Handle for a process.  This type is opaque.  */
+typedef struct td_thragent td_thragent_t;
+
+/* The actual thread handle type.  This is also opaque.  */
+typedef struct td_thrhandle
+{
+  td_thragent_t *th_ta_p;
+  psaddr_t th_unique;
+} td_thrhandle_t;
+
+
+/* Forward declaration of a type defined by and for the dynamic linker.  */
+struct link_map;
+
+
+/* Flags for `td_ta_thr_iter'.  */
+#define TD_THR_ANY_USER_FLAGS  0xffffffff
+#define TD_THR_LOWEST_PRIORITY -20
+#define TD_SIGNO_MASK          NULL
+
+
+#define TD_EVENTSIZE   2
+#define BT_UISHIFT     5 /* log base 2 of BT_NBIPUI, to extract word index */
+#define BT_NBIPUI      (1 << BT_UISHIFT)       /* n bits per uint */
+#define BT_UIMASK      (BT_NBIPUI - 1)         /* to extract bit index */
+
+/* Bitmask of enabled events. */
+typedef struct td_thr_events
+{
+  uint32_t event_bits[TD_EVENTSIZE];
+} td_thr_events_t;
+
+/* Event set manipulation macros. */
+#define __td_eventmask(n) \
+  (UINT32_C (1) << (((n) - 1) & BT_UIMASK))
+#define __td_eventword(n) \
+  ((UINT32_C ((n) - 1)) >> BT_UISHIFT)
+
+#define td_event_emptyset(setp) \
+  do {                                                                       \
+    int __i;                                                                 \
+    for (__i = TD_EVENTSIZE; __i > 0; --__i)                                 \
+      (setp)->event_bits[__i - 1] = 0;                                       \
+  } while (0)
+
+#define td_event_fillset(setp) \
+  do {                                                                       \
+    int __i;                                                                 \
+    for (__i = TD_EVENTSIZE; __i > 0; --__i)                                 \
+      (setp)->event_bits[__i - 1] = UINT32_C (0xffffffff);                   \
+  } while (0)
+
+#define td_event_addset(setp, n) \
+  (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n))
+#define td_event_delset(setp, n) \
+  (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n))
+#define td_eventismember(setp, n) \
+  (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)]))
+#if TD_EVENTSIZE == 2
+# define td_eventisempty(setp) \
+  (!((setp)->event_bits[0]) && !((setp)->event_bits[1]))
+#else
+# error "td_eventisempty must be changed to match TD_EVENTSIZE"
+#endif
+
+/* Events reportable by the thread implementation.  */
+typedef enum
+{
+  TD_ALL_EVENTS,                /* Pseudo-event number.  */
+  TD_EVENT_NONE = TD_ALL_EVENTS, /* Depends on context.  */
+  TD_READY,                     /* Is executable now. */
+  TD_SLEEP,                     /* Blocked in a synchronization obj.  */
+  TD_SWITCHTO,                  /* Now assigned to a process.  */
+  TD_SWITCHFROM,                /* Not anymore assigned to a process.  */
+  TD_LOCK_TRY,                  /* Trying to get an unavailable lock.  */
+  TD_CATCHSIG,                  /* Signal posted to the thread.  */
+  TD_IDLE,                      /* Process getting idle.  */
+  TD_CREATE,                    /* New thread created.  */
+  TD_DEATH,                     /* Thread terminated.  */
+  TD_PREEMPT,                   /* Preempted.  */
+  TD_PRI_INHERIT,               /* Inherited elevated priority.  */
+  TD_REAP,                      /* Reaped.  */
+  TD_CONCURRENCY,               /* Number of processes changing.  */
+  TD_TIMEOUT,                   /* Conditional variable wait timed out.  */
+  TD_MIN_EVENT_NUM = TD_READY,
+  TD_MAX_EVENT_NUM = TD_TIMEOUT,
+  TD_EVENTS_ENABLE = 31                /* Event reporting enabled.  */
+} td_event_e;
+
+/* Values representing the different ways events are reported.  */
+typedef enum
+{
+  NOTIFY_BPT,                  /* User must insert breakpoint at u.bptaddr. */
+  NOTIFY_AUTOBPT,              /* Breakpoint at u.bptaddr is automatically
+                                  inserted.  */
+  NOTIFY_SYSCALL               /* System call u.syscallno will be invoked.  */
+} td_notify_e;
+
+/* Description how event type is reported.  */
+typedef struct td_notify
+{
+  td_notify_e type;            /* Way the event is reported.  */
+  union
+  {
+    psaddr_t bptaddr;          /* Address of breakpoint.  */
+    int syscallno;             /* Number of system call used.  */
+  } u;
+} td_notify_t;
+
+/* Structure used to report event.  */
+typedef struct td_event_msg
+{
+  td_event_e event;            /* Event type being reported.  */
+  const td_thrhandle_t *th_p;  /* Thread reporting the event.  */
+  union
+  {
+# if 0
+    td_synchandle_t *sh;       /* Handle of synchronization object.  */
+#endif
+    uintptr_t data;            /* Event specific data.  */
+  } msg;
+} td_event_msg_t;
+
+/* Structure containing event data available in each thread structure.  */
+typedef struct
+{
+  td_thr_events_t eventmask;   /* Mask of enabled events.  */
+  td_event_e eventnum;         /* Number of last event.  */
+  void *eventdata;             /* Data associated with event.  */
+} td_eventbuf_t;
+
+
+/* Gathered statistics about the process.  */
+typedef struct td_ta_stats
+{
+  int nthreads;                /* Total number of threads in use.  */
+  int r_concurrency;           /* Concurrency level requested by user.  */
+  int nrunnable_num;           /* Average runnable threads, numerator.  */
+  int nrunnable_den;           /* Average runnable threads, denominator.  */
+  int a_concurrency_num;       /* Achieved concurrency level, numerator.  */
+  int a_concurrency_den;       /* Achieved concurrency level, denominator.  */
+  int nlwps_num;               /* Average number of processes in use,
+                                  numerator.  */
+  int nlwps_den;               /* Average number of processes in use,
+                                  denominator.  */
+  int nidle_num;               /* Average number of idling processes,
+                                  numerator.  */
+  int nidle_den;               /* Average number of idling processes,
+                                  denominator.  */
+} td_ta_stats_t;
+
+
+/* Since Sun's library is based on Solaris threads we have to define a few
+   types to map them to POSIX threads.  */
+typedef pthread_t thread_t;
+typedef pthread_key_t thread_key_t;
+
+
+/* Callback for iteration over threads.  */
+typedef int td_thr_iter_f (const td_thrhandle_t *, void *);
+
+/* Callback for iteration over thread local data.  */
+typedef int td_key_iter_f (thread_key_t, void (*) (void *), void *);
+
+
+
+/* Forward declaration.  This has to be defined by the user.  */
+struct ps_prochandle;
+
+
+/* Information about the thread.  */
+typedef struct td_thrinfo
+{
+  td_thragent_t *ti_ta_p;              /* Process handle.  */
+  unsigned int ti_user_flags;          /* Unused.  */
+  thread_t ti_tid;                     /* Thread ID returned by
+                                          pthread_create().  */
+  char *ti_tls;                                /* Pointer to thread-local data.  */
+  psaddr_t ti_startfunc;               /* Start function passed to
+                                          pthread_create().  */
+  psaddr_t ti_stkbase;                 /* Base of thread's stack.  */
+  long int ti_stksize;                 /* Size of thread's stack.  */
+  psaddr_t ti_ro_area;                 /* Unused.  */
+  int ti_ro_size;                      /* Unused.  */
+  td_thr_state_e ti_state;             /* Thread state.  */
+  unsigned char ti_db_suspended;       /* Nonzero if suspended by debugger. */
+  td_thr_type_e ti_type;               /* Type of the thread (system vs
+                                          user thread).  */
+  intptr_t ti_pc;                      /* Unused.  */
+  intptr_t ti_sp;                      /* Unused.  */
+  short int ti_flags;                  /* Unused.  */
+  int ti_pri;                          /* Thread priority.  */
+  lwpid_t ti_lid;                      /* Kernel PID for this thread.  */
+  sigset_t ti_sigmask;                 /* Signal mask.  */
+  unsigned char ti_traceme;            /* Nonzero if event reporting
+                                          enabled.  */
+  unsigned char ti_preemptflag;                /* Unused.  */
+  unsigned char ti_pirecflag;          /* Unused.  */
+  sigset_t ti_pending;                 /* Set of pending signals.  */
+  td_thr_events_t ti_events;           /* Set of enabled events.  */
+} td_thrinfo_t;
+
+
+
+/* Prototypes for exported library functions.  */
+
+/* Initialize the thread debug support library.  */
+extern td_err_e td_init (void);
+
+/* Historical relict.  Should not be used anymore.  */
+extern td_err_e td_log (void);
+
+/* Return list of symbols the library can request.  */
+extern const char **td_symbol_list (void);
+
+/* Generate new thread debug library handle for process PS.  */
+extern td_err_e td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta);
+
+/* Free resources allocated for TA.  */
+extern td_err_e td_ta_delete (td_thragent_t *__ta);
+
+/* Get number of currently running threads in process associated with TA.  */
+extern td_err_e td_ta_get_nthreads (const td_thragent_t *__ta, int *__np);
+
+/* Return process handle passed in `td_ta_new' for process associated with
+   TA.  */
+extern td_err_e td_ta_get_ph (const td_thragent_t *__ta,
+                             struct ps_prochandle **__ph);
+
+/* Map thread library handle PT to thread debug library handle for process
+   associated with TA and store result in *TH.  */
+extern td_err_e td_ta_map_id2thr (const td_thragent_t *__ta, pthread_t __pt,
+                                 td_thrhandle_t *__th);
+
+/* Map process ID LWPID to thread debug library handle for process
+   associated with TA and store result in *TH.  */
+extern td_err_e td_ta_map_lwp2thr (const td_thragent_t *__ta, lwpid_t __lwpid,
+                                  td_thrhandle_t *__th);
+
+
+/* Call for each thread in a process associated with TA the callback function
+   CALLBACK.  */
+extern td_err_e td_ta_thr_iter (const td_thragent_t *__ta,
+                               td_thr_iter_f *__callback, void *__cbdata_p,
+                               td_thr_state_e __state, int __ti_pri,
+                               sigset_t *__ti_sigmask_p,
+                               unsigned int __ti_user_flags);
+
+/* Call for each defined thread local data entry the callback function KI.  */
+extern td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki,
+                               void *__p);
+
+
+/* Get event address for EVENT.  */
+extern td_err_e td_ta_event_addr (const td_thragent_t *__ta,
+                                 td_event_e __event, td_notify_t *__ptr);
+
+/* Enable EVENT in global mask.  */
+extern td_err_e td_ta_set_event (const td_thragent_t *__ta,
+                                td_thr_events_t *__event);
+
+/* Disable EVENT in global mask.  */
+extern td_err_e td_ta_clear_event (const td_thragent_t *__ta,
+                                  td_thr_events_t *__event);
+
+/* Return information about last event.  */
+extern td_err_e td_ta_event_getmsg (const td_thragent_t *__ta,
+                                   td_event_msg_t *__msg);
+
+
+/* Set suggested concurrency level for process associated with TA.  */
+extern td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level);
+
+
+/* Enable collecting statistics for process associated with TA.  */
+extern td_err_e td_ta_enable_stats (const td_thragent_t *__ta, int __enable);
+
+/* Reset statistics.  */
+extern td_err_e td_ta_reset_stats (const td_thragent_t *__ta);
+
+/* Retrieve statistics from process associated with TA.  */
+extern td_err_e td_ta_get_stats (const td_thragent_t *__ta,
+                                td_ta_stats_t *__statsp);
+
+
+/* Validate that TH is a thread handle.  */
+extern td_err_e td_thr_validate (const td_thrhandle_t *__th);
+
+/* Return information about thread TH.  */
+extern td_err_e td_thr_get_info (const td_thrhandle_t *__th,
+                                td_thrinfo_t *__infop);
+
+/* Retrieve floating-point register contents of process running thread TH.  */
+extern td_err_e td_thr_getfpregs (const td_thrhandle_t *__th,
+                                 prfpregset_t *__regset);
+
+/* Retrieve general register contents of process running thread TH.  */
+extern td_err_e td_thr_getgregs (const td_thrhandle_t *__th,
+                                prgregset_t __gregs);
+
+/* Retrieve extended register contents of process running thread TH.  */
+extern td_err_e td_thr_getxregs (const td_thrhandle_t *__th, void *__xregs);
+
+/* Get size of extended register set of process running thread TH.  */
+extern td_err_e td_thr_getxregsize (const td_thrhandle_t *__th, int *__sizep);
+
+/* Set floating-point register contents of process running thread TH.  */
+extern td_err_e td_thr_setfpregs (const td_thrhandle_t *__th,
+                                 const prfpregset_t *__fpregs);
+
+/* Set general register contents of process running thread TH.  */
+extern td_err_e td_thr_setgregs (const td_thrhandle_t *__th,
+                                prgregset_t __gregs);
+
+/* Set extended register contents of process running thread TH.  */
+extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th,
+                                const void *__addr);
+
+
+/* Get address of the given module's TLS storage area for the given thread.  */
+extern td_err_e td_thr_tlsbase (const td_thrhandle_t *__th,
+                               unsigned long int __modid,
+                               psaddr_t *__base);
+
+/* Get address of thread local variable.  */
+extern td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th,
+                                    psaddr_t __map_address, size_t __offset,
+                                    psaddr_t *__address);
+
+
+/* Enable reporting for EVENT for thread TH.  */
+extern td_err_e td_thr_event_enable (const td_thrhandle_t *__th, int __event);
+
+/* Enable EVENT for thread TH.  */
+extern td_err_e td_thr_set_event (const td_thrhandle_t *__th,
+                                 td_thr_events_t *__event);
+
+/* Disable EVENT for thread TH.  */
+extern td_err_e td_thr_clear_event (const td_thrhandle_t *__th,
+                                   td_thr_events_t *__event);
+
+/* Get event message for thread TH.  */
+extern td_err_e td_thr_event_getmsg (const td_thrhandle_t *__th,
+                                    td_event_msg_t *__msg);
+
+
+/* Set priority of thread TH.  */
+extern td_err_e td_thr_setprio (const td_thrhandle_t *__th, int __prio);
+
+
+/* Set pending signals for thread TH.  */
+extern td_err_e td_thr_setsigpending (const td_thrhandle_t *__th,
+                                     unsigned char __n, const sigset_t *__ss);
+
+/* Set signal mask for thread TH.  */
+extern td_err_e td_thr_sigsetmask (const td_thrhandle_t *__th,
+                                  const sigset_t *__ss);
+
+
+/* Return thread local data associated with key TK in thread TH.  */
+extern td_err_e td_thr_tsd (const td_thrhandle_t *__th,
+                           const thread_key_t __tk, void **__data);
+
+
+/* Suspend execution of thread TH.  */
+extern td_err_e td_thr_dbsuspend (const td_thrhandle_t *__th);
+
+/* Resume execution of thread TH.  */
+extern td_err_e td_thr_dbresume (const td_thrhandle_t *__th);
+
+#endif /* thread_db.h */
diff --git a/libpthread/nptl_db/thread_dbP.h b/libpthread/nptl_db/thread_dbP.h
new file mode 100644 (file)
index 0000000..c53d1ed
--- /dev/null
@@ -0,0 +1,254 @@
+/* Private header for thread debug library
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _THREAD_DBP_H
+#define _THREAD_DBP_H  1
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include "proc_service.h"
+#include "thread_db.h"
+#include "../nptl/pthreadP.h"          /* This is for *_BITMASK only.  */
+
+/* Indeces for the symbol names.  */
+enum
+  {
+# define DB_STRUCT(type)               SYM_SIZEOF_##type,
+# define DB_STRUCT_FIELD(type, field)  SYM_##type##_FIELD_##field,
+# define DB_SYMBOL(name)               SYM_##name,
+# define DB_FUNCTION(name)             SYM_##name,
+# define DB_VARIABLE(name)             SYM_##name, SYM_DESC_##name,
+# include "structs.def"
+# undef DB_STRUCT
+# undef DB_STRUCT_FIELD
+# undef DB_SYMBOL
+# undef DB_FUNCTION
+# undef DB_VARIABLE
+
+    SYM_TH_UNIQUE_CONST_THREAD_AREA,
+    SYM_TH_UNIQUE_REGISTER64,
+    SYM_TH_UNIQUE_REGISTER32,
+    SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+    SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+
+    SYM_NUM_MESSAGES
+  };
+
+
+/* Comment out the following for less verbose output.  */
+#ifndef NDEBUG
+# define LOG(c) if (__td_debug) write (2, c "\n", strlen (c "\n"))
+extern int __td_debug attribute_hidden;
+#else
+# define LOG(c)
+#endif
+
+
+#define DB_DESC_SIZE(desc)     ((desc)[0])
+#define DB_DESC_NELEM(desc)    ((desc)[1])
+#define DB_DESC_OFFSET(desc)   ((desc)[2])
+#define DB_SIZEOF_DESC         (3 * sizeof (uint32_t))
+#define DB_DEFINE_DESC(name, size, nelem, offset) \
+  const uint32_t name[3] = { (size), (nelem), (offset) }
+typedef uint32_t db_desc_t[3];
+
+
+/* Handle for a process.  This type is opaque.  */
+struct td_thragent
+{
+  /* Chain on the list of all agent structures.  */
+  list_t list;
+
+  /* Delivered by the debugger and we have to pass it back in the
+     proc callbacks.  */
+  struct ps_prochandle *ph;
+
+  /* Cached values read from the inferior.  */
+# define DB_STRUCT(type) \
+  uint32_t ta_sizeof_##type;
+# define DB_STRUCT_FIELD(type, field) \
+  db_desc_t ta_field_##type##_##field;
+# define DB_SYMBOL(name) \
+  psaddr_t ta_addr_##name;
+# define DB_FUNCTION(name) \
+  psaddr_t ta_addr_##name;
+# define DB_VARIABLE(name) \
+  psaddr_t ta_addr_##name; \
+  db_desc_t ta_var_##name;
+# include "structs.def"
+# undef DB_STRUCT
+# undef DB_STRUCT_FIELD
+# undef DB_FUNCTION
+# undef DB_SYMBOL
+# undef DB_VARIABLE
+
+  /* The method of locating a thread's th_unique value.  */
+  enum
+    {
+      ta_howto_unknown,
+      ta_howto_reg,
+      ta_howto_reg_thread_area,
+      ta_howto_const_thread_area
+    } ta_howto;
+  union
+  {
+    uint32_t const_thread_area;        /* Constant argument to ps_get_thread_area.  */
+    /* These are as if the descriptor of the field in prregset_t,
+       but DB_DESC_NELEM is overloaded as follows: */
+    db_desc_t reg;             /* Signed bias applied to register value.  */
+    db_desc_t reg_thread_area; /* Bits to scale down register value.  */
+  } ta_howto_data;
+};
+
+
+/* List of all known descriptors.  */
+extern list_t __td_agent_list attribute_hidden;
+
+
+/* Function used to test for correct thread agent pointer.  */
+static inline bool
+ta_ok (const td_thragent_t *ta)
+{
+  list_t *runp;
+
+  list_for_each (runp, &__td_agent_list)
+    if (list_entry (runp, td_thragent_t, list) == ta)
+      return true;
+
+  return false;
+}
+
+
+/* Internal wrapper around ps_pglobal_lookup.  */
+extern ps_err_e td_lookup (struct ps_prochandle *ps,
+                          int idx, psaddr_t *sym_addr) attribute_hidden;
+
+
+
+
+/* Store in psaddr_t VAR the address of inferior's symbol NAME.  */
+#define DB_GET_SYMBOL(var, ta, name)                                         \
+  (((ta)->ta_addr_##name == 0                                                \
+    && td_lookup ((ta)->ph, SYM_##name, &(ta)->ta_addr_##name) != PS_OK)      \
+   ? TD_ERR : ((var) = (ta)->ta_addr_##name, TD_OK))
+
+/* Store in psaddr_t VAR the value of ((TYPE) PTR)->FIELD[IDX] in the inferior.
+   A target field smaller than psaddr_t is zero-extended.  */
+#define DB_GET_FIELD(var, ta, ptr, type, field, idx) \
+  _td_fetch_value ((ta), (ta)->ta_field_##type##_##field, \
+                  SYM_##type##_FIELD_##field, \
+                  (psaddr_t) 0 + (idx), (ptr), &(var))
+
+#define DB_GET_FIELD_ADDRESS(var, ta, ptr, type, field, idx) \
+  ((var) = (ptr), _td_locate_field ((ta), (ta)->ta_field_##type##_##field, \
+                                   SYM_##type##_FIELD_##field, \
+                                   (psaddr_t) 0 + (idx), &(var)))
+
+extern td_err_e _td_locate_field (td_thragent_t *ta,
+                                 db_desc_t desc, int descriptor_name,
+                                 psaddr_t idx,
+                                 psaddr_t *address) attribute_hidden;
+
+
+/* Like DB_GET_FIELD, but PTR is a local pointer to a structure that
+   has already been copied in from the inferior.  */
+#define DB_GET_FIELD_LOCAL(var, ta, ptr, type, field, idx) \
+  _td_fetch_value_local ((ta), (ta)->ta_field_##type##_##field, \
+                        SYM_##type##_FIELD_##field, \
+                        (psaddr_t) 0 + (idx), (ptr), &(var))
+
+/* Store in psaddr_t VAR the value of variable NAME[IDX] in the inferior.
+   A target value smaller than psaddr_t is zero-extended.  */
+#define DB_GET_VALUE(var, ta, name, idx)                                     \
+  (((ta)->ta_addr_##name == 0                                                \
+    && td_lookup ((ta)->ph, SYM_##name, &(ta)->ta_addr_##name) != PS_OK)      \
+   ? TD_ERR                                                                  \
+   : _td_fetch_value ((ta), (ta)->ta_var_##name, SYM_DESC_##name,            \
+                     (psaddr_t) 0 + (idx), (ta)->ta_addr_##name, &(var)))
+
+/* Helper functions for those.  */
+extern td_err_e _td_fetch_value (td_thragent_t *ta,
+                                db_desc_t field, int descriptor_name,
+                                psaddr_t idx, psaddr_t address,
+                                psaddr_t *result) attribute_hidden;
+extern td_err_e _td_fetch_value_local (td_thragent_t *ta,
+                                      db_desc_t field,
+                                      int descriptor_name,
+                                      psaddr_t idx, void *address,
+                                      psaddr_t *result) attribute_hidden;
+
+/* Store psaddr_t VALUE in ((TYPE) PTR)->FIELD[IDX] in the inferior.
+   A target field smaller than psaddr_t is zero-extended.  */
+#define DB_PUT_FIELD(ta, ptr, type, field, idx, value) \
+  _td_store_value ((ta), (ta)->ta_field_##type##_##field, \
+                  SYM_##type##_FIELD_##field, \
+                  (psaddr_t) 0 + (idx), (ptr), (value))
+
+#define DB_PUT_FIELD_LOCAL(ta, ptr, type, field, idx, value) \
+  _td_store_value_local ((ta), (ta)->ta_field_##type##_##field, \
+                        SYM_##type##_FIELD_##field, \
+                        (psaddr_t) 0 + (idx), (ptr), (value))
+
+/* Store psaddr_t VALUE in variable NAME[IDX] in the inferior.
+   A target field smaller than psaddr_t is zero-extended.  */
+#define DB_PUT_VALUE(ta, name, idx, value)                                   \
+  (((ta)->ta_addr_##name == 0                                                \
+    && td_lookup ((ta)->ph, SYM_##name, &(ta)->ta_addr_##name) != PS_OK)      \
+   ? TD_ERR                                                                  \
+   : _td_store_value ((ta), (ta)->ta_var_##name, SYM_DESC_##name,            \
+                     (psaddr_t) 0 + (idx), (ta)->ta_addr_##name, (value)))
+
+/* Helper functions for those.  */
+extern td_err_e _td_store_value (td_thragent_t *ta,
+                                db_desc_t field, int descriptor_name,
+                                psaddr_t idx, psaddr_t address,
+                                psaddr_t value) attribute_hidden;
+extern td_err_e _td_store_value_local (td_thragent_t *ta,
+                                      db_desc_t field, int descriptor_name,
+                                      psaddr_t idx, void *address,
+                                      psaddr_t value) attribute_hidden;
+
+#define DB_GET_STRUCT(var, ta, ptr, type)                                    \
+  ({ td_err_e _err = TD_OK;                                                  \
+     if ((ta)->ta_sizeof_##type == 0)                                        \
+       _err = _td_check_sizeof ((ta), &(ta)->ta_sizeof_##type,               \
+                                     SYM_SIZEOF_##type);                     \
+     if (_err == TD_OK)                                                              \
+       _err = ps_pdread ((ta)->ph, (ptr),                                    \
+                        (var) = __alloca ((ta)->ta_sizeof_##type),           \
+                        (ta)->ta_sizeof_##type)                              \
+        == PS_OK ? TD_OK : TD_ERR;                                           \
+     else                                                                    \
+       (var) = NULL;                                                         \
+     _err;                                                                   \
+  })
+#define DB_PUT_STRUCT(ta, ptr, type, copy)                                   \
+  ({ assert ((ta)->ta_sizeof_##type != 0);                                   \
+     ps_pdwrite ((ta)->ph, (ptr), (copy), (ta)->ta_sizeof_##type)            \
+       == PS_OK ? TD_OK : TD_ERR;                                            \
+  })
+
+extern td_err_e _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep,
+                                 int sizep_name) attribute_hidden;
+
+#endif /* thread_dbP.h */