pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Import libpthread_dbg-20161124 as wip/libpthread_dbg.



Module Name:	pkgsrc-wip
Committed By:	Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By:	kamil
Date:		Wed Feb 8 01:07:55 2017 +0100
Changeset:	86b79a5f9a2c6e24bffdc32f3d6c2e70bde98006

Added Files:
	libpthread_dbg/DESCR
	libpthread_dbg/Makefile
	libpthread_dbg/PLIST
	libpthread_dbg/distinfo
	libpthread_dbg/files/Makefile
	libpthread_dbg/files/pthread.h
	libpthread_dbg/files/pthread_dbg.3
	libpthread_dbg/files/pthread_dbg.c
	libpthread_dbg/files/pthread_dbg.h
	libpthread_dbg/files/pthread_dbg_int.h
	libpthread_dbg/files/pthread_int.h
	libpthread_dbg/files/shlib_version
	libpthread_dbg/files/td_map_pth2thr.3
	libpthread_dbg/files/td_open.3
	libpthread_dbg/files/td_thr_getname.3
	libpthread_dbg/files/td_thr_info.3
	libpthread_dbg/files/td_thr_iter.3

Log Message:
Import libpthread_dbg-20161124 as wip/libpthread_dbg.

The pthread_dbg library provides an implementation of the standard POSIX
threads library debugging facilities.

The NetBSD implementation is based on 1:1 thread model, therefore each
pthread(3) has a kernel thread, called a light-weight process (LWP).

Note that the system private thread interfaces upon which the pthread(3)
library is built are subject to change without notice.  In order to
remain compatible with future NetBSD releases, programs must be linked
against the dynamic version of the thread library.  Statically linked
programs using the POSIX threads framework may not work when run on a
future version of the system.

The pthread_dbg library is designed to be used in debuggers and to
control and introspect the NetBSD implementation of the POSIX threads.
Software may use native LWP threads without pthread(3) layer, in that
case pthread_dbg cannot be used.

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=86b79a5f9a2c6e24bffdc32f3d6c2e70bde98006

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 libpthread_dbg/DESCR                   |  17 ++
 libpthread_dbg/Makefile                |  21 ++
 libpthread_dbg/PLIST                   |   7 +
 libpthread_dbg/distinfo                |   2 +
 libpthread_dbg/files/Makefile          |  21 ++
 libpthread_dbg/files/pthread.h         | 422 ++++++++++++++++++++++++++
 libpthread_dbg/files/pthread_dbg.3     | 148 ++++++++++
 libpthread_dbg/files/pthread_dbg.c     | 520 +++++++++++++++++++++++++++++++++
 libpthread_dbg/files/pthread_dbg.h     | 200 +++++++++++++
 libpthread_dbg/files/pthread_dbg_int.h |  48 +++
 libpthread_dbg/files/pthread_int.h     | 333 +++++++++++++++++++++
 libpthread_dbg/files/shlib_version     |   5 +
 libpthread_dbg/files/td_map_pth2thr.3  |  71 +++++
 libpthread_dbg/files/td_open.3         |  79 +++++
 libpthread_dbg/files/td_thr_getname.3  |  75 +++++
 libpthread_dbg/files/td_thr_info.3     | 109 +++++++
 libpthread_dbg/files/td_thr_iter.3     |  69 +++++
 17 files changed, 2147 insertions(+)

