Initial revision
authordrepper <drepper>
Tue, 26 Nov 2002 22:50:35 +0000 (22:50 +0000)
committerdrepper <drepper>
Tue, 26 Nov 2002 22:50:35 +0000 (22:50 +0000)
81 files changed:
nptl/sysdeps/generic/lowlevellock.h [new file with mode: 0644]
nptl/sysdeps/generic/pt-raise.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/bits/local_lim.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/createthread.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/fork.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelcond.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelmutex.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrwlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelsem.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelcond.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelmutex.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrwlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelsem.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/lowlevelsem.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/pt-raise.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/pthread_kill.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/pthread_yield.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/raise.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/register-atfork.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/unregister-atfork.c [new file with mode: 0644]
nptl_db/Makefile [new file with mode: 0644]
nptl_db/Versions [new file with mode: 0644]
nptl_db/proc_service.h [new file with mode: 0644]
nptl_db/shlib-versions [new file with mode: 0644]
nptl_db/td_init.c [new file with mode: 0644]
nptl_db/td_log.c [new file with mode: 0644]
nptl_db/td_symbol_list.c [new file with mode: 0644]
nptl_db/td_ta_clear_event.c [new file with mode: 0644]
nptl_db/td_ta_delete.c [new file with mode: 0644]
nptl_db/td_ta_enable_stats.c [new file with mode: 0644]
nptl_db/td_ta_event_addr.c [new file with mode: 0644]
nptl_db/td_ta_event_getmsg.c [new file with mode: 0644]
nptl_db/td_ta_get_nthreads.c [new file with mode: 0644]
nptl_db/td_ta_get_ph.c [new file with mode: 0644]
nptl_db/td_ta_get_stats.c [new file with mode: 0644]
nptl_db/td_ta_map_id2thr.c [new file with mode: 0644]
nptl_db/td_ta_map_lwp2thr.c [new file with mode: 0644]
nptl_db/td_ta_new.c [new file with mode: 0644]
nptl_db/td_ta_reset_stats.c [new file with mode: 0644]
nptl_db/td_ta_set_event.c [new file with mode: 0644]
nptl_db/td_ta_setconcurrency.c [new file with mode: 0644]
nptl_db/td_ta_thr_iter.c [new file with mode: 0644]
nptl_db/td_ta_tsd_iter.c [new file with mode: 0644]
nptl_db/td_thr_clear_event.c [new file with mode: 0644]
nptl_db/td_thr_dbresume.c [new file with mode: 0644]
nptl_db/td_thr_dbsuspend.c [new file with mode: 0644]
nptl_db/td_thr_event_enable.c [new file with mode: 0644]
nptl_db/td_thr_event_getmsg.c [new file with mode: 0644]
nptl_db/td_thr_get_info.c [new file with mode: 0644]
nptl_db/td_thr_getfpregs.c [new file with mode: 0644]
nptl_db/td_thr_getgregs.c [new file with mode: 0644]
nptl_db/td_thr_getxregs.c [new file with mode: 0644]
nptl_db/td_thr_getxregsize.c [new file with mode: 0644]
nptl_db/td_thr_set_event.c [new file with mode: 0644]
nptl_db/td_thr_setfpregs.c [new file with mode: 0644]
nptl_db/td_thr_setgregs.c [new file with mode: 0644]
nptl_db/td_thr_setprio.c [new file with mode: 0644]
nptl_db/td_thr_setsigpending.c [new file with mode: 0644]
nptl_db/td_thr_setxregs.c [new file with mode: 0644]
nptl_db/td_thr_sigsetmask.c [new file with mode: 0644]
nptl_db/td_thr_tls_get_addr.c [new file with mode: 0644]
nptl_db/td_thr_tsd.c [new file with mode: 0644]
nptl_db/td_thr_validate.c [new file with mode: 0644]
nptl_db/thread_db.h [new file with mode: 0644]
nptl_db/thread_dbP.h [new file with mode: 0644]