diffs:
diff --git a/libpthread_dbg/DESCR b/libpthread_dbg/DESCR
new file mode 100644
index 0000000000..f452105a11
--- /dev/null
+++ b/libpthread_dbg/DESCR
@@ -0,0 +1,17 @@
+The pthread_dbg library provides an implementation of the standard POSIX
+threads library debugging facilities.
+
+The NetBSD implementation is based on 1:1 thread model, therefore each
+pthread(3) has a kernel thread, called a light-weight process (LWP).
+
+Note that the system private thread interfaces upon which the pthread(3)
+library is built are subject to change without notice.  In order to
+remain compatible with future NetBSD releases, programs must be linked
+against the dynamic version of the thread library.  Statically linked
+programs using the POSIX threads framework may not work when run on a
+future version of the system.
+
+The pthread_dbg library is designed to be used in debuggers and to
+control and introspect the NetBSD implementation of the POSIX threads.
+Software may use native LWP threads without pthread(3) layer, in that
+case pthread_dbg cannot be used.
diff --git a/libpthread_dbg/Makefile b/libpthread_dbg/Makefile
new file mode 100644
index 0000000000..acb43435ca
--- /dev/null
+++ b/libpthread_dbg/Makefile
@@ -0,0 +1,21 @@
+# $NetBSD: Makefile,v 1.2 2016/12/16 00:01:04 joerg Exp $
+#
+
+PKGNAME=	libpthread_dbg-20161124
+CATEGORIES=	pkgtools
+
+MAINTAINER=	pkgsrc-users%NetBSD.org@localhost
+#HOMEPAGE=
+COMMENT=	POSIX Debug Threads Library
+LICENSE=	2-clause-bsd
+
+USE_BSD_MAKEFILE=	yes
+USE_TOOLS=		nroff
+
+INSTALLATION_DIRS+=	include ${PKGMANDIR}/man3
+PKGSRC_LOCKTYPE=	none	# avoid "bootstrapping problem"
+
+do-extract:
+	${CP} -R ${FILESDIR} ${WRKSRC}
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/libpthread_dbg/PLIST b/libpthread_dbg/PLIST
new file mode 100644
index 0000000000..a078f9b9bb
--- /dev/null
+++ b/libpthread_dbg/PLIST
@@ -0,0 +1,7 @@
+@comment $NetBSD: PLIST,v 1.1 2016/10/01 18:37:15 kamil Exp $
+bin/plist-add
+bin/plist-del
+bin/plist-sort
+man/man1/plist-add.1
+man/man1/plist-del.1
+man/man1/plist-sort.1
diff --git a/libpthread_dbg/distinfo b/libpthread_dbg/distinfo
new file mode 100644
index 0000000000..afc76512f4
--- /dev/null
+++ b/libpthread_dbg/distinfo
@@ -0,0 +1,2 @@
+$NetBSD$
+
diff --git a/libpthread_dbg/files/Makefile b/libpthread_dbg/files/Makefile
new file mode 100644
index 0000000000..fd1cfab0df
--- /dev/null
+++ b/libpthread_dbg/files/Makefile
@@ -0,0 +1,21 @@
+#	$NetBSD: Makefile,v 1.16 2016/11/22 03:52:01 kamil Exp $
+#
+
+#.include <bsd.own.mk>
+
+SRCS=	pthread_dbg.c 
+
+CPPFLAGS+=	-D__LIBPTHREAD_SOURCE__
+
+INCS=	pthread_dbg.h
+
+MAN+=	pthread_dbg.3
+MAN+=	td_open.3
+MAN+=	td_map_pth2thr.3
+MAN+=	td_thr_getname.3
+MAN+=	td_thr_info.3
+MAN+=	td_thr_iter.3
+
+MLINKS+=	td_open.3 td_close.3
+
+.include <bsd.lib.mk>
diff --git a/libpthread_dbg/files/pthread.h b/libpthread_dbg/files/pthread.h
new file mode 100644
index 0000000000..fed3221652
--- /dev/null
+++ b/libpthread_dbg/files/pthread.h
@@ -0,0 +1,422 @@
+/*	$NetBSD: pthread.h,v 1.38 2016/10/30 23:26:33 kamil Exp $	*/
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_PTHREAD_H
+#define _LIB_PTHREAD_H
+
+#include <sys/cdefs.h>
+
+#include <time.h>	/* For timespec */
+#include <sched.h>
+#include <sys/featuretest.h>
+
+#include <pthread_types.h>
+
+__BEGIN_DECLS
+int	pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
+int	pthread_create(pthread_t * __restrict,
+	    const pthread_attr_t * __restrict, void *(*)(void *),
+	    void * __restrict);
+void	pthread_exit(void *) __attribute__((__noreturn__));
+int	pthread_join(pthread_t, void **);
+int	pthread_equal(pthread_t, pthread_t);
+pthread_t	pthread_self(void);
+int	pthread_detach(pthread_t);
+
+int	pthread_getrrtimer_np(void);
+int	pthread_setrrtimer_np(int);
+
+int	pthread_attr_init(pthread_attr_t *);
+int	pthread_attr_destroy(pthread_attr_t *);
+int	pthread_attr_get_np(pthread_t, pthread_attr_t *);
+int	pthread_attr_getguardsize(const pthread_attr_t * __restrict,
+	    size_t * __restrict);
+int	pthread_attr_setguardsize(pthread_attr_t *, size_t);
+int	pthread_attr_getinheritsched(const pthread_attr_t * __restrict,
+	    int * __restrict);
+int	pthread_attr_setinheritsched(pthread_attr_t *, int);
+int	pthread_attr_getschedparam(const pthread_attr_t * __restrict,
+	    struct sched_param * __restrict);
+int	pthread_attr_setschedparam(pthread_attr_t * __restrict,
+    const struct sched_param * __restrict);
+int	pthread_attr_getschedpolicy(const pthread_attr_t * __restrict,
+	    int * __restrict);
+int	pthread_attr_setschedpolicy(pthread_attr_t *, int);
+int	pthread_attr_getscope(const pthread_attr_t * __restrict,
+	    int * __restrict);
+int	pthread_attr_setscope(pthread_attr_t *, int);
+int	pthread_attr_getstack(const pthread_attr_t * __restrict,
+	    void ** __restrict, size_t * __restrict);
+int	pthread_attr_setstack(pthread_attr_t *, void *, size_t);
+int	pthread_attr_getstacksize(const pthread_attr_t * __restrict,
+	    size_t * __restrict);
+int	pthread_attr_setstacksize(pthread_attr_t *, size_t);
+int	pthread_attr_getstackaddr(const pthread_attr_t * __restrict,
+	    void ** __restrict);
+int	pthread_attr_setstackaddr(pthread_attr_t *, void *);
+int	pthread_attr_getdetachstate(const pthread_attr_t *, int *);
+int	pthread_attr_setdetachstate(pthread_attr_t *, int);
+int	pthread_attr_getname_np(const pthread_attr_t *, char *,
+	    size_t, void **);
+int	pthread_attr_setname_np(pthread_attr_t *, const char *, void *);
+
+int	pthread_mutex_init(pthread_mutex_t * __restrict,
+	    const pthread_mutexattr_t * __restrict);
+int	pthread_mutex_destroy(pthread_mutex_t *);
+int	pthread_mutex_lock(pthread_mutex_t *);
+int	pthread_mutex_trylock(pthread_mutex_t *);
+int	pthread_mutex_unlock(pthread_mutex_t *);
+int	pthread_mutex_timedlock(pthread_mutex_t * __restrict,
+	    const struct timespec * __restrict);
+int	pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict,
+	    int * __restrict);
+int	pthread_mutex_setprioceiling(pthread_mutex_t * __restrict, int,
+	    int * __restrict);
+int	pthread_mutexattr_init(pthread_mutexattr_t *);
+int	pthread_mutexattr_destroy(pthread_mutexattr_t *);
+#ifdef _PTHREAD_PSHARED
+int	pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict,
+	    int * __restrict);
+int	pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+#endif
+int	pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict,
+	    int * __restrict);
+int	pthread_mutexattr_settype(pthread_mutexattr_t *attr, int);
+int	pthread_mutexattr_getprotocol(const pthread_mutexattr_t * __restrict,
+	    int * __restrict);
+int	pthread_mutexattr_setprotocol(pthread_mutexattr_t*,
+	    int);
+int	pthread_mutexattr_getprioceiling(const pthread_mutexattr_t * __restrict,
+	    int * __restrict);
+int	pthread_mutexattr_setprioceiling(pthread_mutexattr_t *,
+	    int);
+int	pthread_cond_init(pthread_cond_t * __restrict,
+	    const pthread_condattr_t * __restrict);
+int	pthread_cond_destroy(pthread_cond_t *);
+int	pthread_cond_wait(pthread_cond_t * __restrict,
+	    pthread_mutex_t * __restrict);
+#ifndef __LIBC12_SOURCE__
+int	pthread_cond_timedwait(pthread_cond_t * __restrict,
+	    pthread_mutex_t * __restrict, const struct timespec * __restrict);
+#endif
+int	pthread_cond_signal(pthread_cond_t *);
+int	pthread_cond_broadcast(pthread_cond_t *);
+int	pthread_condattr_init(pthread_condattr_t *);
+#if defined(_NETBSD_SOURCE)
+int     pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
+int	pthread_condattr_getclock(const pthread_condattr_t * __restrict,
+	    clockid_t * __restrict);
+#endif
+int	pthread_condattr_destroy(pthread_condattr_t *);
+#ifdef _PTHREAD_PSHARED
+int	pthread_condattr_getpshared(const pthread_condattr_t * __restrict,
+	    int * __restrict);
+int	pthread_condattr_setpshared(pthread_condattr_t *, int);
+#endif
+int	pthread_once(pthread_once_t *, void (*)(void));
+
+int	pthread_key_create(pthread_key_t *, void (*)(void *));
+int	pthread_key_delete(pthread_key_t);
+int	pthread_setspecific(pthread_key_t, const void *);
+void*	pthread_getspecific(pthread_key_t);
+
+int	pthread_cancel(pthread_t);
+int	pthread_setcancelstate(int, int *);
+int	pthread_setcanceltype(int, int *);
+void	pthread_testcancel(void);
+
+int	pthread_getname_np(pthread_t, char *, size_t);
+int	pthread_setname_np(pthread_t, const char *, void *);
+
+int 	pthread_attr_setcreatesuspend_np(pthread_attr_t *);
+int	pthread_suspend_np(pthread_t);
+int	pthread_resume_np(pthread_t);
+
+unsigned int	pthread_curcpu_np(void);
+
+int	pthread_getcpuclockid(pthread_t, clockid_t *);
+
+struct pthread_cleanup_store {
+	void	*pad[4];
+};
+
+#define pthread_cleanup_push(routine, arg)			\
+        {							\
+		struct pthread_cleanup_store __store;		\
+		pthread__cleanup_push((routine),(arg), &__store);
+
+#define pthread_cleanup_pop(execute)				\
+		pthread__cleanup_pop((execute), &__store);	\
+	}
+
+void	pthread__cleanup_push(void (*)(void *), void *, void *);
+void	pthread__cleanup_pop(int, void *);
+
+int	pthread_spin_init(pthread_spinlock_t *, int);
+int	pthread_spin_destroy(pthread_spinlock_t *);
+int	pthread_spin_lock(pthread_spinlock_t *);
+int	pthread_spin_trylock(pthread_spinlock_t *);
+int	pthread_spin_unlock(pthread_spinlock_t *);
+
+int	pthread_rwlock_init(pthread_rwlock_t * __restrict,
+	    const pthread_rwlockattr_t * __restrict);
+int	pthread_rwlock_destroy(pthread_rwlock_t *);
+int	pthread_rwlock_rdlock(pthread_rwlock_t *);
+int	pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+int	pthread_rwlock_wrlock(pthread_rwlock_t *);
+int	pthread_rwlock_trywrlock(pthread_rwlock_t *);
+#ifndef __LIBC12_SOURCE__
+int	pthread_rwlock_timedrdlock(pthread_rwlock_t * __restrict,
+	    const struct timespec * __restrict);
+int	pthread_rwlock_timedwrlock(pthread_rwlock_t * __restrict,
+	    const struct timespec * __restrict);
+#endif
+int	pthread_rwlock_unlock(pthread_rwlock_t *);
+int	pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int	pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
+#ifdef _PTHREAD_PSHARED
+int	pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict,
+	    int * __restrict);
+int	pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
+#endif
+int	pthread_barrier_init(pthread_barrier_t * __restrict,
+	    const pthread_barrierattr_t * __restrict, unsigned int);
+int	pthread_barrier_wait(pthread_barrier_t *);
+int	pthread_barrier_destroy(pthread_barrier_t *);
+int	pthread_barrierattr_init(pthread_barrierattr_t *);
+int	pthread_barrierattr_destroy(pthread_barrierattr_t *);
+#ifdef _PTHREAD_PSHARED
+int	pthread_barrierattr_getpshared(const pthread_barrierattr_t * __restrict,
+    int * __restrict);
+int	pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
+#endif
+int	pthread_getschedparam(pthread_t, int * __restrict,
+	    struct sched_param * __restrict);
+int	pthread_setschedparam(pthread_t, int, const struct sched_param *);
+int	pthread_setschedprio(pthread_t, int);
+
+int 	*pthread__errno(void);
+
+#if defined(_NETBSD_SOURCE)
+int	pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);
+int	pthread_setaffinity_np(pthread_t, size_t, cpuset_t *);
+int	pthread_getattr_np(pthread_t, pthread_attr_t *);
+
+int	pthread_mutex_held_np(pthread_mutex_t *);
+pthread_t pthread_mutex_owner_np(pthread_mutex_t *);
+
+int	pthread_rwlock_held_np(pthread_rwlock_t *);
+int	pthread_rwlock_wrheld_np(pthread_rwlock_t *);
+int	pthread_rwlock_rdheld_np(pthread_rwlock_t *);
+
+int	pthread_cond_has_waiters_np(pthread_cond_t *);
+#endif	/* _NETBSD_SOURCE */
+
+__END_DECLS
+
+#define	PTHREAD_CREATE_JOINABLE	0
+#define	PTHREAD_CREATE_DETACHED	1
+
+#define PTHREAD_INHERIT_SCHED	0
+#define PTHREAD_EXPLICIT_SCHED	1
+
+#define PTHREAD_SCOPE_PROCESS	0
+#define PTHREAD_SCOPE_SYSTEM	1
+
+#define PTHREAD_PROCESS_PRIVATE	0
+#define PTHREAD_PROCESS_SHARED	1
+
+#define PTHREAD_CANCEL_DEFERRED		0
+#define PTHREAD_CANCEL_ASYNCHRONOUS	1
+
+#define PTHREAD_CANCEL_ENABLE		0
+#define PTHREAD_CANCEL_DISABLE		1
+
+#define PTHREAD_BARRIER_SERIAL_THREAD	1234567
+
+/*
+ * POSIX 1003.1-2001, section 2.5.9.3: "The symbolic constant
+ * PTHREAD_CANCELED expands to a constant expression of type (void *)
+ * whose value matches no pointer to an object in memory nor the value
+ * NULL."
+ */
+#define PTHREAD_CANCELED	((void *) 1)
+
+/*
+ * Maximum length of a thread's name, including the terminating NUL.
+ */
+#define	PTHREAD_MAX_NAMELEN_NP	32
+
+/*
+ * Mutex attributes.
+ */
+#define	PTHREAD_MUTEX_NORMAL		0
+#define	PTHREAD_MUTEX_ERRORCHECK	1
+#define	PTHREAD_MUTEX_RECURSIVE		2
+#define	PTHREAD_MUTEX_DEFAULT		PTHREAD_MUTEX_NORMAL
+
+#define	PTHREAD_PRIO_NONE		0
+#define	PTHREAD_PRIO_INHERIT		1
+#define	PTHREAD_PRIO_PROTECT		2
+
+#define PTHREAD_COND_INITIALIZER	_PTHREAD_COND_INITIALIZER
+#define PTHREAD_MUTEX_INITIALIZER	_PTHREAD_MUTEX_INITIALIZER
+#define PTHREAD_ONCE_INIT		_PTHREAD_ONCE_INIT
+#define PTHREAD_RWLOCK_INITIALIZER	_PTHREAD_RWLOCK_INITIALIZER
+#define PTHREAD_SPINLOCK_INITIALIZER	_PTHREAD_SPINLOCK_INITIALIZER
+
+/*
+ * Use macros to rename many pthread functions to the corresponding
+ * libc symbols which are either trivial/no-op stubs or the real
+ * thing, depending on whether libpthread is linked in to the
+ * program. This permits code, particularly libraries that do not
+ * directly use threads but want to be thread-safe in the presence of
+ * threaded callers, to use pthread mutexes and the like without
+ * unnecessairly including libpthread in their linkage.
+ *
+ * Left out of this list are functions that can't sensibly be trivial
+ * or no-op stubs in a single-threaded process (pthread_create,
+ * pthread_kill, pthread_detach), functions that normally block and
+ * wait for another thread to do something (pthread_join), and
+ * functions that don't make sense without the previous functions
+ * (pthread_attr_*). The pthread_cond_wait and pthread_cond_timedwait
+ * functions are useful in implementing certain protection mechanisms,
+ * though a non-buggy app shouldn't end up calling them in
+ * single-threaded mode.
+ *
+ * The rename is done as:
+ * #define pthread_foo	__libc_foo
+ * instead of
+ * #define pthread_foo(x) __libc_foo((x))
+ * in order that taking the address of the function ("func =
+ * &pthread_foo;") continue to work.
+ *
+ * POSIX/SUSv3 requires that its functions exist as functions (even if
+ * macro versions exist) and specifically that "#undef pthread_foo" is
+ * legal and should not break anything. Code that does such will not
+ * successfully get the stub behavior implemented here and will
+ * require libpthread to be linked in.
+ */
+
+#ifndef __LIBPTHREAD_SOURCE__
+__BEGIN_DECLS
+int	__libc_mutex_init(pthread_mutex_t * __restrict, const pthread_mutexattr_t * __restrict);
+int	__libc_mutex_lock(pthread_mutex_t *);
+int	__libc_mutex_trylock(pthread_mutex_t *);
+int	__libc_mutex_unlock(pthread_mutex_t *);
+int	__libc_mutex_destroy(pthread_mutex_t *);
+
+int	__libc_mutexattr_init(pthread_mutexattr_t *);
+int	__libc_mutexattr_settype(pthread_mutexattr_t *, int);
+int	__libc_mutexattr_destroy(pthread_mutexattr_t *);
+__END_DECLS
+
+#define	pthread_mutex_init		__libc_mutex_init
+#define	pthread_mutex_lock		__libc_mutex_lock
+#define	pthread_mutex_trylock		__libc_mutex_trylock
+#define	pthread_mutex_unlock		__libc_mutex_unlock
+#define	pthread_mutex_destroy		__libc_mutex_destroy
+
+#define	pthread_mutexattr_init		__libc_mutexattr_init
+#define	pthread_mutexattr_settype	__libc_mutexattr_settype
+#define	pthread_mutexattr_destroy	__libc_mutexattr_destroy
+
+__BEGIN_DECLS
+int	__libc_cond_init(pthread_cond_t * __restrict,
+	    const pthread_condattr_t * __restrict);
+int	__libc_cond_signal(pthread_cond_t *);
+int	__libc_cond_broadcast(pthread_cond_t *);
+int	__libc_cond_wait(pthread_cond_t * __restrict,
+	    pthread_mutex_t * __restrict);
+#ifndef __LIBC12_SOURCE__
+int	__libc_cond_timedwait(pthread_cond_t * __restrict,
+	    pthread_mutex_t * __restrict, const struct timespec * __restrict);
+#endif
+int	__libc_cond_destroy(pthread_cond_t *);
+__END_DECLS
+
+#define	pthread_cond_init	     	__libc_cond_init
+#define	pthread_cond_signal		__libc_cond_signal
+#define	pthread_cond_broadcast		__libc_cond_broadcast
+#define	pthread_cond_wait		__libc_cond_wait
+#define	pthread_cond_timedwait		__libc_cond_timedwait
+#define	pthread_cond_destroy		__libc_cond_destroy
+
+__BEGIN_DECLS
+int	__libc_rwlock_init(pthread_rwlock_t * __restrict,
+	    const pthread_rwlockattr_t * __restrict);
+int	__libc_rwlock_rdlock(pthread_rwlock_t *);
+int	__libc_rwlock_wrlock(pthread_rwlock_t *);
+int	__libc_rwlock_tryrdlock(pthread_rwlock_t *);
+int	__libc_rwlock_trywrlock(pthread_rwlock_t *);
+int	__libc_rwlock_unlock(pthread_rwlock_t *);
+int	__libc_rwlock_destroy(pthread_rwlock_t *);
+__END_DECLS
+
+#define	pthread_rwlock_init		__libc_rwlock_init
+#define	pthread_rwlock_rdlock		__libc_rwlock_rdlock
+#define	pthread_rwlock_wrlock		__libc_rwlock_wrlock
+#define	pthread_rwlock_tryrdlock	__libc_rwlock_tryrdlock
+#define	pthread_rwlock_trywrlock	__libc_rwlock_trywrlock
+#define	pthread_rwlock_unlock		__libc_rwlock_unlock
+#define	pthread_rwlock_destroy		__libc_rwlock_destroy
+
+__BEGIN_DECLS
+int	__libc_thr_keycreate(pthread_key_t *, void (*)(void *));
+int	__libc_thr_setspecific(pthread_key_t, const void *);
+void	*__libc_thr_getspecific(pthread_key_t);
+int	__libc_thr_keydelete(pthread_key_t);
+__END_DECLS
+
+#define	pthread_key_create		__libc_thr_keycreate
+#define	pthread_setspecific		__libc_thr_setspecific
+#define	pthread_getspecific		__libc_thr_getspecific
+#define	pthread_key_delete		__libc_thr_keydelete
+
+__BEGIN_DECLS
+int	__libc_thr_once(pthread_once_t *, void (*)(void));
+pthread_t	__libc_thr_self(void);
+void	__libc_thr_exit(void *) __attribute__((__noreturn__));
+int	__libc_thr_setcancelstate(int, int *);
+int	__libc_thr_equal(pthread_t, pthread_t);
+unsigned int	__libc_thr_curcpu(void);
+__END_DECLS
+
+#define	pthread_once			__libc_thr_once
+#define	pthread_self			__libc_thr_self
+#define	pthread_exit			__libc_thr_exit
+#define	pthread_setcancelstate		__libc_thr_setcancelstate
+#define pthread_equal			__libc_thr_equal
+#define pthread_curcpu_np		__libc_thr_curcpu
+
+#endif /* __LIBPTHREAD_SOURCE__ */
+
+#endif /* _LIB_PTHREAD_H */
diff --git a/libpthread_dbg/files/pthread_dbg.3 b/libpthread_dbg/files/pthread_dbg.3
new file mode 100644
index 0000000000..0f33a06126
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg.3
@@ -0,0 +1,148 @@
+.\"	$NetBSD: pthread_dbg.3,v 1.4 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt PTHREAD_DBG 3
+.Os
+.Sh NAME
+.Nm pthread_dbg
+.Nd POSIX Debug Threads Library
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Pp
+.Nm cc
+.Op Ar flags
+.Ar files
+.Fl lpthread_dbg
+.Op Ar libraries
+.Sh DESCRIPTION
+The
+.Nm
+library provides an implementation of the standard
+.Tn POSIX
+threads library debugging facilities.
+.Pp
+The
+.Nx
+implementation is based on 1:1 thread model, therefore each
+.Xr pthread 3
+has a kernel thread, called a light-weight process (LWP).
+.Pp
+Note that the system private thread interfaces upon which the
+.Xr pthread 3
+library is built are subject to change without notice.
+In order to remain compatible with future
+.Nx
+releases, programs must be linked against the dynamic version of the
+thread library.
+Statically linked programs using the
+.Tn POSIX
+threads framework may not work when run on a future version of the system.
+.Pp
+The
+.Nm
+library is designed to be used in debuggers and to control and introspect the
+.Nx
+implementation of the
+.Tn POSIX
+threads.
+Software may use native
+.Tn LWP
+threads without
+.Xr pthread 3
+layer,
+in that case
+.Nm
+cannot be used.
+.Ss Error codes
+The following error codes are defined in
+.Nm
+functions:
+.Pp
+.Bl -column ".Sy TD_ERR_BADTHREAD" "Request is not meaningful for that thread" -compact
+.\".It Sy "Symbol" Ta Sy "Descriptive name"
+.It Dv TD_ERR_OK Ta "Success"
+.It Dv TD_ERR_ERR Ta "Generic error"
+.It Dv TD_ERR_NOSYM Ta "Symbol not found (proc_lookup)"
+.It Dv TD_ERR_NOOBJ Ta "No object matched the request"
+.It Dv TD_ERR_BADTHREAD Ta "Request is not meaningful for that thread"
+.It Dv TD_ERR_INUSE Ta "The process is already being debugged"
+.It Dv TD_ERR_NOLIB Ta "The process is not using libpthread"
+.It Dv TD_ERR_NOMEM Ta "Memory allocation failed"
+.It Dv TD_ERR_IO Ta "A callback failed to read or write"
+.It Dv TD_ERR_INVAL Ta "Invalid parameter"
+.El
+.Sh FUNCTIONS
+The following functions comprise the core of the
+.Nm
+library:
+.Bl -column -offset indent "td_thr_getname(3)" "convert the pthread_t to a thread handle"
+.It Sy Function Ta Sy Description
+.It Xr td_close 3       Ta close connection to a threaded process
+.It Xr td_map_pth2thr 3 Ta convert a pthread_t to a thread handle
+.It Xr td_open 3        Ta make connection to a threaded process
+.It Xr td_thr_getname 3 Ta get the user-assigned name of a thread
+.It Xr td_thr_info 3    Ta get information on a thread
+.It Xr td_thr_iter 3    Ta iterate over the threads in the process
+.El
+.Sh SEE ALSO
+.Xr pthread 3
+.Sh STANDARDS
+The
+.Nm
+library is a
+.Nx
+extension.
+.Sh HISTORY
+The
+.Nm
+library first appeared in
+.Nx 2.0
+along with the Scheduler Activation thread interface.
+This interface was authored by
+.An Nathan J. Williams
+and merged by
+.An Jason R. Thorpe .
+In
+.Nx 5.0
+the
+.Nm
+library was moved to the new 1:1 thread model.
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
+.Sh BUGS
+It is not possible to debug the
+.Nx
+library with a debugger that is using
+.Nm
+internally.
diff --git a/libpthread_dbg/files/pthread_dbg.c b/libpthread_dbg/files/pthread_dbg.c
new file mode 100644
index 0000000000..70a821ab4b
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg.c
@@ -0,0 +1,520 @@
+/*	$NetBSD: pthread_dbg.c,v 1.51 2016/11/22 04:51:06 kamil Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Nathan J. Williams for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by 
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: pthread_dbg.c,v 1.51 2016/11/22 04:51:06 kamil Exp $");
+
+#define __EXPOSE_STACK 1
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/lock.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <lwp.h>
+
+#include <machine/reg.h>
+
+#include <pthread.h>
+#include <pthread_int.h>
+#include <pthread_dbg.h>
+#include <pthread_dbg_int.h>
+
+#define PT_STACKMASK (proc->stackmask)
+#define OFFSET(thread, field) \
+    (((char *)(thread)->addr) + offsetof(struct __pthread_st, field))
+
+/* Compensate for debuggers that want a zero ID to be a sentinel */
+#define TN_OFFSET 1
+
+static int td__getthread(td_proc_t *proc, caddr_t addr, td_thread_t **threadp);
+
+int
+td_open(struct td_proc_callbacks_t *cb, void *arg, td_proc_t **procp)
+{
+	td_proc_t *proc;
+	caddr_t addr;
+	int dbg;
+	int val;
+
+	proc = malloc(sizeof(*proc));
+	if (proc == NULL)
+		return TD_ERR_NOMEM;
+	proc->cb = cb;
+	proc->arg = arg;
+
+	val = LOOKUP(proc, "pthread__dbg", &addr);
+	if (val != 0) {
+		if (val == TD_ERR_NOSYM)
+			val = TD_ERR_NOLIB;
+		goto error;
+	}
+	proc->dbgaddr = addr;
+
+	val = LOOKUP(proc, "pthread__allqueue", &addr);
+	if (val != 0)
+		goto error;
+	proc->allqaddr = addr;
+
+	val = LOOKUP(proc, "pthread__tsd_list", &addr);
+	if (val != 0)
+		goto error;
+	proc->tsdlistaddr = addr;
+
+	val = LOOKUP(proc, "pthread__tsd_destructors", &addr);
+	if (val != 0)
+		goto error;
+	proc->tsddestaddr = addr;
+
+	val = READ(proc, proc->dbgaddr, &dbg, sizeof(int));
+	if (val != 0)
+		goto error;
+
+	if (dbg != 0) {
+		/* Another instance of libpthread_dbg is already attached. */
+		val = TD_ERR_INUSE;
+		goto error;
+	}
+
+	val = LOOKUP(proc, "pthread__stacksize_lg", &addr);
+	if (val == 0)
+		proc->stacksizeaddr = addr;
+	else
+		proc->stacksizeaddr = NULL;
+	proc->stacksizelg = -1;
+	proc->stacksize = 0;
+	proc->stackmask = 0;
+
+	proc->regbuf = NULL;
+	proc->fpregbuf = NULL;
+	
+	dbg = getpid();
+	/*
+	 * If this fails it probably means we're debugging a core file and
+	 * can't write to it.
+	 * If it's something else we'll lose the next time we hit WRITE,
+	 * but not before, and that's OK.
+	 */
+	WRITE(proc, proc->dbgaddr, &dbg, sizeof(int));
+
+	PTQ_INIT(&proc->threads);
+	
+	*procp = proc;
+
+	return 0;
+
+ error:
+	free(proc);
+	return val;
+}
+
+int
+td_close(td_proc_t *proc)
+{
+	int dbg;
+	td_thread_t *t, *next;
+
+	dbg = 0;
+	/*
+	 * Error returns from this write are mot really a problem;
+	 * the process doesn't exist any more.
+	 */
+	WRITE(proc, proc->dbgaddr, &dbg, sizeof(int));
+
+	/* Deallocate the list of thread structures */
+	for (t = PTQ_FIRST(&proc->threads); t; t = next) {
+		next = PTQ_NEXT(t, list);
+		PTQ_REMOVE(&proc->threads, t, list);
+		free(t);
+	}
+	if (proc->regbuf != NULL) {
+		free(proc->regbuf);
+		free(proc->fpregbuf);
+	}
+
+	free(proc);
+	return 0;
+}
+
+
+int
+td_thr_iter(td_proc_t *proc, int (*call)(td_thread_t *, void *), void *callarg)
+{
+	int val;
+	caddr_t next;
+	pthread_queue_t allq;
+	td_thread_t *thread;
+
+	val = READ(proc, proc->allqaddr, &allq, sizeof(allq));
+	if (val != 0)
+		return val;
+	
+	next = (void *)allq.ptqh_first;
+	while (next != NULL) {
+		val = td__getthread(proc, next, &thread);
+		if (val != 0)
+			return val;
+		val = (*call)(thread, callarg);
+		if (val != 0)
+			return 0;
+
+		val = READ(proc, 
+		    next + offsetof(struct __pthread_st, pt_allq.ptqe_next), 
+		    &next, sizeof(next));
+		if (val != 0)
+			return val;
+	}
+	return 0;
+}
+
+int
+td_thr_info(td_thread_t *thread, td_thread_info_t *info)
+{
+	int tmp, val;
+
+	val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+	if (val != 0)
+		return val;
+
+	if (tmp != PT_MAGIC)
+		return TD_ERR_BADTHREAD;
+
+	info->thread_addr = thread->addr;
+	if ((val = READ(thread->proc,
+	    OFFSET(thread, pt_state), &tmp, sizeof(tmp))) != 0)
+		return val;
+	switch (tmp) {
+	case PT_STATE_RUNNING:
+		info->thread_state = TD_STATE_RUNNING;
+		break;
+	case PT_STATE_ZOMBIE:
+		info->thread_state = TD_STATE_ZOMBIE;
+		break;
+	case PT_STATE_DEAD:
+		info->thread_state = TD_STATE_DEAD;
+		break;
+	default:
+		info->thread_state = TD_STATE_UNKNOWN;
+	}
+
+	if ((val = READ(thread->proc, OFFSET(thread, pt_stack),
+	    &info->thread_stack, sizeof(stack_t))) != 0)
+		return val;
+
+	if ((val = READ(thread->proc, OFFSET(thread, pt_errno),
+	    &info->thread_errno, sizeof(info->thread_errno))) != 0)
+		return val;
+
+	if ((val = READ(thread->proc, OFFSET(thread, pt_lid),
+	    &info->thread_id, sizeof(info->thread_id))) != 0)
+		return val;
+
+	info->thread_id += TN_OFFSET;
+	
+	return 0;
+}
+
+int
+td_thr_getname(td_thread_t *thread, char *name, int len)
+{
+	int val, tmp;
+	caddr_t nameaddr;
+	
+
+	val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+	if (val != 0)
+		return val;
+
+	if (tmp != PT_MAGIC)
+		return TD_ERR_BADTHREAD;
+
+	if ((val = READ(thread->proc, OFFSET(thread, pt_name),
+	    &nameaddr, sizeof(nameaddr))) != 0)
+		return val;
+
+	if (nameaddr == 0)
+		name[0] = '\0';
+	else if ((val = READ(thread->proc, nameaddr,
+	    name, (size_t)MIN(PTHREAD_MAX_NAMELEN_NP, len))) != 0)
+		return val;
+
+	if (len < PTHREAD_MAX_NAMELEN_NP)
+		name[len - 1] = '\0';
+
+	return 0;
+}
+
+int
+td_thr_getregs(td_thread_t *thread, int regset, void *buf)
+{
+	int tmp, val;
+
+	if ((val = READ(thread->proc, OFFSET(thread, pt_state),
+	    &tmp, sizeof(tmp))) != 0)
+		return val;
+
+	switch (tmp) {
+	case PT_STATE_RUNNING:
+		/*
+		 * The register state of the thread is live in the
+		 * inferior process's register state.
+		 */
+		val = GETREGS(thread->proc, regset, thread->lwp, buf);
+		if (val != 0)
+			return val;
+		break;
+	case PT_STATE_ZOMBIE:
+	case PT_STATE_DEAD:
+	default:
+		return TD_ERR_BADTHREAD;
+	}
+
+	return 0;
+}
+
+int
+td_thr_setregs(td_thread_t *thread, int regset, void *buf)
+{
+	int val, tmp;
+
+	if ((val = READ(thread->proc, OFFSET(thread, pt_state),
+	    &tmp, sizeof(tmp))) != 0)
+		return val;
+
+	switch (tmp) {
+	case PT_STATE_RUNNING:
+		/*
+		 * The register state of the thread is live in the
+		 * inferior process's register state.  
+		 */
+		val = SETREGS(thread->proc, regset, thread->lwp, buf);
+		if (val != 0)
+			return val;
+		break;
+	case PT_STATE_ZOMBIE:
+	case PT_STATE_DEAD:
+	default:
+		return TD_ERR_BADTHREAD;
+	}
+
+	return 0;
+}
+
+int
+td_map_pth2thr(td_proc_t *proc, pthread_t thread, td_thread_t **threadp)
+{
+	int magic, val;
+
+	val = READ(proc, (caddr_t)&thread->pt_magic, &magic, sizeof(magic));
+	if (val != 0)
+		return val;
+
+	if (magic != PT_MAGIC)
+		return TD_ERR_NOOBJ;
+
+	val = td__getthread(proc, (void *)thread, threadp);
+	if (val != 0)
+		return val;
+
+	return 0;
+}
+
+int
+td_map_id2thr(td_proc_t *proc, int threadid, td_thread_t **threadp)
+{
+	int val, num;
+	caddr_t next;
+	pthread_queue_t allq;
+	td_thread_t *thread;
+
+
+	val = READ(proc, proc->allqaddr, &allq, sizeof(allq));
+	if (val != 0)
+		return val;
+	
+	/* Correct for offset */
+	threadid -= TN_OFFSET;
+	next = (void *)allq.ptqh_first;
+	while (next != NULL) {
+		val = READ(proc, next + offsetof(struct __pthread_st, pt_lid), 
+		    &num, sizeof(num));
+
+		if (num == threadid)
+			break;
+
+		val = READ(proc, 
+		    next + offsetof(struct __pthread_st, pt_allq.ptqe_next), 
+		    &next, sizeof(next));
+		if (val != 0)
+			return val;
+	}
+
+	if (next == 0) {
+		/* A matching thread was not found. */
+		return TD_ERR_NOOBJ;
+	}
+
+	val = td__getthread(proc, next, &thread);
+	if (val != 0)
+		return val;
+	*threadp = thread;
+
+	return 0;
+}
+
+int
+td_tsd_iter(td_proc_t *proc,
+    int (*call)(pthread_key_t, void (*)(void *), void *), void *arg)
+{
+#ifdef notyet
+	int val;
+	int i;
+	void *allocated;
+	void (*destructor)(void *);
+
+	for (i = 0; i < pthread_keys_max; i++) {
+		val = READ(proc, proc->tsdlistaddr + i * sizeof(allocated),
+		    &allocated, sizeof(allocated));
+		if (val != 0)
+			return val;
+
+		if ((uintptr_t)allocated) {
+			val = READ(proc,  proc->tsddestaddr +
+			    i * sizeof(destructor),
+			    &destructor, sizeof(destructor));
+			if (val != 0)
+				return val;
+			
+			val = (call)(i, destructor, arg);
+			if (val != 0)
+				return val;
+		}
+	}
+#else
+	abort();
+#endif
+
+	return 0;
+}
+		
+/* Suspend a thread from running */
+int
+td_thr_suspend(td_thread_t *thread)
+{
+	int tmp, val;
+
+	/* validate the thread */
+	val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+	if (val != 0)
+		return val;
+	if (tmp != PT_MAGIC)
+		return TD_ERR_BADTHREAD;
+
+	val = READ(thread->proc, OFFSET(thread, pt_lid), &tmp, sizeof(tmp));
+	if (val != 0)
+		return val;
+
+	/* XXXLWP continue the sucker */;
+
+	return 0;
+}
+
+/* Restore a suspended thread to its previous state */
+int
+td_thr_resume(td_thread_t *thread)
+{
+	int tmp, val;
+
+	/* validate the thread */
+	val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+	if (val != 0)
+		return val;
+	if (tmp != PT_MAGIC)
+		return TD_ERR_BADTHREAD;
+
+	val = READ(thread->proc, OFFSET(thread, pt_lid), &tmp, sizeof(tmp));
+	if (val != 0)
+		return val;
+
+	/* XXXLWP continue the sucker */;
+
+	return 0;
+}
+
+static int
+td__getthread(td_proc_t *proc, caddr_t addr, td_thread_t **threadp)
+{
+	td_thread_t *thread;
+	
+	/*
+	 * Check if we've allocated a descriptor for this thread. 
+	 * Sadly, this makes iterating over a set of threads O(N^2)
+	 * in the number of threads. More sophisticated data structures
+	 * can wait.
+       	 */
+	PTQ_FOREACH(thread, &proc->threads, list) {
+		if (thread->addr == addr)
+			break;
+	}
+	if (thread == NULL) {
+		thread = malloc(sizeof(*thread));
+		if (thread == NULL)
+			return TD_ERR_NOMEM;
+		thread->proc = proc;
+		thread->addr = addr;
+		thread->lwp  = 0;
+		PTQ_INSERT_HEAD(&proc->threads, thread, list);
+	}
+
+	*threadp = thread;
+	return 0;
+}
+
+int
+td_thr_tsd(td_thread_t *thread, pthread_key_t key, void **value)
+{
+	int val;
+
+	val = READ(thread->proc, OFFSET(thread, pt_specific) +
+	    key * sizeof(void *), value, sizeof(*value));
+
+	return val;
+}
diff --git a/libpthread_dbg/files/pthread_dbg.h b/libpthread_dbg/files/pthread_dbg.h
new file mode 100644
index 0000000000..3edde66a70
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg.h
@@ -0,0 +1,200 @@
+/*	$NetBSD: pthread_dbg.h,v 1.9 2016/11/22 04:51:06 kamil Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Nathan J. Williams for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by 
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_PTHREAD_DBG_H
+#define _LIB_PTHREAD_DBG_H
+
+#include <sys/types.h>
+#include <signal.h>
+
+__BEGIN_DECLS
+
+struct td_proc_st;
+struct td_thread_st;
+struct td_sync_st;
+
+typedef struct td_proc_st td_proc_t;
+typedef struct td_thread_st td_thread_t;
+typedef struct td_sync_st td_sync_t;
+
+struct td_proc_callbacks_t {
+	int (*proc_read)(void *arg, caddr_t addr, void *buf, size_t size);
+	int (*proc_write)(void *arg, caddr_t addr, void *buf, size_t size);
+	int (*proc_lookup)(void *arg, const char *sym, caddr_t *addr);
+	int (*proc_regsize)(void *arg, int regset, size_t *size);
+	int (*proc_getregs)(void *arg, int regset, int lwp, void *buf);
+	int (*proc_setregs)(void *arg, int regset, int lwp, void *buf);
+};
+
+
+typedef struct td_thread_info_st {
+	caddr_t	thread_addr;		/* Address of data structure */
+	int	thread_state;		/* TD_STATE_*; see below */
+	int	thread_type;		/* TD_TYPE_*; see below */
+	int	thread_id;
+	stack_t	thread_stack;
+	int	thread_hasjoiners;	/* 1 if threads are waiting */
+	caddr_t	thread_tls;
+	int	thread_errno;
+	sigset_t thread_sigmask;
+	sigset_t thread_sigpending;
+	long	pad[32];
+} td_thread_info_t;
+
+#define	TD_STATE_UNKNOWN	0
+#define TD_STATE_RUNNING	1	/* On a processor */
+#define	TD_STATE_UNUSED2	2	/* former TD_STATE_RUNNABLE for SA */
+#define	TD_STATE_UNUSED3	3	/* former TD_STATE_BLOCKED for SA */
+#define	TD_STATE_UNUSED4	4	/* former TD_STATE_SLEEPING for SA */
+#define	TD_STATE_ZOMBIE		5
+#define	TD_STATE_UNUSED6	6	/* former TD_STATE_SUSPENDED for SA */
+#define	TD_STATE_DEAD		7
+
+#define	TD_TYPE_UNUSED0	0
+#define	TD_TYPE_UNUSED1	1
+#define	TD_TYPE_UNUSED2	2
+
+typedef struct {
+	caddr_t	sync_addr;	/* Address within the process */
+	int	sync_type;	/* TD_SYNC_*; see below */
+	size_t	sync_size;
+	int	sync_haswaiters;  /* 1 if threads are known to be waiting */
+	union {
+		struct {
+			int	locked;
+			td_thread_t *owner;
+		} mutex;
+		struct {
+			int	locked;
+		} spin;
+		struct {
+			td_thread_t *thread;
+		} join;
+		struct {
+			int	locked;
+			int	readlocks;
+			td_thread_t *writeowner;
+		} rwlock;
+		long pad[8];
+	} sync_data;
+} td_sync_info_t;
+
+#define	TD_SYNC_UNKNOWN	0
+#define	TD_SYNC_MUTEX	1	/* pthread_mutex_t */
+#define TD_SYNC_COND	2	/* pthread_cond_t */
+#define TD_SYNC_SPIN	3	/* pthread_spinlock_t */
+#define TD_SYNC_JOIN	4	/* thread being joined */
+#define TD_SYNC_RWLOCK	5	/* pthread_rwlock_t */
+
+/* Error return codes */
+#define TD_ERR_OK		0
+#define TD_ERR_ERR		1  /* Generic error */
+#define TD_ERR_NOSYM		2  /* Symbol not found (proc_lookup) */
+#define TD_ERR_NOOBJ		3  /* No object matched the request */
+#define TD_ERR_BADTHREAD	4  /* Request is not meaningful for that thread */
+#define TD_ERR_INUSE		5  /* The process is already being debugged */
+#define TD_ERR_NOLIB		6  /* The process is not using libpthread */
+#define TD_ERR_NOMEM		7  /* malloc() failed */
+#define TD_ERR_IO		8  /* A callback failed to read or write */
+#define TD_ERR_INVAL		9  /* Invalid parameter */
+
+/* Make a connection to a threaded process */
+int td_open(struct td_proc_callbacks_t *, void *arg, td_proc_t **);
+int td_close(td_proc_t *);
+
+/* Iterate over the threads in the process */
+int td_thr_iter(td_proc_t *, int (*)(td_thread_t *, void *), void *);
+
+/* Get information on a thread */
+int td_thr_info(td_thread_t *, td_thread_info_t *);
+
+/* Get the user-assigned name of a thread */
+int td_thr_getname(td_thread_t *, char *, int);
+
+/* Get register state of a thread */
+int td_thr_getregs(td_thread_t *, int, void *);
+
+/* Set register state of a thread */
+int td_thr_setregs(td_thread_t *, int, void *);
+
+/* Iterate over the set of threads that are joining with the given thread */
+int td_thr_join_iter(td_thread_t *, int (*)(td_thread_t *, void *), void *);
+
+/* Get the synchronization object that the thread is sleeping on */
+int td_thr_sleepinfo(td_thread_t *, td_sync_t **);
+
+/* Get information on a synchronization object */
+int td_sync_info(td_sync_t *, td_sync_info_t *);
+
+/* Iterate over the set of threads waiting on a synchronization object */
+int td_sync_waiters_iter(td_sync_t *, int (*)(td_thread_t *, void *), void *);
+
+/* Convert the process address to a synchronization handle, if possible */
+int td_map_addr2sync(td_proc_t *, caddr_t addr, td_sync_t **);
+
+/* Convert the pthread_t to a thread handle, if possible */
+int td_map_pth2thr(td_proc_t *, pthread_t, td_thread_t **);
+
+/* Convert the thread ID to a thread handle, if possible */
+int td_map_id2thr(td_proc_t *, int, td_thread_t **);
+
+/* Return the thread handle of the thread running on the given LWP */
+int td_map_lwp2thr(td_proc_t *, int, td_thread_t **);
+
+/*
+ * Establish a mapping between threads and LWPs. Must be called
+ * every time a live process runs before calling td_thr_getregs() or
+ * td_thr_setregs().
+ */
+int td_map_lwps(td_proc_t *);
+
+/* Iterate over the set of TSD keys in the process */
+int td_tsd_iter(td_proc_t *, int (*)(pthread_key_t, void (*)(void *), void *), 
+    void *);
+
+/* Get a TSD value from a thread */
+int td_thr_tsd(td_thread_t *, pthread_key_t, void **);
+
+/* Suspend a thread from running */
+int td_thr_suspend(td_thread_t *);
+
+/* Restore a suspended thread to its previous state */
+int td_thr_resume(td_thread_t *);
+
+__END_DECLS
+
+#endif /* _LIB_PTHREAD_DBG_H */
diff --git a/libpthread_dbg/files/pthread_dbg_int.h b/libpthread_dbg/files/pthread_dbg_int.h
new file mode 100644
index 0000000000..03cc588231
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg_int.h
@@ -0,0 +1,48 @@
+
+PTQ_HEAD(thread_queue_t, td_thread_st);
+PTQ_HEAD(sync_queue_t, td_sync_st);
+
+struct td_proc_st {
+	struct td_proc_callbacks_t *cb;
+	void *arg;
+
+	void *dbgaddr;
+	void *allqaddr;
+	void *runqaddr;	
+	void *idleqaddr;
+	void *suspqaddr;
+	void *maxlwpsaddr;
+	void *tsdlistaddr;
+	void *tsddestaddr;
+
+	void *stacksizeaddr;
+	int stacksizelg;
+	size_t stacksize;
+	uintptr_t stackmask;
+	struct reg *regbuf;
+	struct fpreg *fpregbuf;
+
+	struct thread_queue_t threads;
+};
+
+
+struct td_thread_st {
+	td_proc_t *proc;
+	void *addr;
+	lwpid_t lwp;
+	PTQ_ENTRY(td_thread_st)	list;
+};
+
+
+struct td_sync_st {
+	td_proc_t *proc;
+	void *addr;
+	PTQ_ENTRY(td_sync_st) list;
+};
+
+#define READ(proc, addr, buf, size) ((proc)->cb->proc_read((proc)->arg, (addr), (buf), (size)))
+#define WRITE(proc, addr, buf, size) ((proc)->cb->proc_write((proc)->arg, (addr), (buf), (size)))
+#define LOOKUP(proc, sym, addr) ((proc)->cb->proc_lookup((proc)->arg, (sym), (addr)))
+#define REGSIZE(proc, regset, size) ((proc)->cb->proc_regsize((proc)->arg, (regset), (size)))
+#define GETREGS(proc, regset, lwp, buf) ((proc)->cb->proc_getregs((proc)->arg, (regset), (lwp), (buf)))
+#define SETREGS(proc, regset, lwp, buf) ((proc)->cb->proc_setregs((proc)->arg, (regset), (lwp), (buf)))
diff --git a/libpthread_dbg/files/pthread_int.h b/libpthread_dbg/files/pthread_int.h
new file mode 100644
index 0000000000..b3463ee598
--- /dev/null
+++ b/libpthread_dbg/files/pthread_int.h
@@ -0,0 +1,333 @@
+/*	$NetBSD: pthread_int.h,v 1.92 2015/05/29 16:05:13 christos Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams and Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * NOTE: when changing anything in this file, please ensure that
+ * libpthread_dbg still compiles.
+ */
+
+#ifndef _LIB_PTHREAD_INT_H
+#define _LIB_PTHREAD_INT_H
+
+#include <sys/tls.h>
+
+/* #define PTHREAD__DEBUG */
+#define ERRORCHECK
+
+#include "pthread_types.h"
+#include "pthread_queue.h"
+#include "pthread_md.h"
+
+/* Need to use libc-private names for atomic operations. */
+#include "../../common/lib/libc/atomic/atomic_op_namespace.h"
+
+#include <sys/atomic.h>
+#include <sys/rbtree.h>
+
+#include <limits.h>
+#include <lwp.h>
+#include <signal.h>
+#include <stdbool.h>
+
+#ifdef __GNUC__
+#define	PTHREAD_HIDE	__attribute__ ((visibility("hidden")))
+#else
+#define	PTHREAD_HIDE	/* nothing */
+#endif
+
+#define	PTHREAD__UNPARK_MAX	32
+
+/*
+ * The size of this structure needs to be no larger than struct
+ * __pthread_cleanup_store, defined in pthread.h.
+ */
+struct pt_clean_t {
+	PTQ_ENTRY(pt_clean_t)	ptc_next;
+	void	(*ptc_cleanup)(void *);
+	void	*ptc_arg;
+};
+
+/* Private data for pthread_attr_t */
+struct pthread_attr_private {
+	char ptap_name[PTHREAD_MAX_NAMELEN_NP];
+	void *ptap_namearg;
+	void *ptap_stackaddr;
+	size_t ptap_stacksize;
+	size_t ptap_guardsize;
+	struct sched_param ptap_sp;
+	int ptap_policy;
+};
+
+struct pthread_lock_ops {
+	void	(*plo_init)(__cpu_simple_lock_t *);
+	int	(*plo_try)(__cpu_simple_lock_t *);
+	void	(*plo_unlock)(__cpu_simple_lock_t *);
+	void	(*plo_lock)(__cpu_simple_lock_t *);
+};
+
+struct	__pthread_st {
+	pthread_t	pt_self;	/* Must be first. */
+#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
+	struct tls_tcb	*pt_tls;	/* Thread Local Storage area */
+#endif
+	unsigned int	pt_magic;	/* Magic number */
+	int		pt_state;	/* running, blocked, etc. */
+	pthread_mutex_t	pt_lock;	/* lock on state */
+	int		pt_flags;	/* see PT_FLAG_* below */
+	int		pt_cancel;	/* Deferred cancellation */
+	int		pt_errno;	/* Thread-specific errno. */
+	stack_t		pt_stack;	/* Our stack */
+	bool		pt_stack_allocated;
+	size_t		pt_guardsize;
+	void		*pt_exitval;	/* Read by pthread_join() */
+	char		*pt_name;	/* Thread's name, set by the app. */
+	int		pt_willpark;	/* About to park */
+	lwpid_t		pt_unpark;	/* Unpark this when parking */
+	struct pthread_lock_ops pt_lockops;/* Cached to avoid PIC overhead */
+	pthread_mutex_t	*pt_droplock;	/* Drop this lock if cancelled */
+	pthread_cond_t	pt_joiners;	/* Threads waiting to join. */
+	void		*(*pt_func)(void *);/* Function to call at start. */
+	void		*pt_arg;	/* Argument to pass at start. */
+
+	/* Threads to defer waking, usually until pthread_mutex_unlock(). */
+	lwpid_t		pt_waiters[PTHREAD__UNPARK_MAX];
+	size_t		pt_nwaiters;
+
+	/* Stack of cancellation cleanup handlers and their arguments */
+	PTQ_HEAD(, pt_clean_t)	pt_cleanup_stack;
+
+	/* LWP ID and entry on the list of all threads. */
+	lwpid_t		pt_lid;
+	rb_node_t	pt_alltree;
+	PTQ_ENTRY(__pthread_st) pt_allq;
+	PTQ_ENTRY(__pthread_st)	pt_deadq;
+
+	/*
+	 * General synchronization data.  We try to align, as threads
+	 * on other CPUs will access this data frequently.
+	 */
+	int		pt_dummy1 __aligned(128);
+	struct lwpctl 	*pt_lwpctl;	/* Kernel/user comms area */
+	volatile int	pt_blocking;	/* Blocking in userspace */
+	volatile int	pt_rwlocked;	/* Handed rwlock successfully */
+	volatile int	pt_signalled;	/* Received pthread_cond_signal() */
+	volatile int	pt_mutexwait;	/* Waiting to acquire mutex */
+	void * volatile pt_mutexnext;	/* Next thread in chain */
+	void * volatile	pt_sleepobj;	/* Object slept on */
+	PTQ_ENTRY(__pthread_st) pt_sleep;
+	void		(*pt_early)(void *);
+	int		pt_dummy2 __aligned(128);
+
+	/* Thread-specific data.  Large so it sits close to the end. */
+	int		pt_havespecific;
+	struct pt_specific {
+		void *pts_value;
+		PTQ_ENTRY(pt_specific) pts_next;
+	} pt_specific[];
+};
+
+/* Thread states */
+#define PT_STATE_RUNNING	1
+#define PT_STATE_ZOMBIE		5
+#define PT_STATE_DEAD		6
+
+/* Flag values */
+
+#define PT_FLAG_DETACHED	0x0001
+#define PT_FLAG_CS_DISABLED	0x0004	/* Cancellation disabled */
+#define PT_FLAG_CS_ASYNC	0x0008  /* Cancellation is async */
+#define PT_FLAG_CS_PENDING	0x0010
+#define PT_FLAG_SCOPE_SYSTEM	0x0040
+#define PT_FLAG_EXPLICIT_SCHED	0x0080
+#define PT_FLAG_SUSPENDED	0x0100	/* In the suspended queue */
+
+#define PT_MAGIC	0x11110001
+#define PT_DEAD		0xDEAD0001
+
+#define PT_ATTR_MAGIC	0x22220002
+#define PT_ATTR_DEAD	0xDEAD0002
+
+extern size_t	pthread__stacksize;
+extern size_t	pthread__pagesize;
+extern int	pthread__nspins;
+extern int	pthread__concurrency;
+extern int 	pthread__osrev;
+extern int 	pthread__unpark_max;
+extern int	pthread_keys_max;
+
+extern int	__uselibcstub;
+
+/* Flag to be used in a ucontext_t's uc_flags indicating that
+ * the saved register state is "user" state only, not full
+ * trap state.
+ */
+#define _UC_USER_BIT		30
+#define _UC_USER		(1LU << _UC_USER_BIT)
+
+/* Utility functions */
+void	pthread__unpark_all(pthread_queue_t *, pthread_t, pthread_mutex_t *)
+    PTHREAD_HIDE;
+void	pthread__unpark(pthread_queue_t *, pthread_t, pthread_mutex_t *)
+    PTHREAD_HIDE;
+int	pthread__park(pthread_t, pthread_mutex_t *, pthread_queue_t *,
+		      const struct timespec *, int, const void *)
+		      PTHREAD_HIDE;
+pthread_mutex_t *pthread__hashlock(volatile const void *) PTHREAD_HIDE;
+
+/* Internal locking primitives */
+void	pthread__lockprim_init(void) PTHREAD_HIDE;
+void	pthread_lockinit(pthread_spin_t *) PTHREAD_HIDE;
+
+static inline void pthread__spinlock(pthread_t, pthread_spin_t *)
+    __attribute__((__always_inline__));
+static inline void
+pthread__spinlock(pthread_t self, pthread_spin_t *lock)
+{
+	if (__predict_true((*self->pt_lockops.plo_try)(lock)))
+		return;
+	(*self->pt_lockops.plo_lock)(lock);
+}
+
+static inline int pthread__spintrylock(pthread_t, pthread_spin_t *)
+    __attribute__((__always_inline__));
+static inline int
+pthread__spintrylock(pthread_t self, pthread_spin_t *lock)
+{
+	return (*self->pt_lockops.plo_try)(lock);
+}
+
+static inline void pthread__spinunlock(pthread_t, pthread_spin_t *)
+    __attribute__((__always_inline__));
+static inline void
+pthread__spinunlock(pthread_t self, pthread_spin_t *lock)
+{
+	(*self->pt_lockops.plo_unlock)(lock);
+}
+
+extern const struct pthread_lock_ops *pthread__lock_ops;
+
+int	pthread__simple_locked_p(__cpu_simple_lock_t *) PTHREAD_HIDE;
+#define	pthread__simple_lock_init(alp)	(*pthread__lock_ops->plo_init)(alp)
+#define	pthread__simple_lock_try(alp)	(*pthread__lock_ops->plo_try)(alp)
+#define	pthread__simple_unlock(alp)	(*pthread__lock_ops->plo_unlock)(alp)
+
+void	pthread__testcancel(pthread_t) PTHREAD_HIDE;
+int	pthread__find(pthread_t) PTHREAD_HIDE;
+
+#ifndef PTHREAD_MD_INIT
+#define PTHREAD_MD_INIT
+#endif
+
+#ifndef _INITCONTEXT_U_MD
+#define _INITCONTEXT_U_MD(ucp)
+#endif
+
+#define _INITCONTEXT_U(ucp) do {					\
+	(ucp)->uc_flags = _UC_CPU | _UC_STACK;				\
+	_INITCONTEXT_U_MD(ucp)						\
+	} while (/*CONSTCOND*/0)
+
+
+#if !defined(__HAVE_TLS_VARIANT_I) && !defined(__HAVE_TLS_VARIANT_II)
+#error Either __HAVE_TLS_VARIANT_I or __HAVE_TLS_VARIANT_II must be defined
+#endif
+
+#ifdef _PTHREAD_GETTCB_EXT
+struct tls_tcb *_PTHREAD_GETTCB_EXT(void);
+#endif
+
+static inline pthread_t __constfunc
+pthread__self(void)
+{
+#if defined(_PTHREAD_GETTCB_EXT)
+	struct tls_tcb * const tcb = _PTHREAD_GETTCB_EXT();
+#elif defined(__HAVE___LWP_GETTCB_FAST)
+	struct tls_tcb * const tcb = __lwp_gettcb_fast();
+#else
+	struct tls_tcb * const tcb = __lwp_getprivate_fast();
+#endif
+	return (pthread_t)tcb->tcb_pthread;
+}
+
+#define pthread__abort()						\
+	pthread__assertfunc(__FILE__, __LINE__, __func__, "unreachable")
+
+#define pthread__assert(e) do {						\
+	if (__predict_false(!(e)))					\
+       	       pthread__assertfunc(__FILE__, __LINE__, __func__, #e);	\
+        } while (/*CONSTCOND*/0)
+
+#define pthread__error(err, msg, e) do {				\
+	if (__predict_false(!(e))) {					\
+       	       pthread__errorfunc(__FILE__, __LINE__, __func__, msg);	\
+	       return (err);						\
+	} 								\
+        } while (/*CONSTCOND*/0)
+
+void 	*pthread_tsd_init(size_t *) PTHREAD_HIDE;
+void	pthread__destroy_tsd(pthread_t) PTHREAD_HIDE;
+__dead void	pthread__assertfunc(const char *, int, const char *, const char *)
+			    PTHREAD_HIDE;
+void	pthread__errorfunc(const char *, int, const char *, const char *)
+			   PTHREAD_HIDE;
+char	*pthread__getenv(const char *) PTHREAD_HIDE;
+__dead void	pthread__cancelled(void) PTHREAD_HIDE;
+void	pthread__mutex_deferwake(pthread_t, pthread_mutex_t *) PTHREAD_HIDE;
+int	pthread__checkpri(int) PTHREAD_HIDE;
+int	pthread__add_specific(pthread_t, pthread_key_t, const void *) PTHREAD_HIDE;
+
+#ifndef pthread__smt_pause
+#define	pthread__smt_pause()	/* nothing */
+#endif
+#ifndef pthread__smt_wake
+#define	pthread__smt_wake()	/* nothing */
+#endif
+
+/*
+ * Bits in the owner field of the lock that indicate lock state.  If the
+ * WRITE_LOCKED bit is clear, then the owner field is actually a count of
+ * the number of readers.
+ */
+#define	RW_HAS_WAITERS		0x01	/* lock has waiters */
+#define	RW_WRITE_WANTED		0x02	/* >= 1 waiter is a writer */
+#define	RW_WRITE_LOCKED		0x04	/* lock is currently write locked */
+#define	RW_UNUSED		0x08	/* currently unused */
+
+#define	RW_FLAGMASK		0x0f
+
+#define	RW_READ_COUNT_SHIFT	4
+#define	RW_READ_INCR		(1 << RW_READ_COUNT_SHIFT)
+#define	RW_THREAD		((uintptr_t)-RW_READ_INCR)
+#define	RW_OWNER(rw)		((rw)->rw_owner & RW_THREAD)
+#define	RW_COUNT(rw)		((rw)->rw_owner & RW_THREAD)
+#define	RW_FLAGS(rw)		((rw)->rw_owner & ~RW_THREAD)
+
+#endif /* _LIB_PTHREAD_INT_H */
diff --git a/libpthread_dbg/files/shlib_version b/libpthread_dbg/files/shlib_version
new file mode 100644
index 0000000000..dc91478808
--- /dev/null
+++ b/libpthread_dbg/files/shlib_version
@@ -0,0 +1,5 @@
+#	$NetBSD: shlib_version,v 1.5 2009/01/11 03:07:49 christos Exp $
+#	Remember to update distrib/sets/lists/base/shl.* when changing
+#
+major=2
+minor=0
diff --git a/libpthread_dbg/files/td_map_pth2thr.3 b/libpthread_dbg/files/td_map_pth2thr.3
new file mode 100644
index 0000000000..159d38578e
--- /dev/null
+++ b/libpthread_dbg/files/td_map_pth2thr.3
@@ -0,0 +1,71 @@
+.\"	$NetBSD: td_map_pth2thr.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 22, 2016
+.Dt TD_MAP_PTH2THR 3
+.Os
+.Sh NAME
+.Nm td_map_pth2thr
+.Nd convert a pthread_t to a thread handle
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_getname "td_proc_t *proc" "pthread_t thread" "td_thread_t **threadp"
+.Sh DESCRIPTION
+The
+.Nm
+function converts a
+.Ta POSIX
+thread
+.Fa thread
+to a
+.Xr pthread_dbg 3
+specific thread passed in the
+.Fa threadp
+argument.
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_open.3 b/libpthread_dbg/files/td_open.3
new file mode 100644
index 0000000000..93158ff74b
--- /dev/null
+++ b/libpthread_dbg/files/td_open.3
@@ -0,0 +1,79 @@
+.\"	$NetBSD: td_open.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt TD_OPEN 3
+.Os
+.Sh NAME
+.Nm td_open ,
+.Nm td_close
+.Nd make or close a connection to a threaded process
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_open "struct td_proc_callbacks_t *cb" "void *arg" "td_proc_t **procp"
+.Ft int
+.Fn td_close "td_proc_t *proc"
+.Sh DESCRIPTION
+The
+.Fn td_open
+function makes a connection to a threaded process.
+That program must be a consumer of the
+.Tn POSIX
+threads implementation using the
+.Xr pthread 3
+library.
+.Pp
+The
+.Fn td_close
+function closes a connection to a threaded process.
+.Sh RETURN VALUES
+If successful, the
+.Fn td_open
+and
+.Fn td_close
+functions will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Fn td_open
+and
+.Fn td_close
+functions first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_thr_getname.3 b/libpthread_dbg/files/td_thr_getname.3
new file mode 100644
index 0000000000..49e596c88c
--- /dev/null
+++ b/libpthread_dbg/files/td_thr_getname.3
@@ -0,0 +1,75 @@
+.\"	$NetBSD: td_thr_getname.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 22, 2016
+.Dt TD_THR_GETNAME 3
+.Os
+.Sh NAME
+.Nm td_thr_getname
+.Nd get the user-assigned name of a thread
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_getname "td_thread_t *thread" "char *name" "int len"
+.Sh DESCRIPTION
+The
+.Nm
+function retrieves the user-assigned name of a thread
+.Fa thread
+and stores it in the buffer
+.Fa name
+of length
+.Fa len .
+If the name is longer than the buffer size, the result will be truncated.
+The returned string always terminates with a
+.Dv NUL
+byte.
+The maximum length of a thread's name,
+including terminating character, is defined by
+.Dv PTHREAD_MAX_NAMELEN_NP .
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_thr_info.3 b/libpthread_dbg/files/td_thr_info.3
new file mode 100644
index 0000000000..33cea0fde3
--- /dev/null
+++ b/libpthread_dbg/files/td_thr_info.3
@@ -0,0 +1,109 @@
+.\"	$NetBSD: td_thr_info.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt TD_THR_INFO 3
+.Os
+.Sh NAME
+.Nm td_thr_info
+.Nd get information on a thread
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_info "td_thread_t *thread" "td_thread_info_t *info"
+.Sh DESCRIPTION
+The
+.Fn td_thr_info
+function retrieves information on a thread specified in the
+.Fa thread
+argument and saves the result in
+.Fa info .
+.Pp
+The following members are defined in the
+.Dv td_thread_info_t
+structure:
+.Bl -column "thread_state" "caddr_t" "Pointer to underlaying Dv pthread_t object"
+.It Sy Name      Ta Sy Type     Ta Sy Description
+.It thread_addr  Ta Dv caddr_t  Ta Points to underlaying Dv pthread_t object
+.It thread_state Ta Dv int      Ta Defines Dv TD_STATE of the thread
+.\" TODO: Add ATF tests, verify and document:
+.\" thread_type
+.\" thread_id
+.\" thread_stack
+.\" thread_hasjoiners
+.\" thread_tls
+.\" thread_errno
+.\" thread_sigmask
+.\" thread_sigpending
+.El
+.Ss Thread State types
+The following state types are possible in
+.Dv thread_state :
+.Pp
+.Bl -column ".Sy TD_STATE_RUNNING" "Thread is alive" -compact
+.It Dv TD_STATE_UNKNOWN Ta "Unknown state"
+.It Dv TD_STATE_RUNNING Ta "Thread is alive"
+.It Dv TD_STATE_ZOMBIE  Ta "Thread is in the zombie state"
+.It Dv TD_STATE_DEAD    Ta "Thread is dead"
+.El
+.Pp
+It is not possible to retrieve information whether a thread
+is suspended or resumed using this interface,
+as this data is stored only inside the kernel and not in the
+.Dv pthread_t
+object.
+The
+.Dv TD_STATE_RUNNING
+name is kept for backwards compatibility with old Scheduler Activation threads.
+The
+.Dv TD_STATE_RUNNING
+state might only be returned for a mismatch between the versions of
+.Xr pthread 3
+and
+.Xr pthread_dbg 3 .
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_thr_iter.3 b/libpthread_dbg/files/td_thr_iter.3
new file mode 100644
index 0000000000..854245bea1
--- /dev/null
+++ b/libpthread_dbg/files/td_thr_iter.3
@@ -0,0 +1,69 @@
+.\"	$NetBSD: td_thr_iter.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt TD_THR_ITER 3
+.Os
+.Sh NAME
+.Nm td_thr_iter
+.Nd iterate over the threads in a process
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_iter "td_proc_t *proc" "int (*call)(td_thread_t *, void *)" "void *callarg"
+.Sh DESCRIPTION
+The
+.Fn td_thr_iter
+function iterates over all threads in the
+.Fa proc
+process and calls the
+.Fa call
+function for each of them with the
+.Fa callarg
+argument.
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .


Home | Main Index | Thread Index | Old Index