diff --git a/nptl/sysdeps/generic/lowlevellock.h b/nptl/sysdeps/generic/lowlevellock.h
new file mode 100644 (file)
index 0000000..9cffca8
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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 <atomic.h>
+
+
+/* Implement generic mutex.  Basic futex syscall support is required:
+
+     lll_futex_wait(futex, value) - call sys_futex with FUTEX_WAIT
+                                   and third parameter VALUE
+
+     lll_futex_wake(futex, value) - call sys_futex with FUTEX_WAKE
+                                   and third parameter VALUE
+*/
+
+
+/* Mutex lock counter:
+   bit 31 clear means unlocked;
+   bit 31 set means locked.
+
+   All code that looks at bit 31 first increases the 'number of
+   interested threads' usage counter, which is in bits 0-30.
+
+   All negative mutex values indicate that the mutex is still locked.  */
+
+
+static inline void
+__generic_mutex_lock (int *mutex)
+{
+  unsigned int v;
+
+  /* Bit 31 was clear, we got the mutex.  (this is the fastpath).  */
+  if (atomic_bit_test_set (mutex, 31) == 0)
+    return;
+
+  atomic_increment (mutex);
+
+  while (1)
+    {
+      if (atomic_bit_test_set (mutex, 31) == 0)
+       {
+         atomic_decrement (mutex);
+         return;
+       }
+
+      /* We have to wait now. First make sure the futex value we are
+        monitoring is truly negative (i.e. locked). */
+      v = *mutex;
+      if (v >= 0)
+       continue;
+
+      lll_futex_wait (mutex, v);
+    }
+}
+
+
+static inline void
+__generic_mutex_unlock (int *mutex)
+{
+  /* Adding 0x80000000 to the counter results in 0 if and only if
+     there are not other interested threads - we can return (this is
+     the fastpath).  */
+  if (atomic_add_zero (0x80000000, mutex))
+    return;
+
+  /* There are other threads waiting for this mutex, wake one of them
+     up.  */
+  lll_futex_wake (mutex, 1);
+}
+
+
+#define lll_mutex_lock(futex) __generic_mutex_lock (&(futex))
+#define lll_mutex_unlock(futex) __generic_mutex_unlock (&(futex))
diff --git a/nptl/sysdeps/generic/pt-raise.c b/nptl/sysdeps/generic/pt-raise.c
new file mode 100644 (file)
index 0000000..59d9590
--- /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 <pthread.h>
+#include <signal.h>
+
+
+int
+raise (sig)
+     int sig;
+{
+  /* This is what POSIX says must happen.  */
+  return pthread_kill (pthread_self (), sig);
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
new file mode 100644 (file)
index 0000000..63de09a
--- /dev/null
@@ -0,0 +1,80 @@
+/* Minimum guaranteed maximum values for system limits.  Linux version.
+   Copyright (C) 1993,94,95,96,97,98,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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+   and defines LINK_MAX although filesystems have different maxima.  A
+   similar thing is true for OPEN_MAX: the limit can be changed at
+   runtime and therefore the macro must not be defined.  Remove this
+   after including the header if necessary.  */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information.  */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN?  */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX?  */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX?  */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+
+/* The number of data keys per process.  */
+#define _POSIX_THREAD_KEYS_MAX 128
+/* This is the value this implementation supports.  */
+#define PTHREAD_KEYS_MAX       1024
+
+/* Controlling the iterations of destructors for thread-specific data.  */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS    4
+/* Number of iterations this implementation does.  */
+#define PTHREAD_DESTRUCTOR_ITERATIONS  _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process.  */
+#define _POSIX_THREAD_THREADS_MAX      64
+/* This is the value this implementation supports.  */
+#define PTHREAD_THREADS_MAX    1024
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+   priority level.  */
+#define AIO_PRIO_DELTA_MAX     20
+
+/* Minimum size for a thread.  We are free to choose a reasonable value.  */
+#define PTHREAD_STACK_MIN      16384
+
+/* Maximum number of POSIX timers available.  */
+#define TIMER_MAX      256
+
+/* Maximum number of timer expiration overruns.  */
+#define DELAYTIMER_MAX 2147483647
diff --git a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
new file mode 100644 (file)
index 0000000..8274f51
--- /dev/null
@@ -0,0 +1,144 @@
+/* Define POSIX options for Linux.
+   Copyright (C) 1996-2001, 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef        _POSIX_OPT_H
+#define        _POSIX_OPT_H    1
+
+/* Job control is supported.  */
+#define        _POSIX_JOB_CONTROL      1
+
+/* Processes have a saved set-user-ID and a saved set-group-ID.  */
+#define        _POSIX_SAVED_IDS        1
+
+/* Priority scheduling is supported.  */
+#define        _POSIX_PRIORITY_SCHEDULING      200112L
+
+/* Synchronizing file data is supported.  */
+#define        _POSIX_SYNCHRONIZED_IO  200112L
+
+/* The fsync function is present.  */
+#define        _POSIX_FSYNC    200112L
+
+/* Mapping of files to memory is supported.  */
+#define        _POSIX_MAPPED_FILES     200112L
+
+/* Locking of all memory is supported.  */
+#define        _POSIX_MEMLOCK  200112L
+
+/* Locking of ranges of memory is supported.  */
+#define        _POSIX_MEMLOCK_RANGE    200112L
+
+/* Setting of memory protections is supported.  */
+#define        _POSIX_MEMORY_PROTECTION        200112L
+
+/* Implementation supports `poll' function.  */
+#define        _POSIX_POLL     1
+
+/* Implementation supports `select' and `pselect' functions.  */
+#define        _POSIX_SELECT   1
+
+/* Only root can change owner of file.  */
+#define        _POSIX_CHOWN_RESTRICTED 1
+
+/* `c_cc' member of 'struct termios' structure can be disabled by
+   using the value _POSIX_VDISABLE.  */
+#define        _POSIX_VDISABLE '\0'
+
+/* Filenames are not silently truncated.  */
+#define        _POSIX_NO_TRUNC 1
+
+/* X/Open realtime support is available.  */
+#define _XOPEN_REALTIME        1
+
+/* X/Open realtime thread support is available.  */
+#define _XOPEN_REALTIME_THREADS        1
+
+/* XPG4.2 shared memory is supported.  */
+#define        _XOPEN_SHM      1
+
+/* Tell we have POSIX threads.  */
+#define _POSIX_THREADS 200112L
+
+/* We have the reentrant functions described in POSIX.  */
+#define _POSIX_REENTRANT_FUNCTIONS      1
+#define _POSIX_THREAD_SAFE_FUNCTIONS   200112L
+
+/* We provide priority scheduling for threads.  */
+#define        _POSIX_THREAD_PRIORITY_SCHEDULING       200112L
+
+/* We support user-defined stack sizes.  */
+#define _POSIX_THREAD_ATTR_STACKSIZE   200112L
+
+/* We support user-defined stacks.  */
+#define _POSIX_THREAD_ATTR_STACKADDR   200112L
+
+/* We support POSIX.1b semaphores, but only the non-shared form for now.  */
+#define _POSIX_SEMAPHORES      1
+
+/* Real-time signals are supported.  */
+#define _POSIX_REALTIME_SIGNALS        1
+
+/* We support asynchronous I/O.  */
+#define _POSIX_ASYNCHRONOUS_IO 1
+#define _POSIX_ASYNC_IO                1
+/* Alternative name for Unix98.  */
+#define _LFS_ASYNCHRONOUS_IO   1
+
+/* The LFS support in asynchronous I/O is also available.  */
+#define _LFS64_ASYNCHRONOUS_IO 1
+
+/* The rest of the LFS is also available.  */
+#define _LFS_LARGEFILE         1
+#define _LFS64_LARGEFILE       1
+#define _LFS64_STDIO           1
+
+/* POSIX shared memory objects are implemented.  */
+#define _POSIX_SHARED_MEMORY_OBJECTS   200112L
+
+/* GNU libc provides regular expression handling.  */
+#define _POSIX_REGEXP  1
+
+/* Reader/Writer locks are available.  */
+#define _POSIX_READER_WRITER_LOCKS     200112L
+
+/* We have a POSIX shell.  */
+#define _POSIX_SHELL   1
+
+/* We support the Timeouts option.  */
+#define _POSIX_TIMEOUTS        200112L
+
+/* We support spinlocks.  */
+#define _POSIX_SPIN_LOCKS      200112L
+
+/* The `spawn' function family is supported.  */
+#define _POSIX_SPAWN   200112L
+
+/* We have POSIX timers.  */
+#define _POSIX_TIMERS  1
+
+/* The barrier functions are available.  */
+#define _POSIX_BARRIERS        200112L
+
+/* POSIX message queues are not yet supported.  */
+#undef _POSIX_MESSAGE_PASSING
+
+/* Thread process-shared synchronization is supported.  */
+#define _POSIX_THREAD_PROCESS_SHARED   200112L
+
+#endif /* posix_opt.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
new file mode 100644 (file)
index 0000000..2167bbb
--- /dev/null
@@ -0,0 +1,150 @@
+/* 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 _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H   1
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_MUTEX_T 24
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 12
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 32
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 20
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers.  The structure of the attribute type is not
+   exposed on purpose.  */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_ATTR_T];
+  long int __align;
+} pthread_attr_t;
+
+
+/* Data structures for mutex handling.  The structure of the attribute
+   type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __count;
+    struct pthread *__owner;
+    /* KIND must stay at this position in the structure to maintain
+       binary compatibility.  */
+    int __kind;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_MUTEX_T];
+  long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+  long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling.  The structure of
+   the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __nr_wakers;
+    unsigned int __nr_sleepers;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_COND_T];
+  long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+  long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#ifdef __USE_UNIX98
+/* Data structure for read-write lock variable handling.  The
+   structure of the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __nr_readers;
+    unsigned int __readers_wakeup;
+    unsigned int __writer_wakeup;
+    unsigned int __nr_readers_queued;
+    unsigned int __nr_writers_queued;
+    /* FLAGS must stay at this position in the structure to maintain
+       binary compatibility.  */
+    unsigned int __flags;
+    pthread_t __writer;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+  long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+  long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type.  */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type.  The structure of the type is
+   deliberately not exposed.  */
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIER_T];
+  long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+  int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h
new file mode 100644 (file)
index 0000000..ab46ac0
--- /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.  */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T 16
+
+
+/* Value returned if `sem_open' failed.  */
+#define SEM_FAILED      ((sem_t *) 0)
+
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   ((int) ((~0u) >> 1))
+
+
+typedef union
+{
+  char __size[__SIZEOF_SEM_T];
+  long int __align;
+} sem_t;
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/createthread.c b/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
new file mode 100644 (file)
index 0000000..3196a8c
--- /dev/null
@@ -0,0 +1,146 @@
+/* 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 <sched.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <atomic.h>
+#include <ldsodefs.h>
+#include <tls.h>
+
+
+#define CLONE_SIGNAL           (CLONE_SIGHAND | CLONE_THREAD)
+
+
+static int
+create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
+{
+  union user_desc_init desc;
+
+  /* Describe the thread-local storage segment.  */
+
+  /* The 'entry_number' field.  The first three bits of the segment
+     register value select the GDT, ignore them.  We get the index
+     from the value of the %gs register in the current thread.  */
+  desc.vals[0] = TLS_GET_GS () >> 3;
+  /* The 'base_addr' field.  Pointer to the TCB.  */
+  desc.vals[1] = (unsigned long int) pd;
+  /* The 'limit' field.  We use 4GB which is 0xfffff pages.  */
+  desc.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 */
+  desc.vals[3] = 0x51;
+
+
+  assert (pd->header.data.tcb != NULL);
+
+
+  if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
+    {
+      /* The parent thread is supposed to report events.  Check whether
+        the TD_CREATE event is needed, too.  */
+      const int _idx = __td_eventword (TD_CREATE);
+      const uint32_t _mask = __td_eventmask (TD_CREATE);
+
+      if ((_mask & (__nptl_threads_events.event_bits[_idx]
+                   | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
+       {
+         /* We have to report the new thread.  Make sure the thread
+            does not run far by forcing it to get a lock.  We lock it
+            here too so that the new thread cannot continue until we
+            tell it to.  */
+         lll_lock (pd->lock);
+
+         /* Create the thread.  */
+         if (__clone (start_thread_debug, STACK_VARIABLES_ARGS,
+                      CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
+                      CLONE_SETTLS | CLONE_PARENT_SETTID |
+                      CLONE_CHILD_CLEARTID | CLONE_DETACHED | 0,
+                      pd, &pd->tid, &desc.desc, &pd->tid) == -1)
+           /* Failed.  */
+           return errno;
+
+         /* Now fill in the information about the new thread in
+            the newly created thread's data structure.  We cannot let
+            the new thread do this since we don't know whether it was
+            already scheduled when we send the event.  */
+         pd->eventbuf.eventnum = TD_CREATE;
+         pd->eventbuf.eventdata = pd;
+
+         /* Enqueue the descriptor.  */
+         do
+           pd->nextevent = __nptl_last_event;
+         while (atomic_compare_and_exchange_acq (__nptl_last_event, pd,
+                                                 pd->nextevent) != 0);
+
+         /* Now call the function which signals the event.  */
+         __nptl_create_event ();
+
+         /* And finally restart the new thread.  */
+         lll_unlock (pd->lock);
+
+         return 0;
+       }
+    }
+
+  /* We rely heavily on various flags the CLONE function understands:
+
+     CLONE_VM, CLONE_FS, CLONE_FILES
+       These flags select semantics with shared address space and
+       file descriptors according to what POSIX requires.
+
+     CLONE_SIGNAL
+       This flag selects the POSIX signal semantics.
+
+     CLONE_SETTLS
+       The sixth parameter to CLONE determines the TLS area for the
+       new thread.
+
+     CLONE_PARENT_SETTID
+       The kernels writes the thread ID of the newly created thread
+       into the location pointed to by the fifth parameters to CLONE.
+
+       Note that it would be semantically equivalent to use
+       CLONE_CHILD_SETTID but it is be more expensive in the kernel.
+
+     CLONE_CHILD_CLEARTID
+       The kernels clears the thread ID of a thread that has called
+       sys_exit() - using the same parameter as CLONE_SETTID.
+
+     CLONE_DETACHED
+       No signal is generated if the thread exists and it is
+       automatically reaped.
+
+     The termination signal is chosen to be zero which means no signal
+     is sent.  */
+  if (__clone (start_thread, STACK_VARIABLES_ARGS,
+              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
+              CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
+              CLONE_DETACHED | 0, pd, &pd->tid, &desc.desc, &pd->tid) == -1)
+    /* Failed.  */
+    return errno;
+
+  return 0;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/fork.c b/nptl/sysdeps/unix/sysv/linux/i386/fork.c
new file mode 100644 (file)
index 0000000..813e529
--- /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 <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+
+#define ARCH_FORK() \
+  INLINE_SYSCALL (clone, 5,                                                  \
+                 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \
+                 NULL, NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelcond.S
new file mode 100644 (file)
index 0000000..9e2b9fe
--- /dev/null
@@ -0,0 +1,279 @@
+/* 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 <sysdep.h>
+
+       .text
+
+#ifdef UP
+# define LOCK
+#else
+# define LOCK lock
+#endif
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EWOULDBLOCK            11
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+#define cond_lock       0
+#define cond_nr_wakers  4
+#define cond_nr_sleepers 8
+
+
+       .global __lll_cond_wait
+       .type   __lll_cond_wait,@function
+       .hidden __lll_cond_wait
+       .align  16
+__lll_cond_wait:
+       pushl   %esi
+       pushl   %ebx
+
+       xorl    %esi, %esi
+
+       leal    cond_nr_wakers(%eax), %ebx
+
+4:     movl    (%ebx), %edx
+       testl   %edx, %edx
+       jne     1f
+
+       LOCK
+       decl    cond_lock-cond_nr_wakers(%ebx)
+       jne     2f
+
+3:     xorl    %ecx, %ecx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, cond_lock-cond_nr_wakers(%ebx)
+       testl   %eax, %eax
+       je      4b
+
+       leal    cond_lock-cond_nr_wakers(%ebx), %ecx
+       /* Preserves %ebx, %edx, %edi, %esi.  */
+       call    __lll_mutex_lock_wait
+       jmp     4b
+
+1:     decl    (%ebx)
+
+       popl    %ebx
+       popl    %esi
+       ret
+
+2:     leal    cond_lock-cond_nr_wakers(%ebx), %eax
+       /* Preserves %ebx, %ecx, %edx, %edi, %esi.  */
+       call    __lll_mutex_unlock_wake
+       jmp     3b
+       .size   __lll_cond_wait,.-__lll_cond_wait
+
+
+       .global __lll_cond_timedwait
+       .type   __lll_cond_timedwait,@function
+       .hidden __lll_cond_timedwait
+       .align  16
+__lll_cond_timedwait:
+       /* Check for a valid timeout value.  */
+       cmpl    $1000000000, 4(%edx)
+       jae     1f
+
+       pushl   %ebp
+       pushl   %edi
+       pushl   %esi
+       pushl   %ebx
+
+       /* Stack frame for the timespec and timeval structs.  */
+       subl    $8, %esp
+
+       leal    cond_nr_wakers(%eax), %ebp      /* cond */
+       movl    %edx, %edi                      /* timeout */
+
+9:     movl    (%ebp), %esi
+       testl   %esi, %esi
+       jne     5f
+
+       LOCK
+       decl    cond_lock-cond_nr_wakers(%ebp)
+       jne     6f
+
+       /* Get current time.  */
+7:     movl    %esp, %ebx
+       xorl    %ecx, %ecx
+       movl    $SYS_gettimeofday, %eax
+       int     $0x80
+
+       /* Compute relative timeout.  */
+       movl    4(%esp), %eax
+       movl    $1000, %edx
+       mul     %edx            /* Milli seconds to nano seconds.  */
+       movl    (%edi), %ecx
+       movl    4(%edi), %edx
+       subl    (%esp), %ecx
+       subl    %eax, %edx
+       jns     3f
+       addl    $1000000000, %edx
+       decl    %ecx
+3:     testl   %ecx, %ecx
+       js      4f              /* Time is already up.  */
+
+       movl    %ecx, (%esp)    /* Store relative timeout.  */
+       movl    %edx, 4(%esp)
+       movl    %esi, %edx
+       movl    %esp, %esi
+       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+       movl    %ebp, %ebx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       movl    %eax, %edx
+
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, cond_lock-cond_nr_wakers(%ebp)
+       testl   %eax, %eax
+       jne     8f
+
+       cmpl    $-ETIMEDOUT, %edx
+       jne     9b
+
+4:     movl    $ETIMEDOUT, %eax
+       jmp     2f
+
+5:     decl    (%ebp)
+       xorl    %eax, %eax
+
+2:     addl    $8, %esp
+       popl    %ebx
+       popl    %esi
+       popl    %edi
+       popl    %ebp
+       ret
+
+6:     leal    cond_lock-cond_nr_wakers(%ebp), %eax
+       /* Preserves %ebx, %ecx, %edx, %edi, %esi.  */
+       call    __lll_mutex_unlock_wake
+       jmp     7b
+
+8:     leal    cond_lock-cond_nr_wakers(%ebp), %ecx
+       /* Preserves %ebx, %edx, %edi, %esi.  */
+       call    __lll_mutex_lock_wait
+       jmp     5b
+
+1:     movl    $EINVAL, %eax
+       ret
+       .size   __lll_cond_timedwait,.-__lll_cond_timedwait
+
+
+       .global __lll_cond_wake
+       .type   __lll_cond_wake,@function
+       .hidden __lll_cond_wake
+       .align  16
+__lll_cond_wake:
+       pushl   %esi
+       pushl   %ebx
+
+       movl    %eax, %ebx
+
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, (%ebx)
+       testl   %eax, %eax
+       jne     1f
+
+2:     leal    cond_nr_wakers(%ebx), %ebx
+       cmpl    $0, cond_nr_sleepers-cond_nr_wakers(%ebx)
+       je      3f
+
+       incl    (%ebx)
+       jz      5f
+
+6:     movl    $FUTEX_WAKE, %ecx
+       xorl    %esi, %esi
+       movl    %ecx, %edx      /* movl $1, %edx */
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+3:     LOCK
+       decl    cond_lock-cond_nr_wakers(%ebx)
+       je,pt   4f
+
+       leal    cond_lock-cond_nr_wakers(%ebx), %eax
+       call    __lll_mutex_unlock_wake
+
+4:     popl    %ebx
+       popl    %esi
+       ret
+
+1:     movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     2b
+
+5:     movl    $0x80000000, (%ebx)
+       jmp     6b
+       .size   __lll_cond_wake,.-__lll_cond_wake
+
+
+       .global __lll_cond_broadcast
+       .type   __lll_cond_broadcast,@function
+       .hidden __lll_cond_broadcast
+       .align  16
+__lll_cond_broadcast:
+       pushl   %esi
+       pushl   %ebx
+
+       movl    %eax, %ebx
+       movl    $0x8000000, %edx
+
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, (%ebx)
+       testl   %eax, %eax
+       jne     1f
+
+2:     leal    cond_nr_wakers(%ebx), %ebx
+       cmpl    $0, cond_nr_sleepers-cond_nr_wakers(%ebx)
+       je      3f
+
+       orl     %edx, (%ebx)
+
+6:     movl    $FUTEX_WAKE, %ecx
+       xorl    %esi, %esi
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+3:     LOCK
+       decl    cond_lock-cond_nr_wakers(%ebx)
+       je,pt   4f
+
+       leal    cond_lock-cond_nr_wakers(%ebx), %eax
+       call    __lll_mutex_unlock_wake
+
+4:     popl    %ebx
+       popl    %esi
+       ret
+
+1:     movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     2b
+       .size   __lll_cond_broadcast,.-__lll_cond_broadcast
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
new file mode 100644 (file)
index 0000000..400413d
--- /dev/null
@@ -0,0 +1,180 @@
+/* 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 <sysdep.h>
+
+       .text
+
+#ifdef UP
+# define LOCK
+#else
+# define LOCK lock
+#endif
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define ETIMEDOUT               110
+
+
+       .globl  __lll_lock_wait
+       .type   __lll_lock_wait,@function
+       .hidden __lll_lock_wait
+       .align  16
+__lll_lock_wait:
+       pushl   %esi
+       pushl   %ebx
+       pushl   %edx
+
+       movl    %ecx, %ebx
+       xorl    %esi, %esi      /* No timeout.  */
+       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+1:
+       leal    -1(%eax), %edx  /* account for the preceeded xadd.  */
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       orl     $-1, %eax       /* Load -1.  */
+       LOCK
+       xaddl   %eax, (%ebx)
+       jne     1b
+
+       movl    $-1, (%ebx)
+
+       popl    %edx
+       popl    %ebx
+       popl    %esi
+       ret
+       .size   __lll_lock_wait,.-__lll_lock_wait
+
+
+       .globl  lll_unlock_wake_cb
+       .type   lll_unlock_wake_cb,@function
+       .hidden lll_unlock_wake_cb
+       .align  16
+lll_unlock_wake_cb:
+       pushl   %esi
+       pushl   %ebx
+       pushl   %ecx
+       pushl   %edx
+
+       movl    20(%esp), %ebx
+       LOCK
+       incl    (%ebx)
+       jng     1f
+
+       popl    %edx
+       popl    %ecx
+       popl    %ebx
+       popl    %esi
+       ret
+       .size   lll_unlock_wake_cb,.-lll_unlock_wake_cb
+
+
+       .globl  __lll_unlock_wake
+       .type   __lll_unlock_wake,@function
+       .hidden __lll_unlock_wake
+__lll_unlock_wake:
+       pushl   %esi
+       pushl   %ebx
+       pushl   %ecx
+       pushl   %edx
+
+       movl    %eax, %ebx
+1:     movl    $FUTEX_WAKE, %ecx
+       movl    $1, %edx        /* Wake one thread.  */
+       xorl    %esi, %esi
+       movl    %edx, (%ebx)    /* Stores '$1'.  */
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       popl    %edx
+       popl    %ecx
+       popl    %ebx
+       popl    %esi
+       ret
+       .size   __lll_unlock_wake,.-__lll_unlock_wake
+
+
+       .globl  __lll_timedwait_tid
+       .type   __lll_timedwait_tid,@function
+       .hidden __lll_timedwait_tid
+__lll_timedwait_tid:
+       pushl   %edi
+       pushl   %esi
+       pushl   %ebx
+       pushl   %ebp
+
+       movl    %eax, %ebp
+       movl    %edx, %edi
+       subl    $8, %esp
+
+       /* Get current time.  */
+2:     movl    %esp, %ebx
+       xorl    %ecx, %ecx
+       movl    $SYS_gettimeofday, %eax
+       int     $0x80
+
+       /* Compute relative timeout.  */
+       movl    4(%esp), %eax
+       movl    $1000, %edx
+       mul     %edx            /* Milli seconds to nano seconds.  */
+       movl    (%edi), %ecx
+       movl    4(%edi), %edx
+       subl    (%esp), %ecx
+       subl    %eax, %edx
+       jns     5f
+       addl    $1000000000, %edx
+       decl    %ecx
+5:     testl   %ecx, %ecx
+       js      6f              /* Time is already up.  */
+
+       movl    %ecx, (%esp)    /* Store relative timeout.  */
+       movl    %edx, 4(%esp)
+
+       movl    (%ebp), %edx
+       testl   %edx, %edx
+       jz      4f
+
+       movl    %esp, %esi
+       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+       movl    %ebp, %ebx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       movl    %eax, %edx
+
+       cmpl    $0, (%ebx)
+       jne     1f
+4:     xorl    %eax, %eax
+
+3:     addl    $8, %esp
+       popl    %ebp
+       popl    %ebx
+       popl    %esi
+       popl    %edi
+       ret
+
+1:     cmpl    $-ETIMEDOUT, %edx
+       jne     2b
+6:     movl    $ETIMEDOUT, %eax
+       jmp     3b
+       .size   __lll_timedwait_tid,.-__lll_timedwait_tid
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S
new file mode 100644 (file)
index 0000000..a48cd88
--- /dev/null
@@ -0,0 +1,176 @@
+/* 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 <sysdep.h>
+
+       .text
+
+#ifdef UP
+# define LOCK
+#else
+# define LOCK lock
+#endif
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EWOULDBLOCK            11
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+
+       .globl  __lll_mutex_lock_wait
+       .type   __lll_mutex_lock_wait,@function
+       .hidden __lll_mutex_lock_wait
+       .align  16
+__lll_mutex_lock_wait:
+       pushl   %esi
+       pushl   %ebx
+       pushl   %edx
+
+       movl    %ecx, %ebx
+       xorl    %esi, %esi      /* No timeout.  */
+       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+1:
+       leal    1(%eax), %edx   /* account for the preceeded xadd.  */
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, (%ebx)
+       testl   %eax, %eax
+       jne     1b
+
+       movl    $2, (%ebx)
+
+       popl    %edx
+       popl    %ebx
+       popl    %esi
+       ret
+       .size   __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
+
+
+       .globl  __lll_mutex_timedlock_wait
+       .type   __lll_mutex_timedlock_wait,@function
+       .hidden __lll_mutex_timedlock_wait
+       .align  16
+__lll_mutex_timedlock_wait:
+       /* Check for a valid timeout value.  */
+       cmpl    $1000000000, 4(%edx)
+       jae     3f
+
+       pushl   %edi
+       pushl   %esi
+       pushl   %ebx
+       pushl   %ebp
+
+       /* Stack frame for the timespec and timeval structs.  */
+       subl    $8, %esp
+
+       movl    %ecx, %ebp
+       movl    %edx, %edi
+       leal    1(%eax), %esi
+
+       /* Get current time.  */
+1:
+       movl    %esp, %ebx
+       xorl    %ecx, %ecx
+       movl    $SYS_gettimeofday, %eax
+       int     $0x80
+
+       /* Compute relative timeout.  */
+       movl    4(%esp), %eax
+       movl    $1000, %edx
+       mul     %edx            /* Milli seconds to nano seconds.  */
+       movl    (%edi), %ecx
+       movl    4(%edi), %edx
+       subl    (%esp), %ecx
+       subl    %eax, %edx
+       jns     4f
+       addl    $1000000000, %edx
+       decl    %ecx
+4:     testl   %ecx, %ecx
+       js      5f              /* Time is already up.  */
+
+       /* Futex call.  */
+       movl    %ecx, (%esp)    /* Store relative timeout.  */
+       movl    %edx, 4(%esp)
+       movl    %esi, %edx
+       movl    %esp, %esi
+       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+       movl    %ebp, %ebx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       movl    $1, %esi
+       LOCK
+       xaddl   %esi, (%ebx)
+       testl   %esi, %esi
+       jne     7f
+
+       movl    $2, (%ebx)
+       xorl    %eax, %eax
+
+6:     addl    $8, %esp
+       popl    %ebp
+       popl    %ebx
+       popl    %esi
+       popl    %edi
+       ret
+
+       /* Check whether the time expired.  */
+7:     cmpl    $-ETIMEDOUT, %eax
+       je      5f
+       jmp     1b
+
+3:     movl    $EINVAL, %eax
+       ret
+
+5:     movl    $ETIMEDOUT, %eax
+       jmp     6b
+       .size   __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
+
+
+       .globl  __lll_mutex_unlock_wake
+       .type   __lll_mutex_unlock_wake,@function
+       .hidden __lll_mutex_unlock_wake
+       .align  16
+__lll_mutex_unlock_wake:
+       pushl   %esi
+       pushl   %ebx
+       pushl   %ecx
+       pushl   %edx
+
+       movl    $FUTEX_WAKE, %ecx
+       movl    %eax, %ebx
+       xorl    %esi, %esi
+       movl    $0, (%ebx)
+       movl    $1, %edx        /* Wake one thread.  */
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       popl    %edx
+       popl    %ecx
+       popl    %ebx
+       popl    %esi
+       ret
+       .size   __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrwlock.S
new file mode 100644 (file)
index 0000000..2dde246
--- /dev/null
@@ -0,0 +1,566 @@
+/* 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 <sysdep.h>
+
+       .text
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EAGAIN         11
+#define EDEADLK                35
+#define ETIMEDOUT      110
+
+/* Offsets in the pthread_rwlock_t structure.  */
+#define MUTEX          0
+#define NR_READERS     4
+#define READERS_WAKEUP 8
+#define WRITERS_WAKEUP 12
+#define READERS_QUEUED 16
+#define WRITERS_QUEUED 20
+#define FLAGS          24
+#define WRITER 28
+
+#ifndef UP
+# define LOCK lock
+#else
+# define LOCK
+#endif
+
+
+       .globl  __pthread_rwlock_rdlock
+       .type   __pthread_rwlock_rdlock,@function
+       .align  16
+__pthread_rwlock_rdlock:
+       pushl   %esi
+       pushl   %ebx
+
+       xorl    %esi, %esi
+       xorl    %edx, %edx
+       movl    12(%esp), %ebx
+
+       /* Get the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebx)
+       testl   %eax, %eax
+       jne     1f
+
+2:     movl    WRITER(%ebx), %eax
+       testl   %eax, %eax
+       jne     14f
+       cmp     $0, WRITERS_QUEUED(%ebx)
+       je      5f
+       cmpl    $0, FLAGS(%ebx)
+       je      5f
+
+3:     incl    READERS_QUEUED(%ebx)
+       je      4f
+
+       LOCK
+       decl    MUTEX(%ebx)
+       jne     10f
+
+11:    addl    $READERS_WAKEUP-MUTEX, %ebx
+       movl    %esi, %ecx      /* movl $FUTEX_WAIT, %ecx */
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       subl    $READERS_WAKEUP-MUTEX, %ebx
+
+       /* Reget the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebx)
+       testl   %eax, %eax
+       jne     12f
+
+13:    decl    READERS_QUEUED(%ebx)
+       jne     2b
+       movl    $0, READERS_WAKEUP(%ebx)
+       jmp     2b
+
+5:     xorl    %ecx, %ecx
+       incl    NR_READERS(%ebx)
+       je      8f
+9:     LOCK
+       decl    MUTEX(%ebx)
+       jne     6f
+7:
+
+       movl    %ecx, %eax
+       popl    %ebx
+       popl    %esi
+       ret
+
+1:     movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     2b
+
+14:    cmpl    %gs:8, %eax
+       jne     3b
+       /* Deadlock detected.  */
+       movl    $EDEADLK, %ecx
+       jmp     9b
+
+6:     movl    %ebx, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     7b
+
+       /* Overflow.  */
+8:     decl    NR_READERS(%ebx)
+       movl    $EAGAIN, %ecx
+       jmp     9b
+
+       /* Overflow.  */
+4:     decl    READERS_QUEUED(%ebx)
+       movl    $EAGAIN, %ecx
+       jmp     9b
+
+10:    movl    %ebx, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     11b
+
+12:    movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     13b
+       .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
+
+       .globl  pthread_rwlock_rdlock
+pthread_rwlock_rdlock = __pthread_rwlock_rdlock
+
+
+       .globl  pthread_rwlock_timedrdlock
+       .type   pthread_rwlock_timedrdlock,@function
+       .align  16
+pthread_rwlock_timedrdlock:
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+       pushl   %ebp
+       subl    $8, %esp
+
+       movl    28(%esp), %ebp
+       movl    32(%esp), %edi
+
+       /* Get the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebp)
+       testl   %eax, %eax
+       jne     1f
+
+2:     movl    WRITER(%ebp), %eax
+       testl   %eax, %eax
+       jne     14f
+       cmp     $0, WRITERS_QUEUED(%ebp)
+       je      5f
+       cmpl    $0, FLAGS(%ebp)
+       je      5f
+
+3:     incl    READERS_QUEUED(%ebp)
+       je      4f
+
+       LOCK
+       decl    MUTEX(%ebp)
+       jne     10f
+
+       /* Get current time.  */
+       movl    %esp, %ebx
+       xorl    %ecx, %ecx
+       movl    $SYS_gettimeofday, %eax
+       int     $0x80
+
+       /* Compute relative timeout.  */
+       movl    4(%esp), %eax
+       movl    $1000, %edx
+       mul     %edx            /* Milli seconds to nano seconds.  */
+       movl    (%edi), %ecx
+       movl    4(%edi), %edx
+       subl    (%esp), %ecx
+       subl    %eax, %edx
+       jns     15f
+       addl    $1000000000, %edx
+       decl    %ecx
+15:    testl   %ecx, %ecx
+       js      16f             /* Time is already up.  */
+
+       /* Futex call.  */
+       movl    %ecx, (%esp)    /* Store relative timeout.  */
+       movl    %edx, 4(%esp)
+       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+       movl    %esp, %esi
+       movl    %ecx, %edx
+       leal    READERS_WAKEUP(%ebp), %ebx
+       movl    $SYS_futex, %eax
+       int     $0x80
+       movl    %eax, %edx
+17:
+
+       /* Reget the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebp)
+       testl   %eax, %eax
+       jne     12f
+
+13:    cmpl    $-ETIMEDOUT, %ecx
+       je      18f
+       decl    READERS_QUEUED(%ebp)
+       jne     2b
+       movl    $0, READERS_WAKEUP(%ebp)
+       jmp     2b
+
+
+5:     xorl    %ecx, %ecx
+       incl    NR_READERS(%ebp)
+       je      8f
+9:     LOCK
+       decl    MUTEX(%ebp)
+       jne     6f
+
+7:     movl    %ecx, %eax
+
+       addl    $8, %esp
+       popl    %ebp
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       ret
+
+1:     movl    %ebp, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     2b
+
+14:    cmpl    %gs:8, %eax
+       jne     3b
+       movl    $EDEADLK, %ecx
+       jmp     9b
+
+6:     movl    %ebp, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     7b
+
+       /* Overflow.  */
+8:     decl    NR_READERS(%ebp)
+       movl    $EAGAIN, %ecx
+       jmp     9b
+
+       /* Overflow.  */
+4:     decl    READERS_QUEUED(%ebp)
+       movl    $EAGAIN, %ecx
+       jmp     9b
+
+10:    movl    %ebp, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     11b
+
+12:    movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     13b
+
+16:    movl    $-ETIMEDOUT, %ecx
+       jmp     17b
+
+18:    movl    $ETIMEDOUT, %ecx
+       jmp     9b
+       .size   pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
+
+
+       .globl  __pthread_rwlock_wrlock
+       .type   __pthread_rwlock_wrlock,@function
+       .align  16
+__pthread_rwlock_wrlock:
+       pushl   %esi
+       pushl   %ebx
+
+       xorl    %esi, %esi
+       xorl    %edx, %edx
+       movl    12(%esp), %ebx
+
+       /* Get the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebx)
+       testl   %eax, %eax
+       jne     1f
+
+2:     movl    WRITER(%ebx), %eax
+       testl   %eax, %eax
+       jne     14f
+       cmp     $0, NR_READERS(%ebx)
+       je      5f
+
+3:     incl    WRITERS_QUEUED(%ebx)
+       je      4f
+
+       LOCK
+       decl    MUTEX(%ebx)
+       jne     10f
+
+11:    addl    $WRITERS_WAKEUP-MUTEX, %ebx
+       movl    %esi, %ecx      /* movl $FUTEX_WAIT, %ecx */
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       subl    $WRITERS_WAKEUP-MUTEX, %ebx
+
+       /* Reget the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebx)
+       testl   %eax, %eax
+       jne     12f
+
+13:    decl    WRITERS_QUEUED(%ebx)
+       movl    $0, WRITERS_WAKEUP(%ebx)
+       jmp     2b
+
+5:     xorl    %ecx, %ecx
+       movl    %gs:8, %eax
+       movl    %eax, WRITER(%ebx)
+9:     LOCK
+       decl    MUTEX(%ebx)
+       jne     6f
+7:
+
+       movl    %ecx, %eax
+       popl    %ebx
+       popl    %esi
+       ret
+
+1:     movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     2b
+
+14:    cmpl    %gs:8, %eax
+       jne     3b
+       movl    $EDEADLK, %ecx
+       jmp     9b
+
+6:     movl    %ebx, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     7b
+
+4:     decl    WRITERS_QUEUED(%ebx)
+       movl    $EAGAIN, %ecx
+       jmp     9b
+
+10:    movl    %ebx, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     11b
+
+12:    movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     13b
+       .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
+
+       .globl  pthread_rwlock_wrlock
+pthread_rwlock_wrlock = __pthread_rwlock_wrlock
+
+
+       .globl  pthread_rwlock_timedwrlock
+       .type   pthread_rwlock_timedwrlock,@function
+       .align  16
+pthread_rwlock_timedwrlock:
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+       pushl   %ebp
+       subl    $8, %esp
+
+       movl    28(%esp), %ebp
+       movl    32(%esp), %edi
+
+       /* Get the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebp)
+       testl   %eax, %eax
+       jne     1f
+
+2:     movl    WRITER(%ebp), %eax
+       testl   %eax, %eax
+       jne     14f
+       cmp     $0, NR_READERS(%ebp)
+       je      5f
+
+3:     incl    WRITERS_QUEUED(%ebp)
+       je      4f
+
+       LOCK
+       decl    MUTEX(%ebp)
+       jne     10f
+
+       /* Get current time.  */
+       movl    %esp, %ebx
+       xorl    %ecx, %ecx
+       movl    $SYS_gettimeofday, %eax
+       int     $0x80
+
+       /* Compute relative timeout.  */
+       movl    4(%esp), %eax
+       movl    $1000, %edx
+       mul     %edx            /* Milli seconds to nano seconds.  */
+       movl    (%edi), %ecx
+       movl    4(%edi), %edx
+       subl    (%esp), %ecx
+       subl    %eax, %edx
+       jns     15f
+       addl    $1000000000, %edx
+       decl    %ecx
+15:    testl   %ecx, %ecx
+       js      16f             /* Time is already up.  */
+
+       /* Futex call.  */
+       movl    %ecx, (%esp)    /* Store relative timeout.  */
+       movl    %edx, 4(%esp)
+       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+       movl    %esp, %esi
+       movl    %ecx, %edx
+       leal    WRITERS_WAKEUP(%ebp), %ebx
+       movl    $SYS_futex, %eax
+       int     $0x80
+       movl    %eax, %edx
+17:
+
+       /* Reget the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebp)
+       testl   %eax, %eax
+       jne     12f
+
+13:    cmpl    $-ETIMEDOUT, %ecx
+       je      18f
+       decl    WRITERS_QUEUED(%ebp)
+       movl    $0, WRITERS_WAKEUP(%ebp)
+       jmp     2b
+
+
+5:     xorl    %ecx, %ecx
+       movl    %gs:8, %eax
+       movl    %eax, WRITER(%ebp)
+9:     LOCK
+       decl    MUTEX(%ebp)
+       jne     6f
+
+7:     movl    %ecx, %eax
+
+       addl    $8, %esp
+       popl    %ebp
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       ret
+
+1:     movl    %ebp, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     2b
+
+14:    cmpl    %gs:8, %eax
+       jne     3b
+       movl    $EDEADLK, %ecx
+       jmp     9b
+
+6:     movl    %ebp, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     7b
+
+       /* Overflow.  */
+4:     decl    WRITERS_QUEUED(%ebp)
+       movl    $EAGAIN, %ecx
+       jmp     9b
+
+10:    movl    %ebp, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     11b
+
+12:    movl    %ebx, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     13b
+
+16:    movl    $-ETIMEDOUT, %ecx
+       jmp     17b
+
+18:    movl    $ETIMEDOUT, %ecx
+       jmp     9b
+       .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
+
+       .globl  __pthread_rwlock_unlock
+       .type   __pthread_rwlock_unlock,@function
+       .align  16
+__pthread_rwlock_unlock:
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+
+       xorl    %esi, %esi
+       xorl    %edx, %edx
+       movl    16(%esp), %edi
+
+       /* Get the lock.  */
+       movl    $1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%edi)
+       testl   %eax, %eax
+       jne     1f
+
+2:     cmpl    $0, WRITER(%edi)
+       jne     5f
+       decl    NR_READERS(%edi)
+       jnz     6f
+
+5:     movl    $0, WRITER(%edi)
+
+       movl    $0x7fffffff, %edx
+       leal    READERS_WAKEUP(%edi), %ebx
+       movl    $1, %ecx
+       leal    WRITERS_WAKEUP(%edi), %eax
+       cmpl    $0, WRITERS_QUEUED(%edi)
+       cmovne  %ecx, %edx
+       cmovne  %eax, %ebx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+6:     LOCK
+       decl    MUTEX(%edi)
+       jne     3f
+
+4:     xorl    %eax, %eax
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       ret
+
+1:     movl    %edi, %ecx
+       call    __lll_mutex_lock_wait
+       jmp     2b
+
+3:     movl    %edi, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     4b
+
+       .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
+
+       .globl  pthread_rwlock_unlock
+pthread_rwlock_unlock = __pthread_rwlock_unlock
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S
new file mode 100644 (file)
index 0000000..18fb16f
--- /dev/null
@@ -0,0 +1,311 @@
+/* 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 <sysdep.h>
+#include <shlib-compat.h>
+
+       .text
+
+#ifndef UP
+# define LOCK lock
+#else
+# define
+#endif
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAKE             1
+
+#define EINTR                  4
+#define EAGAIN                 11
+#define EWOULDBLOCK            EAGAIN
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+
+       .globl  __new_sem_wait
+       .type   __new_sem_wait,@function
+       .align  16
+__new_sem_wait:
+       pushl   %ebx
+       pushl   %esi
+
+       movl    12(%esp), %ebx
+
+3:     movl    (%ebx), %eax
+2:     testl   %eax, %eax
+       je,pn   1f
+
+       leal    -1(%eax), %edx
+       LOCK
+       cmpxchgl %edx, (%ebx)
+       jne,pn  2b
+       xorl    %eax, %eax
+
+       popl    %esi
+       popl    %ebx
+       ret
+
+1:     xorl    %esi, %esi
+       movl    $SYS_futex, %eax
+       movl    %esi, %ecx
+       movl    %esi, %edx
+       int     $0x80
+
+       testl   %eax, %eax
+       je      3b
+       cmpl    $-EWOULDBLOCK, %eax
+       je      3b
+       negl    %eax
+#ifdef PIC
+       call    __i686.get_pc_thunk.bx
+#else
+       movl    $4f, %ebx
+4:
+#endif
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       movl    %gs:0, %edx
+       subl    errno@gottpoff(%ebx), %edx
+       movl    %eax, (%edx)
+       orl     $-1, %eax
+       popl    %esi
+       popl    %ebx
+       ret
+       .size   __new_sem_wait,.-__new_sem_wait
+       .symver __new_sem_wait, sem_wait@@GLIBC_2.1
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+       .global __old_sem_wait
+__old_sem_wait = __new_sem_wait
+       .symver __old_sem_wait, sem_wait@GLIBC_2.0
+#endif
+
+
+       .globl  __new_sem_trywait
+       .type   __new_sem_trywait,@function
+       .align  16
+__new_sem_trywait:
+       movl    4(%esp), %ecx
+
+       movl    (%ecx), %eax
+2:     testl   %eax, %eax
+       jz      1f
+
+       leal    -1(%eax), %edx
+       LOCK
+       cmpxchgl %edx, (%ecx)
+       jne,pn  2b
+       xorl    %eax, %eax
+       ret
+
+1:
+#ifdef PIC
+       call    __i686.get_pc_thunk.cx
+#else
+       movl    $3f, %ecx
+3:
+#endif
+       addl    $_GLOBAL_OFFSET_TABLE_, %ecx
+       movl    %gs:0, %edx
+       subl    errno@gottpoff(%ecx), %edx
+       movl    $EAGAIN, (%edx)
+       orl     $-1, %eax
+       ret
+       .size   __new_sem_trywait,.-__new_sem_trywait
+       .symver __new_sem_trywait, sem_trywait@@GLIBC_2.1
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+       .global __old_sem_trywait
+__old_sem_trywait = __new_sem_trywait
+       .symver __old_sem_trywait, sem_trywait@GLIBC_2.0
+#endif
+
+
+       .globl  sem_timedwait
+       .type   sem_timedwait,@function
+       .align  16
+sem_timedwait:
+       movl    4(%esp), %ecx
+
+       movl    (%ecx), %eax
+2:     testl   %eax, %eax
+       je,pn   1f
+
+       leal    -1(%eax), %edx
+       LOCK
+       cmpxchgl %edx, (%ecx)
+       jne,pn  2b
+
+       xorl    %eax, %eax
+       ret
+
+       /* Check whether the timeout value is valid.  */
+1:     pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+       subl    $8, %esp
+
+       movl    %esp, %esi
+       movl    28(%esp), %edi
+
+       /* Check for invalid nanosecond field.  */
+       cmpl    $1000000000, 4(%edi)
+       movl    $EINVAL, %eax
+       jae     6f
+
+7:     xorl    %ecx, %ecx
+       movl    %esp, %ebx
+       movl    %ecx, %edx
+       movl    $SYS_gettimeofday, %eax
+       int     $0x80
+
+       /* Compute relative timeout.  */
+       movl    4(%esp), %eax
+       movl    $1000, %edx
+       mul     %edx            /* Milli seconds to nano seconds.  */
+       movl    (%edi), %ecx
+       movl    4(%edi), %edx
+       subl    (%esp), %ecx
+       subl    %eax, %edx
+       jns     5f
+       addl    $1000000000, %edx
+       decl    %ecx
+5:     testl   %ecx, %ecx
+       movl    $ETIMEDOUT, %eax
+       js      6f              /* Time is already up.  */
+
+       movl    %ecx, (%esp)    /* Store relative timeout.  */
+       movl    %edx, 4(%esp)
+       movl    24(%esp), %ebx
+       xorl    %ecx, %ecx
+       movl    $SYS_futex, %eax
+       xorl    %edx, %edx
+       int     $0x80
+
+       testl   %eax, %eax
+       je,pt   9f
+       cmpl    $-EWOULDBLOCK, %eax
+       jne     3f
+
+9:     movl    (%ebx), %eax
+8:     testl   %eax, %eax
+       je      7b
+
+       leal    -1(%eax), %ecx
+       LOCK
+       cmpxchgl %ecx, (%ebx)
+       jne,pn  8b
+
+       addl    $8, %esp
+       xorl    %eax, %eax
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       ret
+
+3:     negl    %eax
+6:
+#ifdef PIC
+       call    __i686.get_pc_thunk.bx
+#else
+       movl    $4f, %ebx
+4:
+#endif
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       movl    %gs:0, %edx
+       subl    errno@gottpoff(%ebx), %edx
+       movl    %eax, (%edx)
+
+       addl    $8, %esp
+       orl     $-1, %eax
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       ret
+       .size   sem_timedwait,.-sem_timedwait
+
+
+       .globl  __new_sem_post
+       .type   __new_sem_post,@function
+       .align  16
+__new_sem_post:
+       pushl   %esi
+       pushl   %ebx
+
+       movl    12(%esp), %ebx
+       movl    $1, %edx
+       LOCK
+       xaddl   %edx, (%ebx)
+
+       xorl    %esi, %esi
+       movl    $SYS_futex, %eax
+       movl    $FUTEX_WAKE, %ecx
+       incl    %edx
+       int     $0x80
+
+       testl   %eax, %eax
+       js      1f
+
+       popl    %ebx
+       popl    %esi
+       ret
+
+1:
+#ifdef PIC
+       call    __i686.get_pc_thunk.bx
+#else
+       movl    $4f, %ebx
+4:
+#endif
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       movl    %gs:0, %edx
+       subl    errno@gottpoff(%ebx), %edx
+       movl    $EINVAL, (%edx)
+
+       orl     $-1, %eax
+       popl    %ebx
+       popl    %esi
+       ret
+       .size   __new_sem_post,.-__new_sem_post
+       .symver __new_sem_post, sem_post@@GLIBC_2.1
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+       .global __old_sem_post
+__old_sem_post = __new_sem_post
+       .symver __old_sem_post, sem_post@GLIBC_2.0
+#endif
+
+
+#ifdef PIC
+       .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
+       .globl  __i686.get_pc_thunk.bx
+       .hidden __i686.get_pc_thunk.bx
+       .type   __i686.get_pc_thunk.bx,@function
+__i686.get_pc_thunk.bx:
+       movl (%esp), %ebx;
+       ret
+       .size   __i686.get_pc_thunk.bx,.-__i686.get_pc_thunk.bx
+
+
+       .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
+       .globl  __i686.get_pc_thunk.cx
+       .hidden __i686.get_pc_thunk.cx
+       .type   __i686.get_pc_thunk.cx,@function
+__i686.get_pc_thunk.cx:
+       movl (%esp), %ecx;
+       ret
+       .size   __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
new file mode 100644 (file)
index 0000000..a385adc
--- /dev/null
@@ -0,0 +1,122 @@
+/* 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 <sysdep.h>
+
+#define SYS_futex      240
+#define FUTEX_WAIT     0
+#define FUTEX_WAKE     1
+
+#ifndef UP
+# define LOCK lock
+#else
+# define LOCK
+#endif
+
+#define CURR_EVENT     0
+#define MUTEX          4
+#define LEFT           8
+#define        INIT_COUNT      12
+
+
+       .text
+
+       .globl  pthread_barrier_wait
+       .type   pthread_barrier_wait,@function
+       .align  16
+pthread_barrier_wait:
+       pushl   %esi
+       pushl   %ebx
+
+       movl    12(%esp), %ebx
+       xorl    %esi, %esi
+
+       /* Get the mutex.  */
+       orl     $-1, %eax
+       LOCK
+       xaddl   %eax, MUTEX(%ebx)
+       jne     1f
+
+       /* One less waiter.  If this was the last one needed wake
+          everybody.  */
+2:     decl    LEFT(%ebx)
+       je      3f
+
+       /* There are more threads to come.  */
+       movl    CURR_EVENT(%ebx), %edx
+
+       /* Release the mutex.  */
+       LOCK
+       incl    MUTEX(%ebx)
+       jng     6f
+
+       /* Wait for the remaining threads.  The call will return immediately
+          if the CURR_EVENT memory has meanwhile been changed.  */
+7:     movl    %esi, %ecx              /* movl $FUTEX_WAIT, %ecx */
+8:     movl    $SYS_futex, %eax
+       int     $0x80
+
+       /* Don't return on spurious wakeups.  The syscall does not change
+          any register except %eax so there is no need to reload any of
+          them.  */
+       cmpl    %edx, CURR_EVENT(%ebx)
+       je,pn   8b
+
+       /* Note: %esi is still zero.  */
+       movl    %esi, %eax              /* != PTHREAD_BARRIER_SERIAL_THREAD */
+
+       popl    %ebx
+       popl    %esi
+       ret
+
+       /* The necessary number of threads arrived.  */
+3:     movl    INIT_COUNT(%ebx), %eax
+       movl    %eax, LEFT(%ebx)
+       incl    CURR_EVENT(%ebx)
+
+       /* Wake up all waiters.  The count is a signed number in the kernel
+          so 0x7fffffff is the highest value.  */
+       movl    $0x7fffffff, %edx
+       movl    $FUTEX_WAKE, %ecx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       /* Release the mutex.  */
+       LOCK
+       incl    MUTEX(%ebx)
+       jng     4f
+
+5:     orl     $-1, %eax               /* == PTHREAD_BARRIER_SERIAL_THREAD */
+
+       popl    %ebx
+       popl    %esi
+       ret
+
+1:     leal    MUTEX(%ebx), %ecx
+       call    __lll_lock_wait
+       jmp     2b
+
+4:     leal    MUTEX(%ebx), %eax
+       call    __lll_unlock_wake
+       jmp     5b
+
+6:     leal    MUTEX(%ebx), %eax
+       call    __lll_unlock_wake
+       jmp     7b
+       .size   pthread_barrier_wait,.-pthread_barrier_wait
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelcond.S b/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelcond.S
new file mode 100644 (file)
index 0000000..3dc8403
--- /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/lowlevelcond.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S
new file mode 100644 (file)
index 0000000..e60dea8
--- /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/lowlevellock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelmutex.S
new file mode 100644 (file)
index 0000000..5048199
--- /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/lowlevelmutex.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrwlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrwlock.S
new file mode 100644 (file)
index 0000000..6f4a830
--- /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/lowlevelrwlock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelsem.S b/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelsem.S
new file mode 100644 (file)
index 0000000..cfaa36a
--- /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/lowlevelsem.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S
new file mode 100644 (file)
index 0000000..6d20b9a
--- /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_barrier_wait.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelcond.S b/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelcond.S
new file mode 100644 (file)
index 0000000..3dc8403
--- /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/lowlevelcond.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S
new file mode 100644 (file)
index 0000000..e60dea8
--- /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/lowlevellock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelmutex.S
new file mode 100644 (file)
index 0000000..5048199
--- /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/lowlevelmutex.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrwlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrwlock.S
new file mode 100644 (file)
index 0000000..6f4a830
--- /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/lowlevelrwlock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelsem.S b/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelsem.S
new file mode 100644 (file)
index 0000000..cfaa36a
--- /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/lowlevelsem.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S
new file mode 100644 (file)
index 0000000..6d20b9a
--- /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_barrier_wait.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
new file mode 100644 (file)
index 0000000..71babd5
--- /dev/null
@@ -0,0 +1,257 @@
+/* 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 _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H        1
+
+#include <time.h>
+#include <bits/pthreadtypes.h>
+
+#ifndef LOCK_INSTR
+# ifdef UP
+#  define LOCK_INSTR   /* nothing */
+# else
+#  define LOCK_INSTR "lock;"
+# endif
+#endif
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+
+/* Initializer for compatibility lock.  */
+#define LLL_MUTEX_LOCK_INITIALIZER (0)
+
+
+/* Does not preserve %eax and %ecx.  */
+extern int __lll_mutex_lock_wait (int val, int *__futex)
+     __attribute ((regparm (2))) attribute_hidden;
+/* Does not preserver %eax, %ecx, and %edx.  */
+extern int __lll_mutex_timedlock_wait (int val, int *__futex,
+                                const struct timespec *abstime)
+     __attribute ((regparm (3))) attribute_hidden;
+/* Preserves all registers but %eax.  */
+extern int __lll_mutex_unlock_wait (int *__futex)
+     __attribute ((regparm (1))) attribute_hidden;
+
+
+#define lll_mutex_trylock(futex) \
+  ({ unsigned char ret;                                                              \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1; setne %0"                \
+                      : "=a" (ret), "=m" (futex)                             \
+                      : "r" (1), "1" (futex), "0" (0));                      \
+     ret; })
+
+
+#define lll_mutex_lock(futex) \
+  (void) ({ int ignore1, ignore2;                                            \
+           __asm (LOCK_INSTR "xaddl %0, %2\n\t"                              \
+                  "testl %0, %0\n\t"                                         \
+                  "jne 1f\n\t"                                               \
+                  ".subsection 1\n"                                          \
+                  "1:\tleal %2, %%ecx\n\t"                                   \
+                  "call __lll_mutex_lock_wait\n\t"                           \
+                  "jmp 2f\n\t"                                               \
+                  ".previous\n"                                              \
+                  "2:"                                                       \
+                  : "=a" (ignore1), "=&c" (ignore2), "=m" (futex)            \
+                  : "0" (1), "2" (futex)); })
+
+
+#define lll_mutex_timedlock(futex, timeout) \
+  ({ int result, ignore1, ignore2;                                           \
+     __asm (LOCK_INSTR "xaddl %0, %3\n\t"                                    \
+           "testl %0, %0\n\t"                                                \
+           "jne 1f\n\t"                                                      \
+           ".subsection 1\n"                                                 \
+           "1:\tleal %3, %%ecx\n\t"                                          \
+           "movl %6, %%edx\n\t"                                              \
+           "call __lll_mutex_timedlock_wait\n\t"                             \
+           "jmp 2f\n\t"                                                      \
+           ".previous\n"                                                     \
+           "2:"                                                              \
+           : "=a" (result), "=&c" (ignore1), "=&d" (ignore2), "=m" (futex)   \
+           : "0" (1), "3" (futex), "m" (timeout));                           \
+     result; })
+
+
+#define lll_mutex_unlock(futex) \
+  (void) ({ int ignore;                                                              \
+            __asm (LOCK_INSTR "decl %0\n\t"                                  \
+                  "jne 1f\n\t"                                               \
+                  ".subsection 1\n"                                          \
+                  "1:\tleal %0, %%eax\n\t"                                   \
+                  "call __lll_mutex_unlock_wake\n\t"                         \
+                  "jmp 2f\n\t"                                               \
+                  ".previous\n"                                              \
+                  "2:"                                                       \
+                  : "=m" (futex), "=&a" (ignore)                             \
+                  : "0" (futex)); })
+
+
+#define lll_mutex_islocked(futex) \
+  (futex != 0)
+
+
+/* We have a separate internal lock implementation which is not tied
+   to binary compatibility.  */
+
+/* Type for lock object.  */
+typedef int lll_lock_t;
+
+/* Initializers for lock.  */
+#define LLL_LOCK_INITIALIZER           (1)
+#define LLL_LOCK_INITIALIZER_LOCKED    (0)
+
+
+extern int __lll_lock_wait (int val, int *__futex)
+     __attribute ((regparm (2))) attribute_hidden;
+extern int __lll_unlock_wake (int *__futex)
+     __attribute ((regparm (1))) attribute_hidden;
+extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
+
+
+/* The states of a lock are:
+    1  -  untaken
+    0  -  taken by one user
+   <0  -  taken by more users */
+
+
+#define lll_trylock(futex) \
+  ({ unsigned char ret;                                                              \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1; setne %0"                \
+                      : "=a" (ret), "=m" (futex)                             \
+                      : "r" (0), "1" (futex), "0" (1));                      \
+     ret; })
+
+
+#define lll_lock(futex) \
+  (void) ({ int ignore1, ignore2;                                            \
+           __asm (LOCK_INSTR "xaddl %0, %2\n\t"                              \
+                  "jne 1f\n\t"                                               \
+                  ".subsection 1\n"                                          \
+                  "1:\tleal %2, %%ecx\n\t"                                   \
+                  "call __lll_lock_wait\n\t"                                 \
+                  "jmp 2f\n\t"                                               \
+                  ".previous\n"                                              \
+                  "2:"                                                       \
+                  : "=a" (ignore1), "=&c" (ignore2), "=m" (futex)            \
+                  : "0" (-1), "2" (futex)); })
+
+
+#define lll_unlock(futex) \
+  (void) ({ int ignore;                                                              \
+            __asm (LOCK_INSTR "incl %0\n\t"                                  \
+                  "jng 1f\n\t"                                               \
+                  ".subsection 1\n"                                          \
+                  "1:\tleal %0, %%eax\n\t"                                   \
+                  "call __lll_unlock_wake\n\t"                               \
+                  "jmp 2f\n\t"                                               \
+                  ".previous\n"                                              \
+                  "2:"                                                       \
+                  : "=m" (futex), "=&a" (ignore)                             \
+                  : "0" (futex)); })
+
+
+#define lll_islocked(futex) \
+  (futex != 0)
+
+
+/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+   wakeup when the clone terminates.  The memory location contains the
+   thread ID while the clone is running and is reset to zero
+   afterwards.
+
+   The macro parameter must not have any side effect.  */
+#ifdef PIC
+# define LLL_TID_EBX_LOAD      "xchgl %2, %%ebx\n"
+# define LLL_TID_EBX_REG       "D"
+#else
+# define LLL_TID_EBX_LOAD
+# define LLL_TID_EBX_REG       "b"
+#endif
+#define lll_wait_tid(tid) \
+  do {                                                                       \
+    int __ignore;                                                            \
+    register __typeof (tid) _tid asm ("edx") = (tid);                        \
+    if (_tid != 0)                                                           \
+      __asm __volatile (LLL_TID_EBX_LOAD                                     \
+                       "1:\tmovl %1, %%eax\n\t"                              \
+                       "int $0x80\n\t"                                       \
+                       "cmpl $0, (%%ebx)\n\t"                                \
+                       "jne,pn 1b\n\t"                                       \
+                       LLL_TID_EBX_LOAD                                      \
+                       : "=&a" (__ignore)                                    \
+                       : "i" (SYS_futex), LLL_TID_EBX_REG (&tid), "S" (0),   \
+                         "c" (FUTEX_WAIT), "d" (_tid));                      \
+  } while (0)
+
+extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
+     __attribute__ ((regparm (2))) attribute_hidden;
+#define lll_timedwait_tid(tid, abstime) \
+  ({                                                                         \
+    int __result = 0;                                                        \
+    if (tid != 0)                                                            \
+      {                                                                              \
+       if (abstime == NULL || abstime->tv_nsec >= 1000000000)                \
+         __result = EINVAL;                                                  \
+       else                                                                  \
+         __result = __lll_timedwait_tid (&tid, abstime);                     \
+      }                                                                              \
+    __result; })
+
+
+#define lll_wake_tid(tid) \
+  do {                                                                       \
+    int __ignore;                                                            \
+    (tid) = 0;                                                               \
+    __asm __volatile (LLL_TID_EBX_LOAD                                       \
+                     "\tint $0x80\n\t"                                       \
+                     LLL_TID_EBX_LOAD                                        \
+                     : "=a" (__ignore)                                       \
+                     : "0" (SYS_futex), LLL_TID_EBX_REG (&(tid)), "S" (0),   \
+                       "c" (FUTEX_WAKE), "d" (0x7fffffff));                  \
+  } while (0)
+
+
+/* Conditional variable handling.  */
+
+extern void __lll_cond_wait (pthread_cond_t *cond)
+     __attribute ((regparm (1))) attribute_hidden;
+extern int __lll_cond_timedwait (pthread_cond_t *cond,
+                                const struct timespec *abstime)
+     __attribute ((regparm (2))) attribute_hidden;
+extern void __lll_cond_wake (pthread_cond_t *cond)
+     __attribute ((regparm (1))) attribute_hidden;
+extern void __lll_cond_broadcast (pthread_cond_t *cond)
+     __attribute ((regparm (1))) attribute_hidden;
+
+
+#define lll_cond_wait(cond) \
+  __lll_cond_wait (cond)
+#define lll_cond_timedwait(cond, abstime) \
+  __lll_cond_timedwait (cond, abstime)
+#define lll_cond_wake(cond) \
+  __lll_cond_wake (cond)
+#define lll_cond_broadcast(cond) \
+  __lll_cond_broadcast (cond)
+
+
+#endif /* lowlevellock.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevelsem.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevelsem.h
new file mode 100644 (file)
index 0000000..bd5f964
--- /dev/null
@@ -0,0 +1,101 @@
+/* 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 _LOWLEVELSEM_H
+#define _LOWLEVELSEM_H 1
+
+#ifndef LOCK
+# ifdef UP
+#  define LOCK /* nothing */
+# else
+#  define LOCK "lock;"
+# endif
+#endif
+
+#define SYS_futex              240
+
+
+#define lll_sem_wait(sem) \
+  ({ int result, ignore1, ignore2;                                           \
+     __asm __volatile ("1:\tincl 8(%4)\n\t"                                  \
+                      LOCK "incl (%4)\n\t"                                   \
+                      "jng 2f\n"                                             \
+                      ".subsection 1\n"                                      \
+                      "2:\tmovl %4, %%eax\n\t"                               \
+                      "call __lll_unlock_wake\n\t"                           \
+                      "jmp 3f\n\t"                                           \
+                      ".previous\n"                                          \
+                      "3:\tpushl %%ebx\n\t"                                  \
+                      "movl %%esi, %%ecx\n\t"                                \
+                      "movl %%esi, %%edx\n\t"                                \
+                      "leal 4(%4), %%ebx\n\t"                                \
+                      "movl %5, %%eax\n\t"                                   \
+                      "int $0x80\n\t"                                        \
+                      "movl %%eax, %%edx\n\t"                                \
+                      "popl %%ebx\n\t"                                       \
+                      "orl $-1, %%eax\n\t"                                   \
+                      LOCK "xaddl %%eax, (%4)\n\t"                           \
+                      "jne 4f\n\t"                                           \
+                      ".subsection 1\n"                                      \
+                      "4:\tmovl %4, %%ecx\n\t"                               \
+                      "call __lll_lock_wait\n\t"                             \
+                      "jmp 5f\n\t"                                           \
+                      ".previous\n"                                          \
+                      "5:\tdecl 8(%4)\n\t"                                   \
+                      "xorl %0, %0\n\t"                                      \
+                      "cmpl $0, 4(%4)\n\t"                                   \
+                      "jne,pt 6f\n\t"                                        \
+                      "cmpl %7, %%edx\n\t"                                   \
+                      "jne,pn 1b\n\t"                                        \
+                      "addl %8, %0\n\t" /* Shorter than movl %7, %0 */       \
+                      "6:"                                                   \
+                      : "=a" (result), "=c" (ignore1), "=d" (ignore2),       \
+                        "=m" (*sem)                                          \
+                      : "D" (sem), "i" (SYS_futex), "S" (0),                 \
+                        "i" (-EINTR), "i" (EINTR));                          \
+     result; })
+
+
+extern int __lll_sem_timedwait (struct sem *sem, const struct timespec *ts)
+     __attribute__ ((regparm (2))) attribute_hidden;
+#define lll_sem_timedwait(sem, timeout) \
+  __lll_sem_timedwait (sem, timeout)
+
+
+#define lll_sem_post(sem) \
+  (void) ({ int ignore1, ignore2, ignore3;                                   \
+           __asm __volatile ("movl $1, %%eax\n\t"                            \
+                             LOCK                                            \
+                             "xaddl %%eax, (%4)\n\t"                         \
+                             "pushl %%esi\n\t"                               \
+                             "pushl %%ebx\n\t"                               \
+                             "movl %4, %%ebx\n\t"                            \
+                             "leal 1(%%eax), %%edx\n\t"                      \
+                             "xorl %%esi, %%esi\n\t"                         \
+                             "movl %5, %%eax\n\t"                            \
+                             /* movl $FUTEX_WAKE, %ecx */                    \
+                             "movl $1, %%ecx\n\t"                            \
+                             "int $0x80\n\t"                                 \
+                             "popl %%ebx\n\t"                                \
+                             "popl %%esi"                                    \
+                             : "=&a" (ignore1), "=c" (ignore2),              \
+                               "=m" (*sem), "=d" (ignore3)                   \
+                             : "r" (sem), "i" (SYS_futex)); })
+
+#endif /* lowlevelsem.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S b/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S
new file mode 100644 (file)
index 0000000..6994c0d
--- /dev/null
@@ -0,0 +1,49 @@
+/* Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Schwab <schwab@gnu.org>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#define _ERRNO_H       1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+       /* Pop the return PC value into ECX.  */
+       popl    %ecx
+
+       /* Stuff the syscall number in EAX and enter into the kernel.  */
+       movl    $SYS_ify (vfork), %eax
+       int     $0x80
+
+       /* Jump to the return PC.  Don't jump directly since this
+          disturbs the branch target cache.  Instead push the return
+          address back on the stack.  */
+       pushl   %ecx
+
+       cmpl    $-4095, %eax
+       jae     SYSCALL_ERROR_LABEL     /* Branch forward if it failed.  */
+.Lpseudo_end:
+       ret
+PSEUDO_END (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
new file mode 100644 (file)
index 0000000..747c8ec
--- /dev/null
@@ -0,0 +1,171 @@
+/* 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 <sysdep.h>
+
+#ifndef UP
+# define LOCK lock
+#else
+# define LOCK
+#endif
+
+#define SYS_futex      240
+#define FUTEX_WAKE     1
+
+       .comm   __fork_generation, 4, 4
+
+       .text
+
+
+       .globl  __pthread_once
+       .type   __pthread_once,@function
+       .align  16
+__pthread_once:
+       movl    4(%esp), %ecx
+       testl   $2, (%ecx)
+       jz      1f
+       xorl    %eax, %eax
+       ret
+
+1:     pushl   %ebx
+       pushl   %esi
+       movl    %ecx, %ebx
+       xorl    %esi, %esi
+
+       /* Not yet initialized or initialization in progress.
+          Get the fork generation counter now.  */
+6:     movl    (%ebx), %eax
+#ifdef PIC
+       call    __i686.get_pc_thunk.cx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ecx
+#endif
+
+5:     movl    %eax, %edx
+
+       testl   $2, %eax
+       jnz     4f
+
+       andl    $3, %edx
+#ifdef PIC
+       orl     __fork_generation@GOTOFF(%ecx), %edx
+#else
+       orl     __fork_generation, %edx
+#endif
+       orl     $1, %edx
+
+       LOCK
+       cmpxchgl %edx, (%ebx)
+       jnz     5b
+
+       /* Check whether another thread already runs the initializer.  */
+       testl   $1, %eax
+       jz      3f      /* No -> do it.  */
+
+       /* Check whether the initializer execution was interrupted
+          by a fork.  */
+       xorl    %edx, %eax
+       testl   $0xfffffffc, %eax
+       jnz     3f      /* Different for generation -> run initializer.  */
+
+       /* Somebody else got here first.  Wait.  */
+       movl    %esi, %ecx              /* movl $FUTEX_WAIT, %ecx */
+       movl    $SYS_futex, %eax
+       int     $0x80
+       jmp     6b
+
+3:     /* Call the initializer function after setting up the
+          cancellation handler.  */
+       subl    $16, %esp
+
+       /* Push the cleanup handler.  */
+#ifdef PIC
+       leal    clear_once_control@GOTOFF(%ecx), %eax
+#else
+       leal    clear_once_control, %eax
+#endif
+       movl    %esp, %edx
+       pushl   %ebx
+       pushl   %eax
+       pushl   %edx
+       call    _GI_pthread_cleanup_push        /* Note: no @PLT.  */
+
+       movl    44(%esp), %eax
+       call    *%eax
+
+       /* Pop the cleanup handler.  This code depends on the once
+          handler and _pthread_cleanup_push not touch the content
+          of the stack.  Otherwise the first parameter would have
+          to be reloaded.  */
+       movl    $0, 4(%esp)
+       call    _GI_pthread_cleanup_pop /* Note: no @PLT.  */
+
+       addl    $28, %esp
+
+       /* Sucessful run of the initializer.  Signal that we are done.  */
+       LOCK
+       incl    (%ebx)
+
+       /* Wake up all other threads.  */
+       movl    $0x7fffffff, %edx
+       movl    $FUTEX_WAKE, %ecx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+4:     popl    %esi
+       popl    %ebx
+       xorl    %eax, %eax
+       ret
+
+       .size   __pthread_once,.-__pthread_once
+
+       .globl  pthread_once
+pthread_once = __pthread_once
+
+
+       .type   clear_once_control,@function
+       .align  16
+clear_once_control:
+       pushl   %esi
+       pushl   %ebx
+
+       movl    4(%esp), %eax
+       movl    $0, (%eax)
+
+       xorl    %esi, %esi
+       movl    $0x7fffffff, %edx
+       movl    $FUTEX_WAKE, %ecx
+       movl    $SYS_futex, %eax
+       int     $0x80
+
+       popl    %ebx
+       popl    %esi
+       ret
+       .size   clear_once_control,.-clear_once_control
+
+
+#ifdef PIC
+       .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
+       .globl  __i686.get_pc_thunk.cx
+       .hidden __i686.get_pc_thunk.cx
+       .type   __i686.get_pc_thunk.cx,@function
+__i686.get_pc_thunk.cx:
+       movl (%esp), %ecx;
+       ret
+       .size   __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/pt-raise.c b/nptl/sysdeps/unix/sysv/linux/pt-raise.c
new file mode 100644 (file)
index 0000000..0c68960
--- /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 <errno.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+
+int
+raise (sig)
+     int sig;
+{
+  return INLINE_SYSCALL (tkill, 2, THREAD_SELF->tid, sig);
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
new file mode 100644 (file)
index 0000000..f5c2377
--- /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.  */
+
+#include <errno.h>
+#include <signal.h>
+#include <pthreadP.h>
+#include <tls.h>
+#include <sysdep.h>
+
+
+int
+pthread_kill (threadid, signo)
+     pthread_t threadid;
+     int signo;
+{
+  struct pthread *pd = (struct pthread *) threadid;
+
+  /* We have a special syscall to do the work.  */
+  return INLINE_SYSCALL (tkill, 2, pd->tid, signo);
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_yield.c b/nptl/sysdeps/unix/sysv/linux/pthread_yield.c
new file mode 100644 (file)
index 0000000..5aecffc
--- /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 <pthread.h>
+#include <sched.h>
+
+
+/* With the 1-on-1 model we implement this function is equivalent to
+   the 'sched_yield' function.  */
+int
+pthread_yield (void)
+{
+  return sched_yield ();
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/raise.c b/nptl/sysdeps/unix/sysv/linux/raise.c
new file mode 100644 (file)
index 0000000..009f32a
--- /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 <errno.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <nptl/pthreadP.h>
+
+
+int
+raise (sig)
+     int sig;
+{
+  struct pthread *pd = THREAD_SELF;
+  pid_t selftid = pd->tid;
+  if (selftid == 0)
+    {
+      selftid = INLINE_SYSCALL (gettid, 0);
+      THREAD_SETMEM (pd, tid, selftid);
+    }
+
+  return INLINE_SYSCALL (tkill, 2, selftid, sig);
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/nptl/sysdeps/unix/sysv/linux/register-atfork.c
new file mode 100644 (file)
index 0000000..ef70dde
--- /dev/null
@@ -0,0 +1,87 @@
+/* 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 <stdlib.h>
+#include "fork.h"
+
+
+int
+__register_atfork (prepare, parent, child, dso_handle)
+     void (*prepare) (void);
+     void (*parent) (void);
+     void (*child) (void);
+     void *dso_handle;
+{
+  struct fork_handler *new_prepare = NULL;
+  struct fork_handler *new_parent = NULL;
+  struct fork_handler *new_child = NULL;
+
+  if (prepare != NULL)
+    {
+      new_prepare = (struct fork_handler *) malloc (sizeof (*new_prepare));
+      if (new_prepare == NULL)
+       goto out1;
+
+      new_prepare->handler = prepare;
+      new_prepare->dso_handle = dso_handle;
+    }
+
+  if (parent != NULL)
+    {
+      new_parent = (struct fork_handler *) malloc (sizeof (*new_parent));
+      if (new_parent == NULL)
+       goto out2;
+
+      new_parent->handler = parent;
+      new_parent->dso_handle = dso_handle;
+    }
+
+  if (child != NULL)
+    {
+      new_child = (struct fork_handler *) malloc (sizeof (*new_child));
+      if (new_child == NULL)
+       {
+         free (new_parent);
+       out2:
+         free (new_prepare);
+       out1:
+         return errno;
+       }
+
+      new_child->handler = child;
+      new_child->dso_handle = dso_handle;
+    }
+
+  /* Get the lock to not conflict with running forks.  */
+  lll_lock (__fork_lock);
+
+  /* Now that we have all the handlers allocate enqueue them.  */
+  if (new_prepare != NULL)
+    list_add_tail (&new_prepare->list, &__fork_prepare_list);
+  if (new_parent != NULL)
+    list_add_tail (&new_parent->list, &__fork_parent_list);
+  if (new_child != NULL)
+    list_add_tail (&new_child->list, &__fork_child_list);
+
+  /* Release the lock.  */
+  lll_unlock (__fork_lock);
+
+  return 0;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
new file mode 100644 (file)
index 0000000..470f80d
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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 <stdlib.h>
+#include "fork.h"
+
+
+void
+__unregister_atfork (dso_handle)
+     void *dso_handle;
+{
+  /* Get the lock to not conflict with running forks.  */
+  lll_lock (__fork_lock);
+
+  list_t *runp;
+  list_t *prevp;
+
+  list_for_each_prev_safe (runp, prevp, &__fork_prepare_list)
+    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
+      list_del (runp);
+
+  list_for_each_prev_safe (runp, prevp, &__fork_parent_list)
+    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
+      list_del (runp);
+
+  list_for_each_prev_safe (runp, prevp, &__fork_child_list)
+    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
+      list_del (runp);
+
+  /* Release the lock.  */
+  lll_unlock (__fork_lock);
+}
diff --git a/nptl_db/Makefile b/nptl_db/Makefile
new file mode 100644 (file)
index 0000000..4812cd2
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright (C) 2002 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# 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_tls_get_addr
+
+
+
+libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes))
+
+distribute = thread_dbP.h shlib-versions proc_service.h
+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/nptl_db/Versions b/nptl_db/Versions
new file mode 100644 (file)
index 0000000..4ca8042
--- /dev/null
@@ -0,0 +1,21 @@
+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;
+  }
+}
diff --git a/nptl_db/proc_service.h b/nptl_db/proc_service.h
new file mode 100644 (file)
index 0000000..9963c3a
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright (C) 1999, 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.  */
+
+/* The definitions in this file must correspond to those in the debugger.  */
+#include <sys/procfs.h>
+
+typedef enum
+{
+  PS_OK,          /* generic "call succeeded" */
+  PS_ERR,         /* generic. */
+  PS_BADPID,      /* bad process handle */
+  PS_BADLID,      /* bad lwp identifier */
+  PS_BADADDR,     /* bad address */
+  PS_NOSYM,       /* p_lookup() could not find given symbol */
+        PS_NOFREGS
+  /*
+   * FPU register set not available for given
+   * lwp
+   */
+}       ps_err_e;
+
+
+struct ps_prochandle;          /* user defined. */
+
+
+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);
+
+extern ps_err_e ps_pglobal_lookup(struct ps_prochandle *,
+        const char *object_name, const char *sym_name, psaddr_t *sym_addr);
+
+
+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 *);
+
+extern pid_t ps_getpid (struct ps_prochandle *);
+
+
+extern ps_err_e ps_pstop (const struct ps_prochandle *);
+extern ps_err_e ps_pcontinue (const struct ps_prochandle *);
+
+extern ps_err_e ps_lstop (const struct ps_prochandle *, lwpid_t);
+extern ps_err_e ps_lcontinue (const struct ps_prochandle *, lwpid_t);
+
+extern ps_err_e ps_get_thread_area (const struct ps_prochandle *, lwpid_t,
+                                   int, psaddr_t *);
diff --git a/nptl_db/shlib-versions b/nptl_db/shlib-versions
new file mode 100644 (file)
index 0000000..592f7fa
--- /dev/null
@@ -0,0 +1,2 @@
+# The thread debug library
+.*-.*-linux.*          libthread_db=1
diff --git a/nptl_db/td_init.c b/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/nptl_db/td_log.c b/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/nptl_db/td_symbol_list.c b/nptl_db/td_symbol_list.c
new file mode 100644 (file)
index 0000000..1be7001
--- /dev/null
@@ -0,0 +1,55 @@
+/* Return list of symbols the library can request.
+   Copyright (C) 2001, 2002 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"
+
+
+static const char *symbol_list_arr[] =
+{
+  [SYM_PTHREAD_THREADS_EVENTS] = "__nptl_threads_events",
+  [SYM_PTHREAD_LAST_EVENT] = "__nptl_last_event",
+  [SYM_PTHREAD_NTHREADS] = "nptl_nthreads",
+  [SYM_PTHREAD_STACK_USED] = "stack_used",
+  [SYM_PTHREAD_STACK_USER] = "__stack_user",
+  [SYM_PTHREAD_KEYS] = "pthread_keys",
+  [SYM_PTHREAD_KEYS_MAX] = "__pthread_pthread_keys_max",
+  [SYM_PTHREAD_SIZEOF_DESCR] = "__pthread_pthread_sizeof_descr",
+  [SYM_PTHREAD_CREATE_EVENT] = "__nptl_create_event",
+  [SYM_PTHREAD_DEATH_EVENT] = "__nptl_death_event",
+  [SYM_PTHREAD_VERSION] = "nptl_version",
+  [SYM_NUM_MESSAGES] = NULL
+};
+
+
+const char **
+td_symbol_list (void)
+{
+  return symbol_list_arr;
+}
+
+
+int
+td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr)
+{
+  assert (idx >= 0 && idx < SYM_NUM_MESSAGES);
+  return ps_pglobal_lookup (ps, LIBPTHREAD_SO, symbol_list_arr[idx], sym_addr);
+}
diff --git a/nptl_db/td_ta_clear_event.c b/nptl_db/td_ta_clear_event.c
new file mode 100644 (file)
index 0000000..611281f
--- /dev/null
@@ -0,0 +1,52 @@
+/* Globally disable events.
+   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_clear_event (ta, event)
+     const td_thragent_t *ta;
+     td_thr_events_t *event;
+{
+  LOG ("td_ta_clear_event");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Write the new value into the thread data structure.  */
+  td_thr_events_t old_event;
+  if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
+                &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Remove the set bits in.  */
+  int i;
+  for (i = 0; i < TD_EVENTSIZE; ++i)
+    old_event.event_bits[i] &= ~event->event_bits[i];
+
+  /* Write the new value into the thread data structure.  */
+  if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp,
+                 &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_ta_delete.c b/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/nptl_db/td_ta_enable_stats.c b/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/nptl_db/td_ta_event_addr.c b/nptl_db/td_ta_event_addr.c
new file mode 100644 (file)
index 0000000..906835d
--- /dev/null
@@ -0,0 +1,69 @@
+/* Get event address.
+   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_event_addr (const td_thragent_t *ta, td_event_e event, td_notify_t *addr)
+{
+  td_err_e res = TD_NOEVENT;
+  int idx = -1;
+
+  LOG ("td_ta_event_addr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  switch (event)
+    {
+    case TD_CREATE:
+      idx = SYM_PTHREAD_CREATE_EVENT;
+      break;
+
+    case TD_DEATH:
+      idx = SYM_PTHREAD_DEATH_EVENT;
+      break;
+
+    default:
+      /* Event cannot be handled.  */
+      break;
+    }
+
+  /* Now get the address.  */
+  if (idx != -1)
+    {
+      psaddr_t taddr;
+
+      if (td_lookup (ta->ph, idx, &taddr) == PS_OK)
+       {
+         /* Success, we got the address.  */
+         addr->type = NOTIFY_BPT;
+         addr->u.bptaddr = taddr;
+
+         res = TD_OK;
+       }
+      else
+       res = TD_ERR;
+    }
+
+  return res;
+}
diff --git a/nptl_db/td_ta_event_getmsg.c b/nptl_db/td_ta_event_getmsg.c
new file mode 100644 (file)
index 0000000..4e3245d
--- /dev/null
@@ -0,0 +1,85 @@
+/* Retrieve event.
+   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 <stddef.h>
+#include <string.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg)
+{
+  /* 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_ta_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.  */
+  psaddr_t addr;
+  if (ps_pdread (ta->ph, ta->pthread_last_event,
+                &addr, sizeof (struct pthread *)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Read the even structure from the target.  */
+  if (addr == 0)
+    return TD_NOMSG;
+
+  /* Read the even structure from the target.  */
+  td_eventbuf_t event;
+  if (ps_pdread (ta->ph, (char *) addr + offsetof (struct pthread, eventbuf),
+                &event, sizeof (td_eventbuf_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* If the structure is on the list there better be an event recorded.  */
+  assert (event.eventnum != TD_EVENT_NONE);
+
+  /* Generate the thread descriptor.  */
+  th.th_ta_p = (td_thragent_t *) ta;
+  th.th_unique = addr;
+
+  /* Fill the user's data structure.  */
+  msg->event = event.eventnum;
+  msg->th_p = &th;
+  msg->msg.data = (uintptr_t) event.eventdata;
+
+  /* Get the pointer to the next descriptor with an event.  */
+  psaddr_t next;
+  if (ps_pdread (ta->ph, (char *) addr + offsetof (struct pthread, nextevent),
+                &next, sizeof (struct pthread *)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Store the pointer in the list head variable.  */
+  if (ps_pdwrite (ta->ph, ta->pthread_last_event,
+                addr, sizeof (struct pthread *)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Clear the next pointer in the current descriptor.  */
+  if (ps_pdwrite (ta->ph, (char *) addr + offsetof (struct pthread, nextevent),
+                 NULL, sizeof (struct pthread *)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_ta_get_nthreads.c b/nptl_db/td_ta_get_nthreads.c
new file mode 100644 (file)
index 0000000..cfe93d1
--- /dev/null
@@ -0,0 +1,41 @@
+/* Get the number of threads in the 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_nthreads (const td_thragent_t *ta, int *np)
+{
+  LOG ("td_ta_get_nthreads");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Access the variable `__pthread_handles_num'.  */
+  psaddr_t addr;
+  if (td_lookup (ta->ph, SYM_PTHREAD_NTHREADS, &addr) != PS_OK)
+     return TD_ERR;    /* XXX Other error value?  */
+
+  if (ps_pdread (ta->ph, addr, np, sizeof (int)) != PS_OK)
+     return TD_ERR;    /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_ta_get_ph.c b/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/nptl_db/td_ta_get_stats.c b/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/nptl_db/td_ta_map_id2thr.c b/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/nptl_db/td_ta_map_lwp2thr.c b/nptl_db/td_ta_map_lwp2thr.c
new file mode 100644 (file)
index 0000000..326b9ee
--- /dev/null
@@ -0,0 +1,43 @@
+/* Which thread is running on an lwp?
+   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"
+#include <tls.h>
+
+
+td_err_e
+td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
+{
+  LOG ("td_ta_map_lwp2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Get the thread area for the addressed thread.  */
+  if (ps_get_thread_area (ta->ph, lwpid, TLS_GET_GS () >> 3, &th->th_unique)
+      != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Found it.  Now complete the `td_thrhandle_t' object.  */
+  th->th_ta_p = (td_thragent_t *) ta;
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_ta_new.c b/nptl_db/td_ta_new.c
new file mode 100644 (file)
index 0000000..de564ed
--- /dev/null
@@ -0,0 +1,115 @@
+/* Attach 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 <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 addr;
+  psaddr_t versaddr;
+  char versbuf[sizeof (VERSION)];
+
+  LOG ("td_ta_new");
+
+  /* Get the global event mask.  This is one of the variables which
+     are new in the thread library to enable debugging.  If it is
+     not available we cannot debug.  */
+  if (td_lookup (ps, SYM_PTHREAD_THREADS_EVENTS, &addr) != PS_OK)
+    return TD_NOLIBTHREAD;
+
+  /* Check whether the versions match.  */
+  if (td_lookup (ps, SYM_PTHREAD_VERSION, &versaddr) != PS_OK)
+    return TD_VERSION;
+  if (ps_pdread (ps, versaddr, versbuf, sizeof (versbuf)) != PS_OK)
+    return TD_ERR;
+
+  if (versbuf[sizeof (versbuf) - 1] != '\0' || strcmp (versbuf, VERSION) != 0)
+    /* Not the right version.  */
+    return TD_VERSION;
+
+  /* Fill in the appropriate information.  */
+  *ta = (td_thragent_t *) malloc (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;
+
+  /* Remember the address.  */
+  (*ta)->pthread_threads_eventsp = (td_thr_events_t *) addr;
+
+  /* Get the pointer to the variable pointing to the thread descriptor
+     with the last event.  */
+  if (td_lookup (ps, SYM_PTHREAD_LAST_EVENT, &(*ta)->pthread_last_event)
+      != PS_OK)
+    {
+    free_return:
+      free (*ta);
+      return TD_ERR;
+    }
+
+
+  if (td_lookup (ps, SYM_PTHREAD_STACK_USER, &addr) != PS_OK)
+    goto free_return;
+  /* Cast to the right type.  */
+  (*ta)->stack_user = (list_t *) addr;
+
+  if (td_lookup (ps, SYM_PTHREAD_STACK_USED, &addr) != PS_OK)
+    goto free_return;
+  /* Cast to the right type.  */
+  (*ta)->stack_used = (list_t *) addr;
+
+
+  if (td_lookup (ps, SYM_PTHREAD_KEYS, &addr) != PS_OK)
+    goto free_return;
+  /* Cast to the right type.  */
+  (*ta)->keys = (struct pthread_key_struct *) addr;
+
+
+  /* Similarly for the maximum number of thread local data keys.  */
+  if (td_lookup (ps, SYM_PTHREAD_KEYS_MAX, &addr) != PS_OK
+      || ps_pdread (ps, addr, &(*ta)->pthread_keys_max, sizeof (int)) != PS_OK)
+    goto free_return;
+
+
+  /* And for the size of the second level arrays for the keys.  */
+  if (td_lookup (ps, SYM_PTHREAD_SIZEOF_DESCR, &addr) != PS_OK
+      || ps_pdread (ps, addr, &(*ta)->sizeof_descr, sizeof (int)) != PS_OK)
+    goto free_return;
+
+
+  /* Now add the new agent descriptor to the list.  */
+  list_add (&(*ta)->list, &__td_agent_list);
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_ta_reset_stats.c b/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/nptl_db/td_ta_set_event.c b/nptl_db/td_ta_set_event.c
new file mode 100644 (file)
index 0000000..5e2cca7
--- /dev/null
@@ -0,0 +1,52 @@
+/* Globally enable events.
+   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_set_event (ta, event)
+     const td_thragent_t *ta;
+     td_thr_events_t *event;
+{
+  LOG ("td_ta_set_event");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Write the new value into the thread data structure.  */
+  td_thr_events_t old_event;
+  if (ps_pdread (ta->ph, ta->pthread_threads_eventsp,
+                &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Or the new bits in.  */
+  int i;
+  for (i = 0; i < TD_EVENTSIZE; ++i)
+    old_event.event_bits[i] |= event->event_bits[i];
+
+  /* Write the new value into the thread data structure.  */
+  if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp,
+                 &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_ta_setconcurrency.c b/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/nptl_db/td_ta_thr_iter.c b/nptl_db/td_ta_thr_iter.c
new file mode 100644 (file)
index 0000000..ca1c82d
--- /dev/null
@@ -0,0 +1,125 @@
+/* Iterate over a process's threads.
+   Copyright (C) 1999, 2000, 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"
+#include <nptl/descr.h>
+
+
+static td_err_e
+iterate_thread_list (const td_thragent_t *ta, td_thr_iter_f *callback,
+                    void *cbdata_p, td_thr_state_e state, int ti_pri,
+                    psaddr_t head)
+{
+  list_t list;
+  td_err_e result = TD_OK;
+
+  /* Test the state.
+     XXX This is incomplete.  Normally this test should be in the loop.  */
+  if (state != TD_THR_ANY_STATE)
+    return TD_OK;
+
+  if (ps_pdread (ta->ph, head, &list, sizeof (list_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  while (list.next != head)
+    {
+      psaddr_t addr = ((psaddr_t) list.next
+                      - offsetof (struct pthread, header.data.list));
+
+      int schedpolicy;
+      if (ps_pdread (ta->ph, &((struct pthread *) addr)->schedpolicy,
+                    &schedpolicy, sizeof (int)) != PS_OK)
+       {
+         result = TD_ERR;      /* XXX Other error value?  */
+         break;
+       }
+
+      struct sched_param schedparam;
+      if (ps_pdread (ta->ph, &((struct pthread *) addr)->schedparam,
+                    &schedparam, sizeof (struct sched_param)) != PS_OK)
+       {
+         result = TD_ERR;      /* XXX Other error value?  */
+         break;
+       }
+
+      /* Now test whether this thread matches the specified
+        conditions.  */
+
+      /* Only if the priority level is as high or higher.  */
+      int descr_pri = (schedpolicy == SCHED_OTHER
+                      ? 0 : schedparam.sched_priority);
+      if (descr_pri >= ti_pri)
+       {
+         /* XXX For now we ignore threads which are not running anymore.
+            The reason is that gdb tries to get the registers and fails.
+            In future we should have a special mode of the thread library
+            in which we keep the process around until the actual join
+            operation happened.  */
+         int cancelhandling;
+         if (ps_pdread (ta->ph, &((struct pthread *) addr)->cancelhandling,
+                        &cancelhandling, sizeof (int)) != PS_OK)
+           {
+             result = TD_ERR;  /* XXX Other error value?  */
+             break;
+           }
+
+         if ((cancelhandling & TERMINATED_BIT) == 0)
+           {
+             /* 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;
+           }
+       }
+    }
+
+  return result;
+}
+
+
+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)
+{
+  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.  */
+  td_err_e result = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri,
+                                        ta->stack_user);
+
+  /* And the threads with stacks allocated by the implementation.  */
+  if (result == TD_OK)
+    result = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri,
+                                 ta->stack_used);
+
+  return result;
+}
diff --git a/nptl_db/td_ta_tsd_iter.c b/nptl_db/td_ta_tsd_iter.c
new file mode 100644 (file)
index 0000000..cbc2f37
--- /dev/null
@@ -0,0 +1,53 @@
+/* Iterate over a process's thread-specific data.
+   Copyright (C) 1999, 2000, 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"
+#include <alloca.h>
+
+td_err_e
+td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback,
+               void *cbdata_p)
+{
+  LOG ("td_ta_tsd_iter");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  int pthread_keys_max = ta->pthread_keys_max;
+  struct pthread_key_struct *keys;
+  keys = (struct pthread_key_struct *) alloca (sizeof (keys[0])
+                                              * pthread_keys_max);
+
+  /* Read all the information about the keys.  */
+  if (ps_pdread (ta->ph, ta->keys, keys,
+                sizeof (keys[0]) * pthread_keys_max) != PS_OK)
+       return TD_ERR;  /* XXX Other error value?  */
+
+  /* Now get all descriptors, one after the other.  */
+  int cnt;
+  for (cnt = 0; cnt < pthread_keys_max; ++cnt)
+    if (!KEY_UNUSED (keys[cnt].seq)
+       /* Return with an error if the callback returns a nonzero value.  */
+       && callback (cnt, keys[cnt].destr, cbdata_p) != 0)
+      return TD_DBERR;
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_clear_event.c b/nptl_db/td_thr_clear_event.c
new file mode 100644 (file)
index 0000000..e729b52
--- /dev/null
@@ -0,0 +1,54 @@
+/* Disable specific event for 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 <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;
+{
+  LOG ("td_thr_clear_event");
+
+  /* Write the new value into the thread data structure.  */
+  td_thr_events_t old_event;
+  if (ps_pdread (th->th_ta_p->ph,
+                ((char *) th->th_unique
+                 + offsetof (struct pthread, eventbuf.eventmask)),
+                &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Remove the set bits in.  */
+  int i;
+  for (i = 0; i < TD_EVENTSIZE; ++i)
+    old_event.event_bits[i] &= ~event->event_bits[i];
+
+  /* Write the new value into the thread data structure.  */
+  if (ps_pdwrite (th->th_ta_p->ph,
+                 ((char *) th->th_unique
+                  + offsetof (struct pthread, eventbuf.eventmask)),
+                 &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_dbresume.c b/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/nptl_db/td_thr_dbsuspend.c b/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/nptl_db/td_thr_event_enable.c b/nptl_db/td_thr_event_enable.c
new file mode 100644 (file)
index 0000000..e822453
--- /dev/null
@@ -0,0 +1,41 @@
+/* Enable event process-wide.
+   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 <stddef.h>
+
+#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.  */
+  if (ps_pdwrite (th->th_ta_p->ph,
+                 ((char *) th->th_unique
+                  + offsetof (struct pthread, report_events)),
+                 &onoff, sizeof (int)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_event_getmsg.c b/nptl_db/td_thr_event_getmsg.c
new file mode 100644 (file)
index 0000000..ffd0baa
--- /dev/null
@@ -0,0 +1,60 @@
+/* Retrieve event.
+   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 <stddef.h>
+#include <string.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg)
+{
+  td_eventbuf_t event;
+
+  LOG ("td_thr_event_getmsg");
+
+  /* Read the even structure from the target.  */
+  if (ps_pdread (th->th_ta_p->ph,
+                ((char *) th->th_unique
+                 + offsetof (struct pthread, eventbuf)),
+                &event, sizeof (td_eventbuf_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Check whether an event occurred.  */
+  if (event.eventnum == TD_EVENT_NONE)
+    /* Nothing.  */
+    return TD_NOMSG;
+
+  /* Fill the user's data structure.  */
+  msg->event = event.eventnum;
+  msg->th_p = th;
+  msg->msg.data = (uintptr_t) event.eventdata;
+
+  /* And clear the event message in the target.  */
+  memset (&event, '\0', sizeof (td_eventbuf_t));
+  if (ps_pdwrite (th->th_ta_p->ph,
+                 ((char *) th->th_unique
+                  + offsetof (struct pthread, eventbuf)),
+                 &event, sizeof (td_eventbuf_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_get_info.c b/nptl_db/td_thr_get_info.c
new file mode 100644 (file)
index 0000000..0686649
--- /dev/null
@@ -0,0 +1,64 @@
+/* Get thread information.
+   Copyright (C) 1999, 2000, 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 <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)
+{
+  LOG ("td_thr_get_info");
+
+  /* Get the thread descriptor.  */
+  struct pthread pds;
+  if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
+                sizeof (struct pthread)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* 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 = pds.tid;
+  infop->ti_tls = (char *) pds.specific;
+  infop->ti_pri = (pds.schedpolicy == SCHED_OTHER
+                  ? 0 : pds.schedparam.sched_priority);
+  infop->ti_type = TD_THR_USER;
+
+  if ((pds.cancelhandling & EXITING_BIT) == 0)
+    /* XXX For now there is no way to get more information.  */
+    infop->ti_state = TD_THR_ACTIVE;
+  else if ((pds.cancelhandling & TERMINATED_BIT) == 0)
+    infop->ti_state = TD_THR_ZOMBIE;
+  else
+    infop->ti_state = TD_THR_UNKNOWN;
+
+  /* Initialization which are the same in both cases.  */
+  infop->ti_lid = ps_getpid (th->th_ta_p->ph);
+  infop->ti_ta_p = th->th_ta_p;
+  infop->ti_startfunc = pds.start_routine;
+  memcpy (&infop->ti_events, &pds.eventbuf.eventmask,
+         sizeof (td_thr_events_t));
+  infop->ti_traceme = pds.report_events != false;
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_getfpregs.c b/nptl_db/td_thr_getfpregs.c
new file mode 100644 (file)
index 0000000..360e1d2
--- /dev/null
@@ -0,0 +1,52 @@
+/* Get a thread's floating-point 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_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset)
+{
+  LOG ("td_thr_getfpregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  int cancelhandling;
+  if (ps_pdread (th->th_ta_p->ph,
+                &((struct pthread *) th->th_unique)->cancelhandling,
+                &cancelhandling, sizeof (int)) != PS_OK)
+    return TD_ERR;
+
+  /* If the thread already terminated we return all zeroes.  */
+  if (cancelhandling & TERMINATED_BIT)
+    memset (regset, '\0', sizeof (*regset));
+  /* Otherwise get the register content through the callback.  */
+  else
+    {
+      pid_t tid;
+
+      if (ps_pdread (th->th_ta_p->ph,
+                    &((struct pthread *) th->th_unique)->tid,
+                    &tid, sizeof (pid_t)) != PS_OK
+         || ps_lgetfpregs (th->th_ta_p->ph, tid, regset) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_getgregs.c b/nptl_db/td_thr_getgregs.c
new file mode 100644 (file)
index 0000000..2485e5d
--- /dev/null
@@ -0,0 +1,52 @@
+/* Get a thread's general register set.
+   Copyright (C) 1999, 2000, 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_getgregs (const td_thrhandle_t *th, prgregset_t gregs)
+{
+  LOG ("td_thr_getgregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  int cancelhandling;
+  if (ps_pdread (th->th_ta_p->ph,
+                &((struct pthread *) th->th_unique)->cancelhandling,
+                &cancelhandling, sizeof (int)) != PS_OK)
+    return TD_ERR;
+
+  /* If the thread already terminated we return all zeroes.  */
+  if (cancelhandling & TERMINATED_BIT)
+    memset (gregs, '\0', sizeof (prgregset_t));
+  /* Otherwise get the register content through the callback.  */
+  else
+    {
+      pid_t tid;
+
+      if (ps_pdread (th->th_ta_p->ph,
+                    &((struct pthread *) th->th_unique)->tid,
+                    &tid, sizeof (pid_t)) != PS_OK
+         || ps_lgetregs (th->th_ta_p->ph, tid, gregs) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_getxregs.c b/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/nptl_db/td_thr_getxregsize.c b/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/nptl_db/td_thr_set_event.c b/nptl_db/td_thr_set_event.c
new file mode 100644 (file)
index 0000000..656728c
--- /dev/null
@@ -0,0 +1,54 @@
+/* Enable specific event for 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 <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;
+{
+  LOG ("td_thr_set_event");
+
+  /* Write the new value into the thread data structure.  */
+  td_thr_events_t old_event;
+  if (ps_pdread (th->th_ta_p->ph,
+                ((char *) th->th_unique
+                 + offsetof (struct pthread, eventbuf.eventmask)),
+                &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Or the new bits in.  */
+  int i;
+  for (i = 0; i < TD_EVENTSIZE; ++i)
+    old_event.event_bits[i] |= event->event_bits[i];
+
+  /* Write the new value into the thread data structure.  */
+  if (ps_pdwrite (th->th_ta_p->ph,
+                 ((char *) th->th_unique
+                  + offsetof (struct pthread, eventbuf.eventmask)),
+                 &old_event, sizeof (td_thrhandle_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_setfpregs.c b/nptl_db/td_thr_setfpregs.c
new file mode 100644 (file)
index 0000000..e1ec9be
--- /dev/null
@@ -0,0 +1,49 @@
+/* Set a thread's floating-point 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_setfpregs (const td_thrhandle_t *th, const prfpregset_t *fpregs)
+{
+  LOG ("td_thr_setfpregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  int cancelhandling;
+  if (ps_pdread (th->th_ta_p->ph,
+                &((struct pthread *) th->th_unique)->cancelhandling,
+                &cancelhandling, sizeof (int)) != PS_OK)
+    return TD_ERR;
+
+  /* Only set the registers if the thread hasn't yet terminated.  */
+  if ((cancelhandling & TERMINATED_BIT) == 0)
+    {
+      pid_t tid;
+
+      if (ps_pdread (th->th_ta_p->ph,
+                    &((struct pthread *) th->th_unique)->tid,
+                    &tid, sizeof (pid_t)) != PS_OK
+         || ps_lsetfpregs (th->th_ta_p->ph, tid, fpregs) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_setgregs.c b/nptl_db/td_thr_setgregs.c
new file mode 100644 (file)
index 0000000..d46e32a
--- /dev/null
@@ -0,0 +1,49 @@
+/* Set a thread's general 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_setgregs (const td_thrhandle_t *th, prgregset_t gregs)
+{
+  LOG ("td_thr_setgregs");
+
+  /* We have to get the state and the PID for this thread.  */
+  int cancelhandling;
+  if (ps_pdread (th->th_ta_p->ph,
+                &((struct pthread *) th->th_unique)->cancelhandling,
+                &cancelhandling, sizeof (int)) != PS_OK)
+    return TD_ERR;
+
+  /* Only set the registers if the thread hasn't yet terminated.  */
+  if ((cancelhandling & TERMINATED_BIT) == 0)
+    {
+      pid_t tid;
+
+      if (ps_pdread (th->th_ta_p->ph,
+                    &((struct pthread *) th->th_unique)->tid,
+                    &tid, sizeof (pid_t)) != PS_OK
+         || ps_lsetregs (th->th_ta_p->ph, tid, gregs) != PS_OK)
+       return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_setprio.c b/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/nptl_db/td_thr_setsigpending.c b/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/nptl_db/td_thr_setxregs.c b/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/nptl_db/td_thr_sigsetmask.c b/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/nptl_db/td_thr_tls_get_addr.c b/nptl_db/td_thr_tls_get_addr.c
new file mode 100644 (file)
index 0000000..5bbdc50
--- /dev/null
@@ -0,0 +1,70 @@
+/* Get address of thread local variable.
+   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 "link.h"
+#include "thread_dbP.h"
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+# define TLS_DTV_UNALLOCATED   ((void *) -1l)
+
+
+td_err_e
+td_thr_tls_get_addr (const td_thrhandle_t *th __attribute__ ((unused)),
+                    void *map_address __attribute__ ((unused)),
+                    size_t offset __attribute__ ((unused)),
+                    void **address __attribute__ ((unused)))
+{
+#if USE_TLS
+  size_t modid;
+  union dtv pdtv, *dtvp;
+
+  LOG ("td_thr_tls_get_addr");
+
+  /* Get the DTV pointer from the thread descriptor.  */
+  if (ps_pdread (th->th_ta_p->ph,
+                &((struct pthread *) th->th_unique)->header.data.dtvp,
+                &dtvp, sizeof dtvp) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Read the module ID from the link_map.  */
+  if (ps_pdread (th->th_ta_p->ph,
+                &((struct link_map *) map_address)->l_tls_modid,
+                &modid, sizeof modid) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Get the corresponding entry in the DTV.  */
+  if (ps_pdread (th->th_ta_p->ph, dtvp + modid,
+                &pdtv, sizeof (union dtv)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* It could be that the memory for this module is not allocated for
+     the given thread.  */
+  if (pdtv.pointer == TLS_DTV_UNALLOCATED)
+    /* There is not much we can do.  */
+    return TD_NOTALLOC;
+
+  *address = (char *) pdtv.pointer + offset;
+
+  return TD_OK;
+#else
+  return TD_ERR;
+#endif
+}
diff --git a/nptl_db/td_thr_tsd.c b/nptl_db/td_thr_tsd.c
new file mode 100644 (file)
index 0000000..d1a5453
--- /dev/null
@@ -0,0 +1,71 @@
+/* Get a thread-specific data pointer 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_tsd (const td_thrhandle_t *th, const thread_key_t tk, void **data)
+{
+  LOG ("td_thr_tsd");
+
+  /* Check correct value of key.  */
+  if (tk >= th->th_ta_p->pthread_keys_max)
+    return TD_BADKEY;
+
+  /* Get the key entry.  */
+  uintptr_t seq;
+  if (ps_pdread (th->th_ta_p->ph, &th->th_ta_p->keys[tk].seq, &seq,
+                sizeof (uintptr_t)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Fail if this key is not at all used.  */
+  if (KEY_UNUSED (seq))
+    return TD_BADKEY;
+
+  /* Compute the indeces.  */
+  int pthread_key_2ndlevel_size = th->th_ta_p->pthread_key_2ndlevel_size;
+  unsigned int idx1st = tk / pthread_key_2ndlevel_size;
+  unsigned int idx2nd = tk % pthread_key_2ndlevel_size;
+
+  struct pthread_key_data *level1;
+  if (ps_pdread (th->th_ta_p->ph,
+                &((struct pthread *) th->th_unique)->specific[idx1st],
+                &level1, sizeof (level1)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Check the pointer to the second level array.  */
+  if (level1 == NULL)
+    return TD_NOTSD;
+
+  struct pthread_key_data level2;
+  if (ps_pdread (th->th_ta_p->ph, &level1[idx2nd], &level2,
+                sizeof (level2)) != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  /* Check whether the data is valid.  */
+  if (level2.seq != seq)
+    return TD_NOTSD;
+
+  if (level2.data != NULL)
+    *data = level2.data;
+
+  return TD_OK;
+}
diff --git a/nptl_db/td_thr_validate.c b/nptl_db/td_thr_validate.c
new file mode 100644 (file)
index 0000000..76cbad3
--- /dev/null
@@ -0,0 +1,66 @@
+/* Validate a 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"
+
+
+static td_err_e
+check_thread_list (const td_thrhandle_t *th, psaddr_t head)
+{
+  list_t list;
+  td_err_e result = TD_NOTHR;
+
+  if (ps_pdread (th->th_ta_p->ph, head, &list.next, sizeof (list.next))
+      != PS_OK)
+    return TD_ERR;     /* XXX Other error value?  */
+
+  while (list.next != head)
+    if ((psaddr_t) list.next - offsetof (struct pthread, header.data.list)
+       == th->th_unique)
+      {
+       result = TD_OK;
+       break;
+      }
+    else if (ps_pdread (th->th_ta_p->ph, list.next, &list.next,
+                       sizeof (list.next)) != PS_OK)
+      {
+       result = TD_ERR;        /* XXX Other error value?  */
+       break;
+      }
+
+  return result;
+}
+
+
+td_err_e
+td_thr_validate (const td_thrhandle_t *th)
+{
+  LOG ("td_thr_validate");
+
+  /* First check the list with threads using user allocated stacks.  */
+  td_err_e result = check_thread_list (th, th->th_ta_p->stack_user);
+
+  /* If our thread is not on this list search the list with stack
+     using implementation allocated stacks.  */
+  if (result == TD_NOTHR)
+    result = check_thread_list (th, th->th_ta_p->stack_used);
+
+  return result;
+}
diff --git a/nptl_db/thread_db.h b/nptl_db/thread_db.h
new file mode 100644 (file)
index 0000000..acb0607
--- /dev/null
@@ -0,0 +1,451 @@
+/* Copyright (C) 1999, 2001, 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.  */
+
+#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_NOTALLOC,   /* TLS memory not yet allocated.  */
+  TD_VERSION     /* Version if libpthread and libthread_db do not match.  */
+} 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;                      /* Unused.  */
+  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 thread local variable.  */
+extern td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th,
+                                    void *__map_address, size_t __offset,
+                                    void **__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/nptl_db/thread_dbP.h b/nptl_db/thread_dbP.h
new file mode 100644 (file)
index 0000000..4407143
--- /dev/null
@@ -0,0 +1,98 @@
+/* Private header for thread debug library.  */
+#ifndef _THREAD_DBP_H
+#define _THREAD_DBP_H  1
+
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include "proc_service.h"
+#include "thread_db.h"
+#include "../nptl/pthreadP.h"
+#include <list.h>
+
+
+/* Indeces for the symbol names.  */
+enum
+  {
+    SYM_PTHREAD_THREADS_EVENTS = 0,
+    SYM_PTHREAD_LAST_EVENT,
+    SYM_PTHREAD_NTHREADS,
+    SYM_PTHREAD_STACK_USED,
+    SYM_PTHREAD_STACK_USER,
+    SYM_PTHREAD_KEYS,
+    SYM_PTHREAD_KEYS_MAX,
+    SYM_PTHREAD_SIZEOF_DESCR,
+    SYM_PTHREAD_CREATE_EVENT,
+    SYM_PTHREAD_DEATH_EVENT,
+    SYM_PTHREAD_VERSION,
+    SYM_NUM_MESSAGES
+  };
+
+
+/* Comment out the following for less verbose output.  */
+#ifndef NDEBUG
+# define LOG(c) if (__td_debug) __libc_write (2, c "\n", strlen (c "\n"))
+extern int __td_debug;
+#else
+# define LOG(c)
+#endif
+
+
+/* Handle for a process.  This type is opaque.  */
+struct td_thragent
+{
+  /* Delivered by the debugger and we have to pass it back in the
+     proc callbacks.  */
+  struct ps_prochandle *ph;
+
+  /* Some cached information.  */
+
+  /* Lists of running threads.  */
+  psaddr_t stack_used;
+  psaddr_t stack_user;
+
+  /* Address of the `pthread_keys' array.  */
+  struct pthread_key_struct *keys;
+
+  /* Maximum number of thread-local data keys.  */
+  int pthread_keys_max;
+
+  /* Size of 2nd level array for thread-local data keys.  */
+  int pthread_key_2ndlevel_size;
+
+  /* Sizeof struct _pthread_descr_struct.  */
+  int sizeof_descr;
+
+  /* Pointer to the `__pthread_threads_events' variable in the target.  */
+  psaddr_t pthread_threads_eventsp;
+
+  /* Pointer to the `__pthread_last_event' variable in the target.  */
+  psaddr_t pthread_last_event;
+
+  /* List head the queue agent structures.  */
+  list_t list;
+};
+
+
+/* List of all known descriptors.  */
+extern list_t __td_agent_list;
+
+
+/* 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 int td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr);
+
+#endif /* thread_dbP.h */