about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-04-02 01:43:22 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-04-02 01:44:14 +0200
commit33574c17eefcf326c1cd30eb9f915ad26d3d9ef2 (patch)
tree2c1b143f2b7a0ceba9fba000b70dd2889d56e60f
parent03e2aa50fd512449025bba8c244d16338d8526a4 (diff)
downloadglibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.tar.gz
glibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.tar.xz
glibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.zip
hurd: Add hurd thread library
Contributed by

Agustina Arzille <avarzille@riseup.net>
Amos Jeffries <squid3@treenet.co.nz>
David Michael <fedora.dm0@gmail.com>
Marco Gerards <marco@gnu.org>
Marcus Brinkmann <marcus@gnu.org>
Neal H. Walfield <neal@gnu.org>
Pino Toscano <toscano.pino@tiscali.it>
Richard Braun <rbraun@sceen.net>
Roland McGrath <roland@gnu.org>
Samuel Thibault <samuel.thibault@ens-lyon.org>
Thomas DiModica <ricinwich@yahoo.com>
Thomas Schwinge <tschwinge@gnu.org>

	* htl: New directory.
	* sysdeps/htl: New directory.
	* sysdeps/hurd/htl: New directory.
	* sysdeps/i386/htl: New directory.
	* sysdeps/mach/htl: New directory.
	* sysdeps/mach/hurd/htl: New directory.
	* sysdeps/mach/hurd/i386/htl: New directory.
	* nscd/Depend, resolv/Depend, rt/Depend: Add htl dependency.
	* sysdeps/mach/hurd/i386/Implies: Add mach/hurd/i386/htl imply.
	* sysdeps/mach/hurd/i386/libpthread.abilist: New file.
-rw-r--r--ChangeLog24
-rw-r--r--htl/Makefile237
-rw-r--r--htl/Versions156
-rw-r--r--htl/alloca_cutoff.c26
-rw-r--r--htl/configure2
-rw-r--r--htl/configure.in4
-rw-r--r--htl/cthreads-compat.c101
-rw-r--r--htl/forward.c283
-rw-r--r--htl/libc_pthread_init.c33
-rw-r--r--htl/libpthread.a22
-rw-r--r--htl/libpthread_pic.a22
-rw-r--r--htl/lockfile.c60
-rw-r--r--htl/pt-alloc.c214
-rw-r--r--htl/pt-cancel.c62
-rw-r--r--htl/pt-cleanup.c27
-rw-r--r--htl/pt-create.c246
-rw-r--r--htl/pt-dealloc.c68
-rw-r--r--htl/pt-detach.c79
-rw-r--r--htl/pt-exit.c111
-rw-r--r--htl/pt-getattr.c51
-rw-r--r--htl/pt-initialize.c83
-rw-r--r--htl/pt-internal.h324
-rw-r--r--htl/pt-join.c75
-rw-r--r--htl/pt-self.c33
-rw-r--r--htl/pt-setcancelstate.c46
-rw-r--r--htl/pt-setcanceltype.c46
-rw-r--r--htl/pt-sigmask.c31
-rw-r--r--htl/pt-spin-inlines.c33
-rw-r--r--htl/pt-testcancel.c35
-rw-r--r--htl/pt-yield.c26
-rw-r--r--htl/shlib-versions1
-rw-r--r--htl/tests/Makefile40
-rw-r--r--htl/tests/README6
-rw-r--r--htl/tests/test-1.c68
-rw-r--r--htl/tests/test-10.c62
-rw-r--r--htl/tests/test-11.c159
-rw-r--r--htl/tests/test-12.c45
-rw-r--r--htl/tests/test-13.c82
-rw-r--r--htl/tests/test-14.c60
-rw-r--r--htl/tests/test-15.c102
-rw-r--r--htl/tests/test-16.c87
-rw-r--r--htl/tests/test-17.c73
-rw-r--r--htl/tests/test-2.c56
-rw-r--r--htl/tests/test-3.c71
-rw-r--r--htl/tests/test-4.c102
-rw-r--r--htl/tests/test-5.c91
-rw-r--r--htl/tests/test-6.c114
-rw-r--r--htl/tests/test-7.c89
-rw-r--r--htl/tests/test-8.c78
-rw-r--r--htl/tests/test-9.c104
-rw-r--r--htl/tests/test-__pthread_destroy_specific-skip.c100
-rw-r--r--nscd/Depend1
-rw-r--r--resolv/Depend1
-rw-r--r--rt/Depend1
-rw-r--r--sysdeps/htl/Implies1
-rw-r--r--sysdeps/htl/Makeconfig11
-rw-r--r--sysdeps/htl/Makefile7
-rw-r--r--sysdeps/htl/Subdirs1
-rw-r--r--sysdeps/htl/Versions15
-rw-r--r--sysdeps/htl/bits/cancelation.h50
-rw-r--r--sysdeps/htl/bits/pthread-np.h26
-rw-r--r--sysdeps/htl/bits/pthread.h36
-rw-r--r--sysdeps/htl/bits/pthreadtypes.h131
-rw-r--r--sysdeps/htl/bits/semaphore.h47
-rw-r--r--sysdeps/htl/bits/thread-shared-types.h24
-rw-r--r--sysdeps/htl/bits/types/__pthread_key.h24
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_attr.h45
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_barrier.h38
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_barrierattr.h31
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_cond.h38
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_condattr.h33
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_mutex.h62
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_mutexattr.h40
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_once.h33
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_rwlock.h45
-rw-r--r--sysdeps/htl/bits/types/struct___pthread_rwlockattr.h31
-rw-r--r--sysdeps/htl/flockfile.c31
-rw-r--r--sysdeps/htl/fork.h29
-rw-r--r--sysdeps/htl/ftrylockfile.c35
-rw-r--r--sysdeps/htl/funlockfile.c32
-rw-r--r--sysdeps/htl/libc-lockP.h180
-rw-r--r--sysdeps/htl/old_pt-atfork.c26
-rw-r--r--sysdeps/htl/pt-atfork.c33
-rw-r--r--sysdeps/htl/pt-attr-destroy.c27
-rw-r--r--sysdeps/htl/pt-attr-getdetachstate.c29
-rw-r--r--sysdeps/htl/pt-attr-getguardsize.c27
-rw-r--r--sysdeps/htl/pt-attr-getinheritsched.c29
-rw-r--r--sysdeps/htl/pt-attr-getschedparam.c33
-rw-r--r--sysdeps/htl/pt-attr-getschedpolicy.c29
-rw-r--r--sysdeps/htl/pt-attr-getscope.c29
-rw-r--r--sysdeps/htl/pt-attr-getstack.c30
-rw-r--r--sysdeps/htl/pt-attr-getstackaddr.c27
-rw-r--r--sysdeps/htl/pt-attr-getstacksize.c27
-rw-r--r--sysdeps/htl/pt-attr-init.c28
-rw-r--r--sysdeps/htl/pt-attr-setdetachstate.c38
-rw-r--r--sysdeps/htl/pt-attr-setguardsize.c27
-rw-r--r--sysdeps/htl/pt-attr-setinheritsched.c38
-rw-r--r--sysdeps/htl/pt-attr-setschedparam.c38
-rw-r--r--sysdeps/htl/pt-attr-setschedpolicy.c42
-rw-r--r--sysdeps/htl/pt-attr-setscope.c41
-rw-r--r--sysdeps/htl/pt-attr-setstack.c48
-rw-r--r--sysdeps/htl/pt-attr-setstackaddr.c27
-rw-r--r--sysdeps/htl/pt-attr-setstacksize.c28
-rw-r--r--sysdeps/htl/pt-attr.c39
-rw-r--r--sysdeps/htl/pt-barrier-destroy.c26
-rw-r--r--sysdeps/htl/pt-barrier-init.c51
-rw-r--r--sysdeps/htl/pt-barrier-wait.c68
-rw-r--r--sysdeps/htl/pt-barrier.c24
-rw-r--r--sysdeps/htl/pt-barrierattr-destroy.c26
-rw-r--r--sysdeps/htl/pt-barrierattr-getpshared.c28
-rw-r--r--sysdeps/htl/pt-barrierattr-init.c27
-rw-r--r--sysdeps/htl/pt-barrierattr-setpshared.c37
-rw-r--r--sysdeps/htl/pt-cond-brdcast.c44
-rw-r--r--sysdeps/htl/pt-cond-destroy.c28
-rw-r--r--sysdeps/htl/pt-cond-init.c45
-rw-r--r--sysdeps/htl/pt-cond-signal.c42
-rw-r--r--sysdeps/htl/pt-cond-timedwait.c177
-rw-r--r--sysdeps/htl/pt-cond-wait.c38
-rw-r--r--sysdeps/htl/pt-cond.c27
-rw-r--r--sysdeps/htl/pt-condattr-destroy.c28
-rw-r--r--sysdeps/htl/pt-condattr-getclock.c29
-rw-r--r--sysdeps/htl/pt-condattr-getpshared.c27
-rw-r--r--sysdeps/htl/pt-condattr-init.c29
-rw-r--r--sysdeps/htl/pt-condattr-setclock.c51
-rw-r--r--sysdeps/htl/pt-condattr-setpshared.c37
-rw-r--r--sysdeps/htl/pt-destroy-specific.c77
-rw-r--r--sysdeps/htl/pt-equal.c30
-rw-r--r--sysdeps/htl/pt-getconcurrency.c26
-rw-r--r--sysdeps/htl/pt-getcpuclockid.c35
-rw-r--r--sysdeps/htl/pt-getschedparam.c31
-rw-r--r--sysdeps/htl/pt-getspecific.c38
-rw-r--r--sysdeps/htl/pt-init-specific.c30
-rw-r--r--sysdeps/htl/pt-key-create.c108
-rw-r--r--sysdeps/htl/pt-key-delete.c63
-rw-r--r--sysdeps/htl/pt-key.h76
-rw-r--r--sysdeps/htl/pt-kill.c33
-rw-r--r--sysdeps/htl/pt-mutex-destroy.c38
-rw-r--r--sysdeps/htl/pt-mutex-getprioceiling.c28
-rw-r--r--sysdeps/htl/pt-mutex-init.c48
-rw-r--r--sysdeps/htl/pt-mutex-lock.c36
-rw-r--r--sysdeps/htl/pt-mutex-setprioceiling.c28
-rw-r--r--sysdeps/htl/pt-mutex-timedlock.c195
-rw-r--r--sysdeps/htl/pt-mutex-transfer-np.c66
-rw-r--r--sysdeps/htl/pt-mutex-trylock.c111
-rw-r--r--sysdeps/htl/pt-mutex-unlock.c107
-rw-r--r--sysdeps/htl/pt-mutexattr-destroy.c27
-rw-r--r--sysdeps/htl/pt-mutexattr-getprioceiling.c29
-rw-r--r--sysdeps/htl/pt-mutexattr-getprotocol.c27
-rw-r--r--sysdeps/htl/pt-mutexattr-getpshared.c27
-rw-r--r--sysdeps/htl/pt-mutexattr-gettype.c27
-rw-r--r--sysdeps/htl/pt-mutexattr-init.c28
-rw-r--r--sysdeps/htl/pt-mutexattr-setprioceiling.c28
-rw-r--r--sysdeps/htl/pt-mutexattr-setprotocol.c40
-rw-r--r--sysdeps/htl/pt-mutexattr-setpshared.c37
-rw-r--r--sysdeps/htl/pt-mutexattr-settype.c37
-rw-r--r--sysdeps/htl/pt-mutexattr.c41
-rw-r--r--sysdeps/htl/pt-once.c44
-rw-r--r--sysdeps/htl/pt-rwlock-attr.c24
-rw-r--r--sysdeps/htl/pt-rwlock-destroy.c28
-rw-r--r--sysdeps/htl/pt-rwlock-init.c44
-rw-r--r--sysdeps/htl/pt-rwlock-rdlock.c34
-rw-r--r--sysdeps/htl/pt-rwlock-timedrdlock.c120
-rw-r--r--sysdeps/htl/pt-rwlock-timedwrlock.c103
-rw-r--r--sysdeps/htl/pt-rwlock-tryrdlock.c55
-rw-r--r--sysdeps/htl/pt-rwlock-trywrlock.c45
-rw-r--r--sysdeps/htl/pt-rwlock-unlock.c98
-rw-r--r--sysdeps/htl/pt-rwlock-wrlock.c36
-rw-r--r--sysdeps/htl/pt-rwlockattr-destroy.c26
-rw-r--r--sysdeps/htl/pt-rwlockattr-getpshared.c27
-rw-r--r--sysdeps/htl/pt-rwlockattr-init.c27
-rw-r--r--sysdeps/htl/pt-rwlockattr-setpshared.c37
-rw-r--r--sysdeps/htl/pt-setconcurrency.c33
-rw-r--r--sysdeps/htl/pt-setschedparam.c30
-rw-r--r--sysdeps/htl/pt-setschedprio.c28
-rw-r--r--sysdeps/htl/pt-setspecific.c50
-rw-r--r--sysdeps/htl/pt-spin.c50
-rw-r--r--sysdeps/htl/pt-startup.c24
-rw-r--r--sysdeps/htl/pthread-functions.h140
-rw-r--r--sysdeps/htl/pthread.h883
-rw-r--r--sysdeps/htl/pthreadP.h46
-rw-r--r--sysdeps/htl/raise.c51
-rw-r--r--sysdeps/htl/sem-close.c31
-rw-r--r--sysdeps/htl/sem-destroy.c37
-rw-r--r--sysdeps/htl/sem-getvalue.c32
-rw-r--r--sysdeps/htl/sem-init.c45
-rw-r--r--sysdeps/htl/sem-open.c31
-rw-r--r--sysdeps/htl/sem-post.c61
-rw-r--r--sysdeps/htl/sem-timedwait.c98
-rw-r--r--sysdeps/htl/sem-trywait.c41
-rw-r--r--sysdeps/htl/sem-unlink.c31
-rw-r--r--sysdeps/htl/sem-wait.c31
-rw-r--r--sysdeps/htl/shm-directory.h30
-rw-r--r--sysdeps/htl/timer_routines.h46
-rw-r--r--sysdeps/hurd/htl/pt-kill.c51
-rw-r--r--sysdeps/i386/htl/bits/pthreadtypes-arch.h22
-rw-r--r--sysdeps/i386/htl/machine-sp.h29
-rw-r--r--sysdeps/i386/htl/pt-machdep.h28
-rw-r--r--sysdeps/mach/htl/Implies1
-rw-r--r--sysdeps/mach/htl/bits/spin-lock-inline.h87
-rw-r--r--sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h34
-rw-r--r--sysdeps/mach/htl/pt-block.c38
-rw-r--r--sysdeps/mach/htl/pt-spin.c31
-rw-r--r--sysdeps/mach/htl/pt-stack-alloc.c67
-rw-r--r--sysdeps/mach/htl/pt-thread-alloc.c94
-rw-r--r--sysdeps/mach/htl/pt-thread-start.c53
-rw-r--r--sysdeps/mach/htl/pt-thread-terminate.c82
-rw-r--r--sysdeps/mach/htl/pt-timedblock.c65
-rw-r--r--sysdeps/mach/htl/pt-wakeup.c37
-rw-r--r--sysdeps/mach/hurd/htl/Implies2
-rw-r--r--sysdeps/mach/hurd/htl/bits/pthread-np.h37
-rw-r--r--sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h49
-rw-r--r--sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c27
-rw-r--r--sysdeps/mach/hurd/htl/pt-attr-setstacksize.c27
-rw-r--r--sysdeps/mach/hurd/htl/pt-docancel.c65
-rw-r--r--sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c169
-rw-r--r--sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c40
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-consistent.c48
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-destroy.c38
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-init.c56
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-lock.c81
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c36
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-timedlock.c79
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c77
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-trylock.c85
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-unlock.c92
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex.h90
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c34
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c32
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c32
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c32
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-init.c40
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c34
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c37
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-settype.c36
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr.c1
-rw-r--r--sysdeps/mach/hurd/htl/pt-sigstate-destroy.c26
-rw-r--r--sysdeps/mach/hurd/htl/pt-sigstate-init.c44
-rw-r--r--sysdeps/mach/hurd/htl/pt-sigstate.c70
-rw-r--r--sysdeps/mach/hurd/htl/pt-sysdep.c99
-rw-r--r--sysdeps/mach/hurd/htl/pt-sysdep.h65
-rw-r--r--sysdeps/mach/hurd/i386/Implies1
-rw-r--r--sysdeps/mach/hurd/i386/htl/Implies2
-rw-r--r--sysdeps/mach/hurd/i386/htl/pt-machdep.c82
-rw-r--r--sysdeps/mach/hurd/i386/htl/pt-setup.c110
-rw-r--r--sysdeps/mach/hurd/i386/libpthread.abilist151
250 files changed, 13927 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 55eec1b939..2d813a8eef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2018-04-02  Agustina Arzille  <avarzille@riseup.net>
+            Amos Jeffries  <squid3@treenet.co.nz>
+            David Michael  <fedora.dm0@gmail.com>
+            Marco Gerards  <marco@gnu.org>
+            Marcus Brinkmann  <marcus@gnu.org>
+            Neal H. Walfield  <neal@gnu.org>
+            Pino Toscano  <toscano.pino@tiscali.it>
+            Richard Braun  <rbraun@sceen.net>
+            Roland McGrath  <roland@gnu.org>
+            Samuel Thibault  <samuel.thibault@ens-lyon.org>
+            Thomas DiModica  <ricinwich@yahoo.com>
+            Thomas Schwinge  <tschwinge@gnu.org>
+
+	* htl: New directory.
+	* sysdeps/htl: New directory.
+	* sysdeps/hurd/htl: New directory.
+	* sysdeps/i386/htl: New directory.
+	* sysdeps/mach/htl: New directory.
+	* sysdeps/mach/hurd/htl: New directory.
+	* sysdeps/mach/hurd/i386/htl: New directory.
+	* nscd/Depend, resolv/Depend, rt/Depend: Add htl dependency.
+	* sysdeps/mach/hurd/i386/Implies: Add mach/hurd/i386/htl imply.
+	* sysdeps/mach/hurd/i386/libpthread.abilist: New file.
+
 2018-04-02  Samuel Thibault  <samuel.thibault@ens-lyon.org>
 
 	* sysdeps/pthread/timer_routines.c (__timer_thread_start): Block all
diff --git a/htl/Makefile b/htl/Makefile
new file mode 100644
index 0000000000..3bde5f0800
--- /dev/null
+++ b/htl/Makefile
@@ -0,0 +1,237 @@
+#
+#   Copyright (C) 1994-2018 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU General Public License as
+#   published by the Free Software Foundation; either version 2, or (at
+#   your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+subdir := htl
+
+srcdir = .
+
+MICROKERNEL := mach
+SYSDEPS := lockfile
+
+LCLHDRS :=
+
+libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate	    \
+	pt-attr-getguardsize pt-attr-getinheritsched			    \
+	pt-attr-getschedparam pt-attr-getschedpolicy pt-attr-getscope	    \
+	pt-attr-getstack pt-attr-getstackaddr pt-attr-getstacksize	    \
+	pt-attr-init pt-attr-setdetachstate pt-attr-setguardsize	    \
+	pt-attr-setinheritsched pt-attr-setschedparam			    \
+	pt-attr-setschedpolicy pt-attr-setscope pt-attr-setstack	    \
+	pt-attr-setstackaddr pt-attr-setstacksize			    \
+									    \
+	pt-barrier-destroy pt-barrier-init pt-barrier-wait		    \
+	pt-barrier pt-barrierattr-destroy pt-barrierattr-init		    \
+	pt-barrierattr-getpshared pt-barrierattr-setpshared		    \
+									    \
+	pt-destroy-specific pt-init-specific				    \
+	pt-key-create pt-key-delete					    \
+	pt-getspecific pt-setspecific					    \
+									    \
+	pt-once								    \
+									    \
+	pt-alloc							    \
+	pt-create							    \
+	pt-getattr							    \
+	pt-equal							    \
+	pt-dealloc							    \
+	pt-detach							    \
+	pt-exit								    \
+	pt-initialize							    \
+	pt-join								    \
+	pt-self								    \
+	pt-sigmask							    \
+	pt-spin-inlines							    \
+	pt-cleanup							    \
+	pt-setcancelstate						    \
+	pt-setcanceltype						    \
+	pt-testcancel							    \
+	pt-cancel							    \
+									    \
+	pt-mutexattr							    \
+	pt-mutexattr-destroy pt-mutexattr-init				    \
+	pt-mutexattr-getprioceiling pt-mutexattr-getprotocol		    \
+	pt-mutexattr-getpshared pt-mutexattr-gettype			    \
+	pt-mutexattr-setprioceiling pt-mutexattr-setprotocol		    \
+	pt-mutexattr-setpshared pt-mutexattr-settype			    \
+	pt-mutexattr-getrobust pt-mutexattr-setrobust			    \
+									    \
+	pt-mutex-init pt-mutex-destroy					    \
+	pt-mutex-lock pt-mutex-trylock pt-mutex-timedlock		    \
+	pt-mutex-unlock							    \
+	pt-mutex-transfer-np						    \
+	pt-mutex-getprioceiling pt-mutex-setprioceiling			    \
+	pt-mutex-consistent 						    \
+									    \
+	pt-rwlock-attr							    \
+	pt-rwlockattr-init pt-rwlockattr-destroy			    \
+	pt-rwlockattr-getpshared pt-rwlockattr-setpshared		    \
+									    \
+	pt-rwlock-init pt-rwlock-destroy				    \
+	pt-rwlock-rdlock pt-rwlock-tryrdlock				    \
+	pt-rwlock-trywrlock pt-rwlock-wrlock				    \
+	pt-rwlock-timedrdlock pt-rwlock-timedwrlock			    \
+	pt-rwlock-unlock						    \
+									    \
+	pt-cond								    \
+	pt-condattr-init pt-condattr-destroy				    \
+	pt-condattr-getclock pt-condattr-getpshared			    \
+	pt-condattr-setclock pt-condattr-setpshared			    \
+									    \
+	pt-cond-destroy pt-cond-init					    \
+	pt-cond-brdcast							    \
+	pt-cond-signal							    \
+	pt-cond-wait							    \
+	pt-cond-timedwait						    \
+	pt-hurd-cond-wait						    \
+	pt-hurd-cond-timedwait						    \
+									    \
+	pt-stack-alloc							    \
+	pt-thread-alloc							    \
+	pt-thread-start							    \
+	pt-thread-terminate						    \
+	pt-startup							    \
+									    \
+	pt-getconcurrency pt-setconcurrency				    \
+									    \
+	pt-block							    \
+	pt-timedblock							    \
+	pt-wakeup							    \
+	pt-docancel							    \
+	pt-sysdep							    \
+	pt-setup							    \
+	pt-machdep							    \
+	pt-spin								    \
+									    \
+	pt-sigstate-init						    \
+	pt-sigstate-destroy						    \
+	pt-sigstate							    \
+									    \
+	pt-atfork							    \
+	old_pt-atfork							    \
+	pt-kill								    \
+	pt-getcpuclockid						    \
+									    \
+	pt-getschedparam pt-setschedparam pt-setschedprio		    \
+	pt-yield							    \
+									    \
+	sem-close sem-destroy sem-getvalue sem-init sem-open		    \
+	sem-post sem-timedwait sem-trywait sem-unlink			    \
+	sem-wait							    \
+									    \
+	shm-directory							    \
+									    \
+	cthreads-compat							    \
+	$(SYSDEPS)
+
+libpthread-static-only-routines = pt-atfork
+
+headers :=				\
+              pthread.h				\
+	      semaphore.h			\
+						\
+              bits/pthread.h			\
+              bits/pthread-np.h			\
+              bits/pthreadtypes.h		\
+              bits/pthreadtypes-arch.h		\
+              bits/thread-shared-types.h	\
+              bits/types/struct___pthread_mutex.h	\
+              bits/types/struct___pthread_cond.h	\
+              bits/types/struct___pthread_condattr.h	\
+              bits/types/__pthread_spinlock_t.h	\
+              bits/spin-lock-inline.h		\
+              bits/cancelation.h		\
+              bits/types/struct___pthread_attr.h	\
+              bits/types/struct___pthread_barrierattr.h	\
+              bits/types/struct___pthread_barrier.h	\
+              bits/types/__pthread_key.h		\
+              bits/types/struct___pthread_once.h	\
+              bits/types/struct___pthread_mutexattr.h	\
+              bits/types/struct___pthread_rwlock.h	\
+              bits/types/struct___pthread_rwlockattr.h	\
+	      bits/semaphore.h
+
+distribute :=
+
+routines := forward libc_pthread_init alloca_cutoff
+shared-only-routines = forward
+
+extra-libs := libpthread
+extra-libs-others := $(extra-libs)
+install-lib := libpthread.so
+
+include ../Makeconfig
+
+CFLAGS-lockfile.c = -D_IO_MTSAFE_IO
+
+all: # Make this the default target; it will be defined in Rules.
+
+subdir_install: $(inst_libdir)/libpthread2.a
+
+# XXX: If $(inst_libdir)/libpthread2.a is installed and
+# $(inst_libdir)/libpthread is not, we can have some issues.
+.PHONY: $(inst_libdir)/libpthread.a $(inst_libdir)/libpthread_pic.a
+
+# XXX: These rules are a hack.  But it is better than messing with
+# ../Makeconf at the moment.  Note that the linker scripts
+# $(srcdir)/libpthread.a and $(srcdir)/libpthread_pic.a get overwritten
+# when building in $(srcdir) and not a seperate build directory.
+$(inst_libdir)/libpthread2.a: $(inst_libdir)/libpthread.a
+	mv $< $@
+	$(INSTALL_DATA) $(srcdir)/libpthread.a $<
+
+$(inst_libdir)/libpthread2_pic.a: $(inst_libdir)/libpthread_pic.a
+	mv $< $@
+	$(INSTALL_DATA) $(srcdir)/libpthread_pic.a $<
+
+libc-link.so = $(common-objpfx)libc.so
+
+extra-B-pthread.so = -B$(common-objpfx)htl/
+
+include ../Rules
+
+ifeq (yes,$(build-shared))
+# What we install as libpthread.so for programs to link against is in fact a
+# link script.  It contains references for the various libraries we need.
+# The libpthread.so object is not complete since some functions are only
+# defined in libpthread_nonshared.a.
+# We need to use absolute paths since otherwise local copies (if they exist)
+# of the files are taken by the linker.
+install: $(inst_libdir)/libpthread.so
+
+$(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
+			      $(objpfx)libpthread.so$(libpthread.so-version) \
+			      $(inst_libdir)/$(patsubst %,$(libtype.oS),\
+							$(libprefix)pthread) \
+			      $(+force)
+	(echo '/* GNU ld script';\
+	 echo '   Use the shared library, but some functions are only in';\
+	 echo '   the static library, so try that secondarily.  */';\
+	 cat $<; \
+	 echo 'GROUP ( $(slibdir)/libpthread.so$(libpthread.so-version)' \
+	      '$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)pthread)'\
+	      ')' \
+	) > $@.new
+	mv -f $@.new $@
+
+$(addprefix $(objpfx), \
+  $(filter-out $(tests-static) $(xtests-static) $(tests-reverse) \
+    $(tests-nolibpthread), \
+    $(tests) $(xtests) $(test-srcs))): $(objpfx)libpthread.so \
+				       $(objpfx)libpthread_nonshared.a
+endif
+
+generated += libpthread_nonshared.a
diff --git a/htl/Versions b/htl/Versions
new file mode 100644
index 0000000000..6a63a1b8a1
--- /dev/null
+++ b/htl/Versions
@@ -0,0 +1,156 @@
+libc {
+  GLIBC_2.21 {
+    pthread_attr_destroy; pthread_attr_getdetachstate;
+    pthread_attr_getinheritsched; pthread_attr_getschedparam;
+    pthread_attr_getschedpolicy; pthread_attr_getscope; pthread_attr_init;
+    pthread_attr_setdetachstate; pthread_attr_setinheritsched;
+    pthread_attr_setschedparam; pthread_attr_setschedpolicy;
+    pthread_attr_setscope;
+    pthread_condattr_destroy; pthread_condattr_init;
+    pthread_cond_broadcast; pthread_cond_destroy;
+    pthread_cond_init; pthread_cond_signal; pthread_cond_wait;
+    pthread_cond_timedwait;
+    pthread_equal;
+    pthread_exit; pthread_getschedparam; pthread_setschedparam;
+    pthread_mutex_destroy; pthread_mutex_init;
+    pthread_mutex_lock; pthread_mutex_trylock; pthread_mutex_unlock;
+    pthread_self; pthread_setcancelstate; pthread_setcanceltype;
+    __pthread_get_cleanup_stack;
+  }
+  GLIBC_2.22 {
+    __register_atfork;
+  }
+  GLIBC_PRIVATE {
+    __libc_alloca_cutoff;
+    __libc_pthread_init;
+  }
+}
+
+libpthread {
+  GLIBC_2.2.6 {
+    _IO_flockfile; _IO_ftrylockfile; _IO_funlockfile;
+  }
+  GLIBC_2.12 {
+    __pthread_errorcheck_mutexattr; __pthread_recursive_mutexattr;
+
+    __pthread_get_cleanup_stack;
+
+    __pthread_mutex_transfer_np;
+
+    _pthread_mutex_destroy; _pthread_mutex_init;
+    _pthread_mutex_lock; _pthread_mutex_trylock; _pthread_mutex_unlock;
+    _pthread_rwlock_destroy; _pthread_rwlock_init;
+
+    _cthread_init_routine;
+
+    cthread_detach;
+    cthread_fork;
+    cthread_keycreate;
+    cthread_getspecific;
+    cthread_setspecific;
+    __mutex_lock_solid;
+    __mutex_unlock_solid;
+    _cthreads_flockfile;
+    _cthreads_ftrylockfile;
+    _cthreads_funlockfile;
+
+    flockfile; ftrylockfile; funlockfile;
+
+    pthread_atfork;
+
+    pthread_attr_destroy; pthread_attr_getdetachstate;
+    pthread_attr_getguardsize; pthread_attr_getinheritsched;
+    pthread_attr_getschedparam; pthread_attr_getschedpolicy;
+    pthread_attr_getscope; pthread_attr_getstack; pthread_attr_getstackaddr;
+    pthread_attr_getstacksize; pthread_attr_init; pthread_attr_setdetachstate;
+    pthread_attr_setguardsize; pthread_attr_setinheritsched;
+    pthread_attr_setschedparam; pthread_attr_setschedpolicy;
+    pthread_attr_setscope; pthread_attr_setstack; pthread_attr_setstackaddr;
+    pthread_attr_setstacksize;
+
+    pthread_barrier_destroy; pthread_barrier_init; pthread_barrier_wait;
+    pthread_barrierattr_destroy; pthread_barrierattr_getpshared;
+    pthread_barrierattr_init; pthread_barrierattr_setpshared;
+
+    pthread_cancel;
+
+    pthread_cond_broadcast; pthread_cond_destroy; pthread_cond_init;
+    pthread_cond_signal; pthread_cond_timedwait; pthread_cond_wait;
+
+    pthread_condattr_destroy; pthread_condattr_getclock;
+    pthread_condattr_getpshared; pthread_condattr_init;
+    pthread_condattr_setclock; pthread_condattr_setpshared;
+
+    pthread_create; pthread_detach; pthread_equal; pthread_exit;
+
+    pthread_getattr_np;
+
+    pthread_getconcurrency; pthread_getcpuclockid;
+    pthread_getschedparam; pthread_getspecific;
+
+    pthread_join;
+
+    pthread_key_create; pthread_key_delete;
+    __pthread_key_create;
+
+    pthread_kill;
+    __pthread_kill;
+
+    pthread_mutex_destroy; pthread_mutex_getprioceiling;
+    pthread_mutex_init; pthread_mutex_lock; pthread_mutex_setprioceiling;
+    pthread_mutex_timedlock; pthread_mutex_transfer_np;
+    pthread_mutex_trylock; pthread_mutex_unlock;
+
+    pthread_mutexattr_destroy; pthread_mutexattr_getprioceiling;
+    pthread_mutexattr_getprotocol; pthread_mutexattr_getpshared;
+    pthread_mutexattr_gettype; pthread_mutexattr_init;
+    pthread_mutexattr_setprioceiling; pthread_mutexattr_setprotocol;
+    pthread_mutexattr_setpshared; pthread_mutexattr_settype;
+
+    pthread_once;
+
+    pthread_rwlock_destroy; pthread_rwlock_init; pthread_rwlock_rdlock;
+    pthread_rwlock_timedrdlock; pthread_rwlock_timedwrlock;
+    pthread_rwlock_tryrdlock; pthread_rwlock_trywrlock;
+    pthread_rwlock_unlock; pthread_rwlock_wrlock;
+
+    pthread_rwlockattr_destroy; pthread_rwlockattr_getpshared;
+    pthread_rwlockattr_init; pthread_rwlockattr_setpshared;
+
+    pthread_self;
+    __pthread_self;
+
+    pthread_setcancelstate; pthread_setcanceltype;
+    pthread_setconcurrency; pthread_setschedparam;
+    pthread_setschedprio; pthread_setspecific;
+
+    pthread_sigmask;
+    pthread_testcancel;
+    pthread_yield;
+
+    sem_close; sem_destroy; sem_getvalue; sem_init; sem_open; sem_post;
+    sem_timedwait; sem_trywait; sem_unlink; sem_wait;
+
+    pthread_spin_destroy; pthread_spin_init; pthread_spin_lock;
+    pthread_spin_trylock; pthread_spin_unlock;
+    __pthread_spin_destroy; __pthread_spin_init;
+    __pthread_spin_lock; __pthread_spin_trylock; __pthread_spin_unlock;
+    _pthread_spin_lock;
+  }
+  GLIBC_2.21 {
+    pthread_hurd_cond_wait_np;
+    pthread_hurd_cond_timedwait_np;
+  }
+  GLIBC_PRIVATE {
+    __shm_directory;
+    __pthread_threads;
+
+    __cthread_detach;
+    __cthread_fork;
+    __cthread_keycreate;
+    __cthread_getspecific;
+    __cthread_setspecific;
+    __pthread_getattr_np;
+    __pthread_attr_getstack;
+  }
+}
diff --git a/htl/alloca_cutoff.c b/htl/alloca_cutoff.c
new file mode 100644
index 0000000000..4c183bd7fa
--- /dev/null
+++ b/htl/alloca_cutoff.c
@@ -0,0 +1,26 @@
+/* Allocate a new thread structure.
+   Copyright (C) 2015-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <alloca.h>
+
+int
+__libc_alloca_cutoff (size_t size)
+{
+  return size <= 65536;
+}
+libc_hidden_def (__libc_alloca_cutoff)
diff --git a/htl/configure b/htl/configure
new file mode 100644
index 0000000000..5983490dde
--- /dev/null
+++ b/htl/configure
@@ -0,0 +1,2 @@
+libc_add_on_canonical=libpthread
+libc_add_on_subdirs=.
diff --git a/htl/configure.in b/htl/configure.in
new file mode 100644
index 0000000000..4e140b1197
--- /dev/null
+++ b/htl/configure.in
@@ -0,0 +1,4 @@
+GLIBC_PROVIDES
+
+libc_add_on_canonical=libpthread
+libc_add_on_subdirs=.
diff --git a/htl/cthreads-compat.c b/htl/cthreads-compat.c
new file mode 100644
index 0000000000..042ed64e1d
--- /dev/null
+++ b/htl/cthreads-compat.c
@@ -0,0 +1,101 @@
+/* Compatibility routines for cthreads.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <pthreadP.h>
+
+#define	CTHREAD_KEY_INVALID (__cthread_key_t) -1
+
+void
+__cthread_detach (__cthread_t thread)
+{
+  int err;
+
+  err = pthread_detach ((pthread_t) thread);
+  assert_perror (err);
+}
+weak_alias (__cthread_detach, cthread_detach)
+
+__cthread_t
+__cthread_fork (__cthread_fn_t func, void *arg)
+{
+  pthread_t thread;
+  int err;
+
+  err = pthread_create (&thread, NULL, func, arg);
+  assert_perror (err);
+
+  return (__cthread_t) thread;
+}
+weak_alias (__cthread_fork, cthread_fork)
+
+int
+__cthread_keycreate (__cthread_key_t *key)
+{
+  error_t err;
+
+  err = pthread_key_create (key, 0);
+  if (err)
+    {
+      errno = err;
+      *key = CTHREAD_KEY_INVALID;
+      err = -1;
+    }
+
+  return err;
+}
+weak_alias (__cthread_keycreate, cthread_keycreate)
+
+int
+__cthread_getspecific (__cthread_key_t key, void **val)
+{
+  *val = pthread_getspecific (key);
+  return 0;
+}
+weak_alias (__cthread_getspecific, cthread_getspecific)
+
+int
+__cthread_setspecific (__cthread_key_t key, void *val)
+{
+  error_t err;
+
+  err = pthread_setspecific (key, (const void *) val);
+  if (err)
+    {
+      errno = err;
+      err = -1;
+    }
+
+  return err;
+}
+weak_alias (__cthread_setspecific, cthread_setspecific)
+
+void
+__mutex_lock_solid (void *lock)
+{
+  __pthread_mutex_lock (lock);
+}
+
+void
+__mutex_unlock_solid (void *lock)
+{
+  if (__pthread_spin_trylock (lock) != 0)
+    /* Somebody already got the lock, that one will manage waking up others */
+    return;
+  __pthread_mutex_unlock (lock);
+}
diff --git a/htl/forward.c b/htl/forward.c
new file mode 100644
index 0000000000..cb36ae2cb7
--- /dev/null
+++ b/htl/forward.c
@@ -0,0 +1,283 @@
+/* Libc stubs for pthread functions.  Hurd pthread version.
+   Copyright (C) 2002-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <shlib-compat.h>
+#include <pthread-functions.h>
+#include <libc-lock.h>
+#include <fork.h>
+
+/* Pointers to the libc functions.  */
+struct pthread_functions __libc_pthread_functions attribute_hidden;
+int __libc_pthread_functions_init attribute_hidden;
+
+
+#define FORWARD2(name, rettype, decl, params, defaction) \
+rettype									      \
+name decl								      \
+{									      \
+  if (!__libc_pthread_functions_init)					      \
+    defaction;								      \
+									      \
+  return PTHFCT_CALL (ptr_##name, params);				      \
+}
+
+/* Same as FORWARD2, only without return.  */
+#define FORWARD_NORETURN(name, rettype, decl, params, defaction) \
+rettype									      \
+name decl								      \
+{									      \
+  if (!__libc_pthread_functions_init)					      \
+    defaction;								      \
+									      \
+  PTHFCT_CALL (ptr_##name, params);					      \
+}
+
+#define FORWARD(name, decl, params, defretval) \
+  FORWARD2 (name, int, decl, params, return defretval)
+
+FORWARD (pthread_attr_destroy, (pthread_attr_t *attr), (attr), 0)
+
+FORWARD (pthread_attr_init, (pthread_attr_t *attr), (attr), 0)
+
+FORWARD (pthread_attr_getdetachstate,
+	 (const pthread_attr_t *attr, int *detachstate), (attr, detachstate),
+	 0)
+FORWARD (pthread_attr_setdetachstate, (pthread_attr_t *attr, int detachstate),
+	 (attr, detachstate), 0)
+
+FORWARD (pthread_attr_getinheritsched,
+	 (const pthread_attr_t *attr, int *inherit), (attr, inherit), 0)
+FORWARD (pthread_attr_setinheritsched, (pthread_attr_t *attr, int inherit),
+	 (attr, inherit), 0)
+
+FORWARD (pthread_attr_getschedparam,
+	 (const pthread_attr_t *attr, struct sched_param *param),
+	 (attr, param), 0)
+FORWARD (pthread_attr_setschedparam,
+	 (pthread_attr_t *attr, const struct sched_param *param),
+	 (attr, param), 0)
+
+FORWARD (pthread_attr_getschedpolicy,
+	 (const pthread_attr_t *attr, int *policy), (attr, policy), 0)
+FORWARD (pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy),
+	 (attr, policy), 0)
+
+FORWARD (pthread_attr_getscope,
+	 (const pthread_attr_t *attr, int *scope), (attr, scope), 0)
+FORWARD (pthread_attr_setscope, (pthread_attr_t *attr, int scope),
+	 (attr, scope), 0)
+
+
+FORWARD (pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), 0)
+FORWARD (pthread_condattr_init, (pthread_condattr_t *attr), (attr), 0)
+
+
+FORWARD (pthread_cond_broadcast, (pthread_cond_t *cond), (cond), 0)
+FORWARD (pthread_cond_destroy, (pthread_cond_t *cond), (cond), 0)
+FORWARD (pthread_cond_init,
+	 (pthread_cond_t *cond, const pthread_condattr_t *cond_attr),
+	 (cond, cond_attr), 0)
+FORWARD (pthread_cond_signal, (pthread_cond_t *cond), (cond), 0)
+FORWARD (pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
+	 (cond, mutex), 0)
+FORWARD (pthread_cond_timedwait,
+	 (pthread_cond_t *cond, pthread_mutex_t *mutex,
+	  const struct timespec *abstime), (cond, mutex, abstime), 0)
+
+FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
+	 (thread1, thread2), 1)
+
+
+/* Use an alias to avoid warning, as pthread_exit is declared noreturn.  */
+FORWARD_NORETURN (__pthread_exit, void, (void *retval), (retval),
+		  exit (EXIT_SUCCESS))
+strong_alias (__pthread_exit, pthread_exit);
+
+
+FORWARD (pthread_getschedparam,
+	 (pthread_t target_thread, int *policy, struct sched_param *param),
+	 (target_thread, policy, param), 0)
+FORWARD (pthread_setschedparam,
+	 (pthread_t target_thread, int policy,
+	  const struct sched_param *param), (target_thread, policy, param), 0)
+
+
+FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0)
+
+FORWARD (pthread_mutex_init,
+	 (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
+	 (mutex, mutexattr), 0)
+
+FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
+
+FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
+
+
+FORWARD2 (pthread_self, pthread_t, (void), (), return 0)
+
+
+FORWARD (__pthread_setcancelstate, (int state, int *oldstate),
+	 (state, oldstate), 0)
+strong_alias (__pthread_setcancelstate, pthread_setcancelstate);
+
+FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0)
+
+struct __pthread_cancelation_handler *dummy_list;
+FORWARD2 (__pthread_get_cleanup_stack, struct __pthread_cancelation_handler **,
+	  (void), (), return &dummy_list);
+
+
+/* Fork interaction */
+
+struct atfork
+{
+  void (*prepare) (void);
+  void (*parent) (void);
+  void (*child) (void);
+  void *dso_handle;
+  struct atfork *prev;
+  struct atfork *next;
+};
+
+/* TODO: better locking */
+__libc_lock_define_initialized (static, atfork_lock);
+static struct atfork *fork_handlers, *fork_last_handler;
+
+static void
+atfork_pthread_prepare (void)
+{
+  struct atfork *handlers, *last_handler;
+
+  __libc_lock_lock (atfork_lock);
+  handlers = fork_handlers;
+  last_handler = fork_last_handler;
+  __libc_lock_unlock (atfork_lock);
+
+  if (last_handler == NULL)
+    return;
+
+  while (1)
+    {
+      if (last_handler->prepare != NULL)
+	last_handler->prepare ();
+      if (last_handler == handlers)
+	break;
+      last_handler = last_handler->prev;
+    }
+}
+text_set_element (_hurd_atfork_prepare_hook, atfork_pthread_prepare);
+
+static void
+atfork_pthread_parent (void)
+{
+  struct atfork *handlers;
+
+  __libc_lock_lock (atfork_lock);
+  handlers = fork_handlers;
+  __libc_lock_unlock (atfork_lock);
+
+  while (handlers != NULL)
+    {
+      if (handlers->parent != NULL)
+	handlers->parent ();
+      handlers = handlers->next;
+    }
+}
+text_set_element (_hurd_atfork_parent_hook, atfork_pthread_parent);
+
+static void
+atfork_pthread_child (void)
+{
+  struct atfork *handlers;
+
+  __libc_lock_lock (atfork_lock);
+  handlers = fork_handlers;
+  __libc_lock_unlock (atfork_lock);
+
+  while (handlers != NULL)
+    {
+      if (handlers->child != NULL)
+	handlers->child ();
+      handlers = handlers->next;
+    }
+}
+text_set_element (_hurd_atfork_child_hook, atfork_pthread_child);
+
+int
+__register_atfork (void (*prepare) (void),
+		   void (*parent) (void),
+		   void (*child) (void),
+		   void *dso_handle)
+{
+  struct atfork *new = malloc (sizeof (*new));
+  if (new == NULL)
+    return errno;
+
+  new->prepare = prepare;
+  new->parent = parent;
+  new->child = child;
+  new->dso_handle = dso_handle;
+  new->prev = NULL;
+
+  __libc_lock_lock (atfork_lock);
+  new->next = fork_handlers;
+  if (fork_handlers != NULL)
+    fork_handlers->prev = new;
+  fork_handlers = new;
+  if (fork_last_handler == NULL)
+    fork_last_handler = new;
+  __libc_lock_unlock (atfork_lock);
+
+  return 0;
+}
+libc_hidden_def (__register_atfork)
+
+void
+__unregister_atfork (void *dso_handle)
+{
+  struct atfork **handlers, *prev = NULL, *next;
+  __libc_lock_lock (atfork_lock);
+  handlers = &fork_handlers;
+  while (*handlers != NULL)
+    {
+      if ((*handlers)->dso_handle == dso_handle)
+	{
+	  /* Drop this handler from the list.  */
+	  if (*handlers == fork_last_handler)
+	    {
+	      /* Was last, new last is prev, if any.  */
+	      fork_last_handler = prev;
+	    }
+
+	  next = (*handlers)->next;
+	  if (next != NULL)
+	    next->prev = prev;
+	  *handlers = next;
+	}
+      else
+	{
+	  /* Just proceed to next handler.  */
+	  prev = *handlers;
+	  handlers = &prev->next;
+	}
+    }
+  __libc_lock_unlock (atfork_lock);
+}
diff --git a/htl/libc_pthread_init.c b/htl/libc_pthread_init.c
new file mode 100644
index 0000000000..b6e96827a5
--- /dev/null
+++ b/htl/libc_pthread_init.c
@@ -0,0 +1,33 @@
+/* libc initialization for libpthread.  Hurd pthread version.
+   Copyright (C) 2002-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <pthread-functions.h>
+
+void
+__libc_pthread_init (const struct pthread_functions *functions)
+{
+#ifdef SHARED
+  /* We copy the content of the variable pointed to by the FUNCTIONS
+     parameter to one in libc.so since this means access to the array
+     can be done with one memory access instead of two.  */
+  memcpy (&__libc_pthread_functions, functions,
+	  sizeof (__libc_pthread_functions));
+  __libc_pthread_functions_init = 1;
+#endif
+}
diff --git a/htl/libpthread.a b/htl/libpthread.a
new file mode 100644
index 0000000000..e5bd2cc229
--- /dev/null
+++ b/htl/libpthread.a
@@ -0,0 +1,22 @@
+/* pthread initializer is weak in glibc.  It must be included if glibc
+   is to start threading. */
+EXTERN(_cthread_init_routine)
+
+/* Weak references in glibc that must be filled if glibc is to be
+   thread safe.  */
+EXTERN(cthread_detach)
+EXTERN(cthread_fork)
+EXTERN(cthread_keycreate)
+EXTERN(cthread_getspecific)
+EXTERN(cthread_setspecific)
+EXTERN(__mutex_lock_solid)
+EXTERN(__mutex_unlock_solid)
+/* For libio stream locking.  */
+EXTERN(_cthreads_flockfile)
+EXTERN(_cthreads_funlockfile)
+EXTERN(_cthreads_ftrylockfile)
+/* To get the sigthread stack layout on fork */
+EXTERN(pthread_getattr_np)
+EXTERN(pthread_attr_getstack)
+
+GROUP(-lpthread2 -lrt)
diff --git a/htl/libpthread_pic.a b/htl/libpthread_pic.a
new file mode 100644
index 0000000000..33346b4b39
--- /dev/null
+++ b/htl/libpthread_pic.a
@@ -0,0 +1,22 @@
+/* pthread initializer is weak in glibc.  It must be included if glibc
+   is to start threading. */
+EXTERN(_cthread_init_routine)
+
+/* Weak references in glibc that must be filled if glibc is to be
+   thread safe.  */
+EXTERN(cthread_detach)
+EXTERN(cthread_fork)
+EXTERN(cthread_keycreate)
+EXTERN(cthread_getspecific)
+EXTERN(cthread_setspecific)
+EXTERN(__mutex_lock_solid)
+EXTERN(__mutex_unlock_solid)
+/* For libio stream locking.  */
+EXTERN(_cthreads_flockfile)
+EXTERN(_cthreads_funlockfile)
+EXTERN(_cthreads_ftrylockfile)
+/* To get the sigthread stack layout on fork */
+EXTERN(pthread_getattr_np)
+EXTERN(pthread_attr_getstack)
+
+GROUP(-lpthread2_pic)
diff --git a/htl/lockfile.c b/htl/lockfile.c
new file mode 100644
index 0000000000..9069496185
--- /dev/null
+++ b/htl/lockfile.c
@@ -0,0 +1,60 @@
+/* lockfile - Handle locking and unlocking of streams.  Hurd pthread version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <cthreads.h>
+#include <pthread.h>		/* Must come before <stdio.h>! */
+#include <stdio.h>
+
+void
+_cthreads_flockfile (FILE *fp)
+{
+  _IO_lock_lock (*fp->_lock);
+}
+
+void
+_cthreads_funlockfile (FILE *fp)
+{
+  _IO_lock_unlock (*fp->_lock);
+}
+
+int
+_cthreads_ftrylockfile (FILE *fp)
+{
+  return __libc_lock_trylock_recursive (*fp->_lock);
+}
+
+#undef	_IO_flockfile
+#undef	_IO_funlockfile
+#undef	_IO_ftrylockfile
+#undef	flockfile
+#undef	funlockfile
+#undef	ftrylockfile
+
+void _IO_flockfile (FILE *)
+     __attribute__ ((alias ("_cthreads_flockfile")));
+void _IO_funlockfile (FILE *)
+     __attribute__ ((alias ("_cthreads_funlockfile")));
+int _IO_ftrylockfile (FILE *)
+     __attribute__ ((alias ("_cthreads_ftrylockfile")));
+
+void flockfile (FILE *)
+     __attribute__ ((alias ("_cthreads_flockfile")));
+void funlockfile (FILE *)
+     __attribute__ ((alias ("_cthreads_funlockfile")));
+int ftrylockfile (FILE *)
+     __attribute__ ((alias ("_cthreads_ftrylockfile")));
diff --git a/htl/pt-alloc.c b/htl/pt-alloc.c
new file mode 100644
index 0000000000..adab790d9d
--- /dev/null
+++ b/htl/pt-alloc.c
@@ -0,0 +1,214 @@
+/* Allocate a new thread structure.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <pt-internal.h>
+
+/* This braindamage is necessary because the standard says that some
+   of the threads functions "shall fail" if "No thread could be found
+   corresponding to that specified by the given thread ID."  */
+
+/* Thread ID lookup table.  */
+struct __pthread **__pthread_threads;
+
+/* The size of the thread ID lookup table.  */
+int __pthread_max_threads;
+
+/* The total number of thread IDs currently in use, or on the list of
+   available thread IDs.  */
+int __pthread_num_threads;
+
+/* A lock for the table, and the other variables above.  */
+pthread_rwlock_t __pthread_threads_lock;
+
+/* List of thread structures corresponding to free thread IDs.  */
+struct __pthread *__pthread_free_threads;
+pthread_mutex_t __pthread_free_threads_lock;
+
+static inline error_t
+initialize_pthread (struct __pthread *new)
+{
+  error_t err;
+
+  err = __pthread_init_specific (new);
+  if (err)
+    return err;
+
+  new->nr_refs = 1;
+  new->cancel_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
+  new->cancel_hook = NULL;
+  new->cancel_hook_arg = NULL;
+  new->cancel_state = PTHREAD_CANCEL_ENABLE;
+  new->cancel_type = PTHREAD_CANCEL_DEFERRED;
+  new->cancel_pending = 0;
+
+  new->state_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
+  new->state_cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
+
+  new->cancelation_handlers = 0;
+
+  memset (&new->res_state, '\0', sizeof (new->res_state));
+
+  new->tcb = NULL;
+
+  new->next = 0;
+  new->prevp = 0;
+
+  return 0;
+}
+
+
+/* Allocate a new thread structure and its pthread thread ID (but not
+   a kernel thread).  */
+int
+__pthread_alloc (struct __pthread **pthread)
+{
+  error_t err;
+
+  struct __pthread *new;
+  struct __pthread **threads;
+  struct __pthread **old_threads;
+  int max_threads;
+  int new_max_threads;
+
+  pthread_mutex_lock (&__pthread_free_threads_lock);
+  for (new = __pthread_free_threads; new; new = new->next)
+    {
+      /* There is no need to take NEW->STATE_LOCK: if NEW is on this
+         list, then it is protected by __PTHREAD_FREE_THREADS_LOCK
+         except in __pthread_dealloc where after it is added to the
+         list (with the lock held), it drops the lock and then sets
+         NEW->STATE and immediately stops using NEW.  */
+      if (new->state == PTHREAD_TERMINATED)
+	{
+	  __pthread_dequeue (new);
+	  break;
+	}
+    }
+  pthread_mutex_unlock (&__pthread_free_threads_lock);
+
+  if (new)
+    {
+      if (new->tcb)
+	{
+	  /* Drop old values */
+	  _dl_deallocate_tls (new->tcb, 1);
+	}
+
+      err = initialize_pthread (new);
+      if (!err)
+	*pthread = new;
+      return err;
+    }
+
+  /* Allocate a new thread structure.  */
+  new = malloc (sizeof (struct __pthread));
+  if (new == NULL)
+    return ENOMEM;
+
+  err = initialize_pthread (new);
+  if (err)
+    {
+      free (new);
+      return err;
+    }
+
+retry:
+  __pthread_rwlock_wrlock (&__pthread_threads_lock);
+
+  if (__pthread_num_threads < __pthread_max_threads)
+    {
+      /* We have a free slot.  Use the slot number plus one as the
+         thread ID for the new thread.  */
+      new->thread = 1 + __pthread_num_threads++;
+      __pthread_threads[new->thread - 1] = NULL;
+
+      __pthread_rwlock_unlock (&__pthread_threads_lock);
+
+      *pthread = new;
+      return 0;
+    }
+#ifdef PTHREAD_THREADS_MAX
+  else if (__pthread_num_threads >= PTHREAD_THREADS_MAX)
+    {
+      /* We have reached the limit on the number of threads per process.  */
+      __pthread_rwlock_unlock (&__pthread_threads_lock);
+
+      free (new);
+      return EAGAIN;
+    }
+#endif
+
+  /* We are going to enlarge the threads table.  Save its current
+     size.  We're going to release the lock before doing the necessary
+     memory allocation, since that's a potentially blocking operation.  */
+  max_threads = __pthread_max_threads;
+
+  __pthread_rwlock_unlock (&__pthread_threads_lock);
+
+  /* Allocate a new lookup table that's twice as large.  */
+  new_max_threads
+      = max_threads > 0 ? max_threads * 2 : _POSIX_THREAD_THREADS_MAX;
+  threads = malloc (new_max_threads * sizeof (struct __pthread *));
+  if (threads == NULL)
+    {
+      free (new);
+      return ENOMEM;
+    }
+
+  __pthread_rwlock_wrlock (&__pthread_threads_lock);
+
+  /* Check if nobody else has already enlarged the table.  */
+  if (max_threads != __pthread_max_threads)
+    {
+      /* Yep, they did.  */
+      __pthread_rwlock_unlock (&__pthread_threads_lock);
+
+      /* Free the newly allocated table and try again to allocate a slot.  */
+      free (threads);
+      goto retry;
+    }
+
+  /* Copy over the contents of the old table.  */
+  memcpy (threads, __pthread_threads,
+	  __pthread_max_threads * sizeof (struct __pthread *));
+
+  /* Save the location of the old table.  We want to deallocate its
+     storage after we released the lock.  */
+  old_threads = __pthread_threads;
+
+  /* Replace the table with the new one.  */
+  __pthread_max_threads = new_max_threads;
+  __pthread_threads = threads;
+
+  /* And allocate ourselves one of the newly created slots.  */
+  new->thread = 1 + __pthread_num_threads++;
+  __pthread_threads[new->thread - 1] = NULL;
+
+  __pthread_rwlock_unlock (&__pthread_threads_lock);
+
+  free (old_threads);
+
+  *pthread = new;
+  return 0;
+}
diff --git a/htl/pt-cancel.c b/htl/pt-cancel.c
new file mode 100644
index 0000000000..9f877243b9
--- /dev/null
+++ b/htl/pt-cancel.c
@@ -0,0 +1,62 @@
+/* Cancel a thread.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+int
+pthread_cancel (pthread_t t)
+{
+  int err = 0;
+  struct __pthread *p;
+
+  p = __pthread_getid (t);
+  if (p == NULL)
+    return ESRCH;
+
+  __pthread_mutex_lock (&p->cancel_lock);
+  if (p->cancel_pending)
+    {
+      __pthread_mutex_unlock (&p->cancel_lock);
+      return 0;
+    }
+
+  p->cancel_pending = 1;
+
+  if (p->cancel_state != PTHREAD_CANCEL_ENABLE)
+    {
+      __pthread_mutex_unlock (&p->cancel_lock);
+      return 0;
+    }
+
+  if (p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS)
+    /* CANCEL_LOCK is unlocked by this call.  */
+    err = __pthread_do_cancel (p);
+  else
+    {
+      if (p->cancel_hook != NULL)
+	/* Thread blocking on a cancellation point.  Invoke hook to unblock.
+	   See __pthread_cond_timedwait_internal.  */
+	p->cancel_hook (p->cancel_hook_arg);
+
+      __pthread_mutex_unlock (&p->cancel_lock);
+    }
+
+  return err;
+}
diff --git a/htl/pt-cleanup.c b/htl/pt-cleanup.c
new file mode 100644
index 0000000000..74c86b2bf4
--- /dev/null
+++ b/htl/pt-cleanup.c
@@ -0,0 +1,27 @@
+/* Add a cancelation handler to the stack.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+struct __pthread_cancelation_handler **
+__pthread_get_cleanup_stack (void)
+{
+  return &_pthread_self ()->cancelation_handlers;
+}
diff --git a/htl/pt-create.c b/htl/pt-create.c
new file mode 100644
index 0000000000..f5c06ffdaf
--- /dev/null
+++ b/htl/pt-create.c
@@ -0,0 +1,246 @@
+/* Thread creation.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <resolv.h>
+
+#include <atomic.h>
+#include <hurd/resource.h>
+
+#include <pt-internal.h>
+
+#if IS_IN (libpthread)
+# include <ctype.h>
+#endif
+#ifdef HAVE_USELOCALE
+# include <locale.h>
+#endif
+
+/* The total number of pthreads currently active.  This is defined
+   here since it would be really stupid to have a threads-using
+   program that doesn't call `pthread_create'.  */
+unsigned int __pthread_total;
+
+
+/* The entry-point for new threads.  */
+static void
+entry_point (struct __pthread *self, void *(*start_routine) (void *), void *arg)
+{
+  ___pthread_self = self;
+  __resp = &self->res_state;
+
+#if IS_IN (libpthread)
+  /* Initialize pointers to locale data.  */
+  __ctype_init ();
+#endif
+#ifdef HAVE_USELOCALE
+  /* A fresh thread needs to be bound to the global locale.  */
+  uselocale (LC_GLOBAL_LOCALE);
+#endif
+
+  __pthread_startup ();
+
+  pthread_exit (start_routine (arg));
+}
+
+/* Create a thread with attributes given by ATTR, executing
+   START_ROUTINE with argument ARG.  */
+int
+pthread_create (pthread_t * thread, const pthread_attr_t * attr,
+		void *(*start_routine) (void *), void *arg)
+{
+  int err;
+  struct __pthread *pthread;
+
+  err = __pthread_create_internal (&pthread, attr, start_routine, arg);
+  if (!err)
+    *thread = pthread->thread;
+  else if (err == ENOMEM)
+    err = EAGAIN;
+
+  return err;
+}
+
+/* Internal version of pthread_create.  See comment in
+   pt-internal.h.  */
+int
+__pthread_create_internal (struct __pthread **thread,
+			   const pthread_attr_t * attr,
+			   void *(*start_routine) (void *), void *arg)
+{
+  int err;
+  struct __pthread *pthread;
+  const struct __pthread_attr *setup;
+  sigset_t sigset;
+  size_t stacksize;
+
+  /* Allocate a new thread structure.  */
+  err = __pthread_alloc (&pthread);
+  if (err)
+    goto failed;
+
+  /* Use the default attributes if ATTR is NULL.  */
+  setup = attr ? attr : &__pthread_default_attr;
+
+  stacksize = setup->__stacksize;
+  if (stacksize == 0)
+    {
+      struct rlimit rlim;
+      __getrlimit (RLIMIT_STACK, &rlim);
+      if (rlim.rlim_cur != RLIM_INFINITY)
+	stacksize = rlim.rlim_cur;
+      if (stacksize == 0)
+	stacksize = PTHREAD_STACK_DEFAULT;
+    }
+
+  /* Initialize the thread state.  */
+  pthread->state = (setup->__detachstate == PTHREAD_CREATE_DETACHED
+		    ? PTHREAD_DETACHED : PTHREAD_JOINABLE);
+
+  if (setup->__stackaddr)
+    {
+      pthread->stackaddr = setup->__stackaddr;
+
+      /* If the user supplied a stack, it is not our responsibility to
+         setup a stack guard.  */
+      pthread->guardsize = 0;
+      pthread->stack = 0;
+    }
+  else
+    {
+      /* Allocate a stack.  */
+      err = __pthread_stack_alloc (&pthread->stackaddr,
+				   ((setup->__guardsize + __vm_page_size - 1)
+				    / __vm_page_size) * __vm_page_size
+				   + stacksize);
+      if (err)
+	goto failed_stack_alloc;
+
+      pthread->guardsize = setup->__guardsize;
+      pthread->stack = 1;
+    }
+
+  pthread->stacksize = stacksize;
+
+  /* Allocate the kernel thread and other required resources.  */
+  err = __pthread_thread_alloc (pthread);
+  if (err)
+    goto failed_thread_alloc;
+
+  pthread->tcb = _dl_allocate_tls (NULL);
+  if (pthread->tcb == NULL)
+    {
+      err = ENOMEM;
+      goto failed_thread_tls_alloc;
+    }
+  pthread->tcb->tcb = pthread->tcb;
+
+  /* And initialize the rest of the machine context.  This may include
+     additional machine- and system-specific initializations that
+     prove convenient.  */
+  err = __pthread_setup (pthread, entry_point, start_routine, arg);
+  if (err)
+    goto failed_setup;
+
+  /* Initialize the system-specific signal state for the new
+     thread.  */
+  err = __pthread_sigstate_init (pthread);
+  if (err)
+    goto failed_sigstate;
+
+  /* If the new thread is joinable, add a reference for the caller.  */
+  if (pthread->state == PTHREAD_JOINABLE)
+    pthread->nr_refs++;
+
+  /* Set the new thread's signal mask and set the pending signals to
+     empty.  POSIX says: "The signal mask shall be inherited from the
+     creating thread.  The set of signals pending for the new thread
+     shall be empty."  If the currnet thread is not a pthread then we
+     just inherit the process' sigmask.  */
+  if (__pthread_num_threads == 1)
+    err = sigprocmask (0, 0, &sigset);
+  else
+    err = __pthread_sigstate (_pthread_self (), 0, 0, &sigset, 0);
+  assert_perror (err);
+
+  err = __pthread_sigstate (pthread, SIG_SETMASK, &sigset, 0, 1);
+  assert_perror (err);
+
+  /* Increase the total number of threads.  We do this before actually
+     starting the new thread, since the new thread might immediately
+     call `pthread_exit' which decreases the number of threads and
+     calls `exit' if the number of threads reaches zero.  Increasing
+     the number of threads from within the new thread isn't an option
+     since this thread might return and call `pthread_exit' before the
+     new thread runs.  */
+  atomic_increment (&__pthread_total);
+
+  /* Store a pointer to this thread in the thread ID lookup table.  We
+     could use __thread_setid, however, we only lock for reading as no
+     other thread should be using this entry (we also assume that the
+     store is atomic).  */
+  __pthread_rwlock_rdlock (&__pthread_threads_lock);
+  __pthread_threads[pthread->thread - 1] = pthread;
+  __pthread_rwlock_unlock (&__pthread_threads_lock);
+
+  /* At this point it is possible to guess our pthread ID.  We have to
+     make sure that all functions taking a pthread_t argument can
+     handle the fact that this thread isn't really running yet.  Since
+     the new thread might be passed its ID through pthread_create (to
+     avoid calling pthread_self), read it before starting the thread.  */
+  *thread = pthread;
+
+  /* Schedule the new thread.  */
+  err = __pthread_thread_start (pthread);
+  if (err)
+    goto failed_starting;
+
+
+  return 0;
+
+failed_starting:
+  /* If joinable, a reference was added for the caller.  */
+  if (pthread->state == PTHREAD_JOINABLE)
+    __pthread_dealloc (pthread);
+
+  __pthread_setid (pthread->thread, NULL);
+  atomic_decrement (&__pthread_total);
+failed_sigstate:
+  __pthread_sigstate_destroy (pthread);
+failed_setup:
+  _dl_deallocate_tls (pthread->tcb, 1);
+  pthread->tcb = NULL;
+failed_thread_tls_alloc:
+  __pthread_thread_terminate (pthread);
+
+  /* __pthread_thread_terminate has taken care of deallocating the stack and
+     the thread structure.  */
+  goto failed;
+failed_thread_alloc:
+  if (pthread->stack)
+    __pthread_stack_dealloc (pthread->stackaddr,
+			     ((setup->__guardsize + __vm_page_size - 1)
+			      / __vm_page_size) * __vm_page_size + stacksize);
+failed_stack_alloc:
+  __pthread_dealloc (pthread);
+failed:
+  return err;
+}
diff --git a/htl/pt-dealloc.c b/htl/pt-dealloc.c
new file mode 100644
index 0000000000..15e251ef46
--- /dev/null
+++ b/htl/pt-dealloc.c
@@ -0,0 +1,68 @@
+/* Deallocate a thread structure.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <pt-internal.h>
+
+#include <atomic.h>
+
+/* List of thread structures corresponding to free thread IDs.  */
+extern struct __pthread *__pthread_free_threads;
+extern pthread_mutex_t __pthread_free_threads_lock;
+
+
+/* Deallocate the thread structure for PTHREAD.  */
+void
+__pthread_dealloc (struct __pthread *pthread)
+{
+  assert (pthread->state != PTHREAD_TERMINATED);
+
+  if (!atomic_decrement_and_test (&pthread->nr_refs))
+    return;
+
+  /* Withdraw this thread from the thread ID lookup table.  */
+  __pthread_setid (pthread->thread, NULL);
+
+  /* Mark the thread as terminated.  We broadcast the condition
+     here to prevent pthread_join from waiting for this thread to
+     exit where it was never really started.  Such a call to
+     pthread_join is completely bogus, but unfortunately allowed
+     by the standards.  */
+  __pthread_mutex_lock (&pthread->state_lock);
+  if (pthread->state != PTHREAD_EXITED)
+    __pthread_cond_broadcast (&pthread->state_cond);
+  __pthread_mutex_unlock (&pthread->state_lock);
+
+  /* We do not actually deallocate the thread structure, but add it to
+     a list of re-usable thread structures.  */
+  __pthread_mutex_lock (&__pthread_free_threads_lock);
+  __pthread_enqueue (&__pthread_free_threads, pthread);
+  __pthread_mutex_unlock (&__pthread_free_threads_lock);
+
+  /* Setting PTHREAD->STATE to PTHREAD_TERMINATED makes this TCB
+     available for reuse.  After that point, we can no longer assume
+     that PTHREAD is valid.
+
+     Note that it is safe to not lock this update to PTHREAD->STATE:
+     the only way that it can now be accessed is in __pthread_alloc,
+     which reads this variable.  */
+  pthread->state = PTHREAD_TERMINATED;
+}
diff --git a/htl/pt-detach.c b/htl/pt-detach.c
new file mode 100644
index 0000000000..773ed10722
--- /dev/null
+++ b/htl/pt-detach.c
@@ -0,0 +1,79 @@
+/* Detach a thread.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stddef.h>
+
+#include <pt-internal.h>
+
+/* Indicate that the storage for THREAD can be reclaimed when it
+   terminates.  */
+int
+pthread_detach (pthread_t thread)
+{
+  struct __pthread *pthread;
+  int err = 0;
+
+  /* Lookup the thread structure for THREAD.  */
+  pthread = __pthread_getid (thread);
+  if (pthread == NULL)
+    return ESRCH;
+
+  __pthread_mutex_lock (&pthread->state_lock);
+
+  switch (pthread->state)
+    {
+    case PTHREAD_JOINABLE:
+      /* THREAD still running.  Mark it as detached such that its
+         resources can be reclaimed as soon as the thread exits.  */
+      pthread->state = PTHREAD_DETACHED;
+
+      /* Broadcast the condition.  This will make threads that are
+         waiting to join THREAD continue with hopefully disastrous
+         consequences instead of blocking indefinitely.  */
+      pthread_cond_broadcast (&pthread->state_cond);
+      __pthread_mutex_unlock (&pthread->state_lock);
+
+      __pthread_dealloc (pthread);
+      break;
+
+    case PTHREAD_EXITED:
+      __pthread_mutex_unlock (&pthread->state_lock);
+
+      /* THREAD has already exited.  PTHREAD remained after the thread
+         exited in order to provide the exit status, but it turns out
+         it won't be needed.  */
+      __pthread_dealloc (pthread);
+      break;
+
+    case PTHREAD_TERMINATED:
+      /* Pretend THREAD wasn't there in the first place.  */
+      __pthread_mutex_unlock (&pthread->state_lock);
+      err = ESRCH;
+      break;
+
+    default:
+      /* Thou shalt not detach non-joinable threads!  */
+      __pthread_mutex_unlock (&pthread->state_lock);
+      err = EINVAL;
+      break;
+    }
+
+  return err;
+}
diff --git a/htl/pt-exit.c b/htl/pt-exit.c
new file mode 100644
index 0000000000..8f3d755773
--- /dev/null
+++ b/htl/pt-exit.c
@@ -0,0 +1,111 @@
+/* Thread termination.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <pt-internal.h>
+
+#include <atomic.h>
+
+
+/* Terminate the current thread and make STATUS available to any
+   thread that might join it.  */
+void
+__pthread_exit (void *status)
+{
+  struct __pthread *self = _pthread_self ();
+  struct __pthread_cancelation_handler **handlers;
+  int oldstate;
+
+  /* Run any cancelation handlers.  According to POSIX, the
+     cancellation cleanup handlers should be called with cancellation
+     disabled.  */
+  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
+
+  for (handlers = __pthread_get_cleanup_stack ();
+       *handlers != NULL;
+       *handlers = (*handlers)->__next)
+    (*handlers)->__handler ((*handlers)->__arg);
+
+  pthread_setcancelstate (oldstate, &oldstate);
+
+  /* Decrease the number of threads.  We use an atomic operation to
+     make sure that only the last thread calls `exit'.  */
+  if (atomic_decrement_and_test (&__pthread_total))
+    /* We are the last thread.  */
+    exit (0);
+
+  /* Note that after this point the process can be terminated at any
+     point if another thread calls `pthread_exit' and happens to be
+     the last thread.  */
+
+  __pthread_mutex_lock (&self->state_lock);
+
+  if (self->cancel_state == PTHREAD_CANCEL_ENABLE && self->cancel_pending)
+    status = PTHREAD_CANCELED;
+
+  switch (self->state)
+    {
+    default:
+      assert (!"Consistency error: unexpected self->state");
+      abort ();
+      break;
+
+    case PTHREAD_DETACHED:
+      __pthread_mutex_unlock (&self->state_lock);
+
+      break;
+
+    case PTHREAD_JOINABLE:
+      /* We need to stay around for a while since another thread
+         might want to join us.  */
+      self->state = PTHREAD_EXITED;
+
+      /* We need to remember the exit status.  A thread joining us
+         might ask for it.  */
+      self->status = status;
+
+      /* Broadcast the condition.  This will wake up threads that are
+         waiting to join us.  */
+      __pthread_cond_broadcast (&self->state_cond);
+      __pthread_mutex_unlock (&self->state_lock);
+
+      break;
+    }
+
+  /* Destroy any thread specific data.  */
+  __pthread_destroy_specific (self);
+
+  /* Destroy any signal state.  */
+  __pthread_sigstate_destroy (self);
+
+  /* Self terminating requires TLS, so defer the release of the TCB until
+     the thread structure is reused.  */
+
+  /* Release kernel resources, including the kernel thread and the stack,
+     and drop the self reference.  */
+  __pthread_thread_terminate (self);
+
+  /* NOTREACHED */
+  abort ();
+}
+
+strong_alias (__pthread_exit, pthread_exit);
diff --git a/htl/pt-getattr.c b/htl/pt-getattr.c
new file mode 100644
index 0000000000..b1ec5e0257
--- /dev/null
+++ b/htl/pt-getattr.c
@@ -0,0 +1,51 @@
+/* Thread attributes retrieval.
+   Copyright (C) 2008-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+/* Initialize thread attribute *ATTR with attributes corresponding to the
+   already running thread THREAD.  It shall be called on an uninitialized ATTR
+   and destroyed with pthread_attr_destroy when no longer needed.  */
+int
+__pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
+{
+  struct __pthread *pthread;
+
+  pthread = __pthread_getid (thread);
+  if (pthread == NULL)
+    return ESRCH;
+
+  /* Some attributes (schedparam, inheritsched, contentionscope and schedpolicy)
+     are not supported yet, so fill them with our default values.  */
+  *attr = __pthread_default_attr;
+
+  attr->__stackaddr = pthread->stackaddr +
+      ((pthread->guardsize + __vm_page_size - 1)
+       / __vm_page_size * __vm_page_size);
+  attr->__stacksize = pthread->stacksize;
+  attr->__guardsize = pthread->guardsize;
+  attr->__detachstate = (pthread->state == PTHREAD_DETACHED
+			 ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE);
+
+  return 0;
+}
+weak_alias (__pthread_getattr_np, pthread_getattr_np)
diff --git a/htl/pt-initialize.c b/htl/pt-initialize.c
new file mode 100644
index 0000000000..201810f1ca
--- /dev/null
+++ b/htl/pt-initialize.c
@@ -0,0 +1,83 @@
+/* Initialize pthreads library.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <string.h>
+
+#include <pt-internal.h>
+#include <set-hooks.h>
+
+#include <pthread.h>
+#include <pthread-functions.h>
+
+#if IS_IN (libpthread)
+static const struct pthread_functions pthread_functions = {
+  .ptr_pthread_attr_destroy = __pthread_attr_destroy,
+  .ptr_pthread_attr_init = __pthread_attr_init,
+  .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate,
+  .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate,
+  .ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched,
+  .ptr_pthread_attr_setinheritsched = __pthread_attr_setinheritsched,
+  .ptr_pthread_attr_getschedparam = __pthread_attr_getschedparam,
+  .ptr_pthread_attr_setschedparam = __pthread_attr_setschedparam,
+  .ptr_pthread_attr_getschedpolicy = __pthread_attr_getschedpolicy,
+  .ptr_pthread_attr_setschedpolicy = __pthread_attr_setschedpolicy,
+  .ptr_pthread_attr_getscope = __pthread_attr_getscope,
+  .ptr_pthread_attr_setscope = __pthread_attr_setscope,
+  .ptr_pthread_condattr_destroy = __pthread_condattr_destroy,
+  .ptr_pthread_condattr_init = __pthread_condattr_init,
+  .ptr_pthread_cond_broadcast = __pthread_cond_broadcast,
+  .ptr_pthread_cond_destroy = __pthread_cond_destroy,
+  .ptr_pthread_cond_init = __pthread_cond_init,
+  .ptr_pthread_cond_signal = __pthread_cond_signal,
+  .ptr_pthread_cond_wait = __pthread_cond_wait,
+  .ptr_pthread_cond_timedwait = __pthread_cond_timedwait,
+  .ptr_pthread_equal = __pthread_equal,
+  .ptr___pthread_exit = __pthread_exit,
+  .ptr_pthread_getschedparam = __pthread_getschedparam,
+  .ptr_pthread_setschedparam = __pthread_setschedparam,
+  .ptr_pthread_mutex_destroy = _pthread_mutex_destroy,
+  .ptr_pthread_mutex_init = _pthread_mutex_init,
+  .ptr_pthread_mutex_lock = __pthread_mutex_lock,
+  .ptr_pthread_mutex_trylock = __pthread_mutex_trylock,
+  .ptr_pthread_mutex_unlock = __pthread_mutex_unlock,
+  .ptr_pthread_self = __pthread_self,
+  .ptr___pthread_setcancelstate = __pthread_setcancelstate,
+  .ptr_pthread_setcanceltype = __pthread_setcanceltype,
+  .ptr___pthread_get_cleanup_stack = __pthread_get_cleanup_stack,
+  .ptr_pthread_once = __pthread_once,
+  .ptr_pthread_rwlock_rdlock = __pthread_rwlock_rdlock,
+  .ptr_pthread_rwlock_wrlock = __pthread_rwlock_wrlock,
+  .ptr_pthread_rwlock_unlock = __pthread_rwlock_unlock,
+  .ptr___pthread_key_create = __pthread_key_create,
+  .ptr___pthread_getspecific = __pthread_getspecific,
+  .ptr___pthread_setspecific = __pthread_setspecific,
+  .ptr__IO_flockfile = _cthreads_flockfile,
+  .ptr__IO_funlockfile = _cthreads_funlockfile,
+  .ptr__IO_ftrylockfile = _cthreads_ftrylockfile,
+};
+#endif /* IS_IN (libpthread) */
+
+/* Initialize the pthreads library.  */
+void
+___pthread_init (void)
+{
+#if IS_IN (libpthread)
+  __libc_pthread_init (&pthread_functions);
+#endif
+}
diff --git a/htl/pt-internal.h b/htl/pt-internal.h
new file mode 100644
index 0000000000..22afc1fcce
--- /dev/null
+++ b/htl/pt-internal.h
@@ -0,0 +1,324 @@
+/* Internal defenitions for pthreads library.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PT_INTERNAL_H
+#define _PT_INTERNAL_H	1
+
+#include <pthread.h>
+#include <stddef.h>
+#include <sched.h>
+#include <signal.h>
+#include <assert.h>
+#include <bits/types/res_state.h>
+
+#include <atomic.h>
+
+#include <pt-key.h>
+
+#include <pt-sysdep.h>
+#include <pt-machdep.h>
+
+#if IS_IN (libpthread)
+# include <ldsodefs.h>
+#endif
+
+/* Thread state.  */
+enum pthread_state
+{
+  /* The thread is running and joinable.  */
+  PTHREAD_JOINABLE = 0,
+  /* The thread is running and detached.  */
+  PTHREAD_DETACHED,
+  /* A joinable thread exited and its return code is available.  */
+  PTHREAD_EXITED,
+  /* The thread structure is unallocated and available for reuse.  */
+  PTHREAD_TERMINATED
+};
+
+#ifndef PTHREAD_KEY_MEMBERS
+# define PTHREAD_KEY_MEMBERS
+#endif
+
+#ifndef PTHREAD_SYSDEP_MEMBERS
+# define PTHREAD_SYSDEP_MEMBERS
+#endif
+
+#if !(IS_IN (libpthread))
+/* Type of the TCB.  */
+typedef struct
+{
+  void *tcb;			/* Points to this structure.  */
+  void *dtv;			/* Vector of pointers to TLS data.  */
+  thread_t self;		/* This thread's control port.  */
+} tcbhead_t;
+#endif /* ! IS_IN (libpthread) */
+
+/* This structure describes a POSIX thread.  */
+struct __pthread
+{
+  /* Thread ID.  */
+  pthread_t thread;
+
+  unsigned int nr_refs;		/* Detached threads have a self reference only,
+				   while joinable threads have two references.
+				   These are used to keep the structure valid at
+				   thread destruction.  Detaching/joining a thread
+				   drops a reference.  */
+
+  /* Cancellation.  */
+  pthread_mutex_t cancel_lock;	/* Protect cancel_xxx members.  */
+  void (*cancel_hook) (void *);	/* Called to unblock a thread blocking
+				   in a cancellation point (namely,
+				   __pthread_cond_timedwait_internal).  */
+  void *cancel_hook_arg;
+  int cancel_state;
+  int cancel_type;
+  int cancel_pending;
+  struct __pthread_cancelation_handler *cancelation_handlers;
+
+  /* Thread stack.  */
+  void *stackaddr;
+  size_t stacksize;
+  size_t guardsize;
+  int stack;			/* Nonzero if the stack was allocated.  */
+
+  /* Exit status.  */
+  void *status;
+
+  /* Thread state.  */
+  enum pthread_state state;
+  pthread_mutex_t state_lock;	/* Locks the state.  */
+  pthread_cond_t state_cond;	/* Signalled when the state changes.  */
+
+  /* Resolver state.  */
+  struct __res_state res_state;
+
+  /* Thread context.  */
+  struct pthread_mcontext mcontext;
+
+  PTHREAD_KEY_MEMBERS
+
+  PTHREAD_SYSDEP_MEMBERS
+
+  tcbhead_t *tcb;
+
+  /* Queue links.  Since PREVP is used to determine if a thread has been
+     awaken, it must be protected by the queue lock.  */
+  struct __pthread *next, **prevp;
+};
+
+/* Enqueue an element THREAD on the queue *HEAD.  */
+static inline void
+__pthread_enqueue (struct __pthread **head, struct __pthread *thread)
+{
+  assert (thread->prevp == 0);
+
+  thread->next = *head;
+  thread->prevp = head;
+  if (*head)
+    (*head)->prevp = &thread->next;
+  *head = thread;
+}
+
+/* Dequeue the element THREAD from the queue it is connected to.  */
+static inline void
+__pthread_dequeue (struct __pthread *thread)
+{
+  assert (thread);
+  assert (thread->prevp);
+
+  if (thread->next)
+    thread->next->prevp = thread->prevp;
+  *thread->prevp = thread->next;
+  thread->prevp = 0;
+}
+
+/* Iterate over QUEUE storing each element in ELEMENT.  */
+#define __pthread_queue_iterate(queue, element)				\
+  for (struct __pthread *__pdi_next = (queue);				\
+       ((element) = __pdi_next)						\
+	 && ((__pdi_next = __pdi_next->next),				\
+	     1);							\
+       )
+
+/* Iterate over QUEUE dequeuing each element, storing it in
+   ELEMENT.  */
+#define __pthread_dequeuing_iterate(queue, element)			\
+  for (struct __pthread *__pdi_next = (queue);				\
+       ((element) = __pdi_next)						\
+	 && ((__pdi_next = __pdi_next->next),				\
+	     ((element)->prevp = 0),					\
+	     1);							\
+       )
+
+/* The total number of threads currently active.  */
+extern unsigned int __pthread_total;
+
+/* The total number of thread IDs currently in use, or on the list of
+   available thread IDs.  */
+extern int __pthread_num_threads;
+
+/* Concurrency hint.  */
+extern int __pthread_concurrency;
+
+/* Array of __pthread structures and its lock.  Indexed by the pthread
+   id minus one.  (Why not just use the pthread id?  Because some
+   brain-dead users of the pthread interface incorrectly assume that 0
+   is an invalid pthread id.)  */
+extern struct __pthread **__pthread_threads;
+extern pthread_rwlock_t __pthread_threads_lock;
+
+#define __pthread_getid(thread) \
+  ({ struct __pthread *__t;                                                  \
+     __pthread_rwlock_rdlock (&__pthread_threads_lock);                      \
+     __t = __pthread_threads[thread - 1];                                    \
+     __pthread_rwlock_unlock (&__pthread_threads_lock);                      \
+     __t; })
+
+#define __pthread_setid(thread, pthread) \
+  __pthread_rwlock_wrlock (&__pthread_threads_lock);                         \
+  __pthread_threads[thread - 1] = pthread;                                   \
+  __pthread_rwlock_unlock (&__pthread_threads_lock);
+
+/* Similar to pthread_self, but returns the thread descriptor instead
+   of the thread ID.  */
+#ifndef _pthread_self
+extern struct __pthread *_pthread_self (void);
+#endif
+
+
+/* Initialize the pthreads library.  */
+extern void ___pthread_init (void);
+
+/* Internal version of pthread_create.  Rather than return the new
+   tid, we return the whole __pthread structure in *PTHREAD.  */
+extern int __pthread_create_internal (struct __pthread **__restrict pthread,
+				      const pthread_attr_t *__restrict attr,
+				      void *(*start_routine) (void *),
+				      void *__restrict arg);
+
+/* Allocate a new thread structure and a pthread thread ID (but not a
+   kernel thread or a stack).  THREAD has one reference.  */
+extern int __pthread_alloc (struct __pthread **thread);
+
+/* Deallocate the thread structure.  This is the dual of
+   __pthread_alloc (N.B. it does not call __pthread_stack_dealloc nor
+   __pthread_thread_terminate).  THREAD loses one reference and is
+   released if the reference counter drops to 0.  */
+extern void __pthread_dealloc (struct __pthread *thread);
+
+
+/* Allocate a stack of size STACKSIZE.  The stack base shall be
+   returned in *STACKADDR.  */
+extern int __pthread_stack_alloc (void **stackaddr, size_t stacksize);
+
+/* Deallocate the stack STACKADDR of size STACKSIZE.  */
+extern void __pthread_stack_dealloc (void *stackaddr, size_t stacksize);
+
+
+/* Setup thread THREAD's context.  */
+extern int __pthread_setup (struct __pthread *__restrict thread,
+			    void (*entry_point) (struct __pthread *,
+						 void *(*)(void *),
+						 void *),
+			    void *(*start_routine) (void *),
+			    void *__restrict arg);
+
+
+/* Allocate a kernel thread (and any miscellaneous system dependent
+   resources) for THREAD; it must not be placed on the run queue.  */
+extern int __pthread_thread_alloc (struct __pthread *thread);
+
+/* Start THREAD making it eligible to run.  */
+extern int __pthread_thread_start (struct __pthread *thread);
+
+/* Terminate the kernel thread associated with THREAD, and deallocate its
+   stack as well as any other kernel resource associated with it.
+   In addition, THREAD looses one reference.
+
+   This function can be called by any thread, including the target thread.
+   Since some resources that are destroyed along the kernel thread are
+   stored in thread-local variables, the conditions required for this
+   function to behave correctly are a bit unusual : as long as the target
+   thread hasn't been started, any thread can terminate it, but once it
+   has started, no other thread can terminate it, so that thread-local
+   variables created by that thread are correctly released.  */
+extern void __pthread_thread_terminate (struct __pthread *thread);
+
+
+/* Called by a thread just before it calls the provided start
+   routine.  */
+extern void __pthread_startup (void);
+
+/* Block THREAD.  */
+extern void __pthread_block (struct __pthread *thread);
+
+/* Block THREAD until *ABSTIME is reached.  */
+extern error_t __pthread_timedblock (struct __pthread *__restrict thread,
+				     const struct timespec *__restrict abstime,
+				     clockid_t clock_id);
+
+/* Wakeup THREAD.  */
+extern void __pthread_wakeup (struct __pthread *thread);
+
+
+/* Perform a cancelation.  The CANCEL_LOCK member of the given thread must
+   be locked before calling this function, which must unlock it.  */
+extern int __pthread_do_cancel (struct __pthread *thread);
+
+
+/* Initialize the thread specific data structures.  THREAD must be the
+   calling thread.  */
+extern error_t __pthread_init_specific (struct __pthread *thread);
+
+/* Call the destructors on all of the thread specific data in THREAD.
+   THREAD must be the calling thread.  */
+extern void __pthread_destroy_specific (struct __pthread *thread);
+
+
+/* Initialize newly create thread *THREAD's signal state data
+   structures.  */
+extern error_t __pthread_sigstate_init (struct __pthread *thread);
+
+/* Destroy the signal state data structures associcated with thread
+   *THREAD.  */
+extern void __pthread_sigstate_destroy (struct __pthread *thread);
+
+/* Modify thread *THREAD's signal state.  */
+extern error_t __pthread_sigstate (struct __pthread *__restrict thread, int how,
+				   const sigset_t *__restrict set,
+				   sigset_t *__restrict oset,
+				   int clear_pending);
+
+
+/* Default thread attributes.  */
+extern const struct __pthread_attr __pthread_default_attr;
+
+/* Default barrier attributes.  */
+extern const struct __pthread_barrierattr __pthread_default_barrierattr;
+
+/* Default mutex attributes.  */
+extern const struct __pthread_mutexattr __pthread_default_mutexattr;
+
+/* Default rdlock attributes.  */
+extern const struct __pthread_rwlockattr __pthread_default_rwlockattr;
+
+/* Default condition attributes.  */
+extern const struct __pthread_condattr __pthread_default_condattr;
+
+#endif /* pt-internal.h */
diff --git a/htl/pt-join.c b/htl/pt-join.c
new file mode 100644
index 0000000000..329163d514
--- /dev/null
+++ b/htl/pt-join.c
@@ -0,0 +1,75 @@
+/* Wait for thread termination.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stddef.h>
+
+#include <pt-internal.h>
+
+/* Make calling thread wait for termination of thread THREAD.  Return
+   the exit status of the thread in *STATUS.  */
+int
+pthread_join (pthread_t thread, void **status)
+{
+  struct __pthread *pthread;
+  int err = 0;
+
+  /* Lookup the thread structure for THREAD.  */
+  pthread = __pthread_getid (thread);
+  if (pthread == NULL)
+    return ESRCH;
+
+  __pthread_mutex_lock (&pthread->state_lock);
+  pthread_cleanup_push ((void (*)(void *)) __pthread_mutex_unlock,
+			&pthread->state_lock);
+
+  /* Rely on pthread_cond_wait being a cancellation point to make
+     pthread_join one too.  */
+  while (pthread->state == PTHREAD_JOINABLE)
+    __pthread_cond_wait (&pthread->state_cond, &pthread->state_lock);
+
+  pthread_cleanup_pop (0);
+
+  switch (pthread->state)
+    {
+    case PTHREAD_EXITED:
+      /* THREAD has already exited.  Salvage its exit status.  */
+      if (status != NULL)
+	*status = pthread->status;
+
+      __pthread_mutex_unlock (&pthread->state_lock);
+
+      __pthread_dealloc (pthread);
+      break;
+
+    case PTHREAD_TERMINATED:
+      /* Pretend THREAD wasn't there in the first place.  */
+      __pthread_mutex_unlock (&pthread->state_lock);
+      err = ESRCH;
+      break;
+
+    default:
+      /* Thou shalt not join non-joinable threads!  */
+      __pthread_mutex_unlock (&pthread->state_lock);
+      err = EINVAL;
+      break;
+    }
+
+  return err;
+}
diff --git a/htl/pt-self.c b/htl/pt-self.c
new file mode 100644
index 0000000000..0f932ac1f4
--- /dev/null
+++ b/htl/pt-self.c
@@ -0,0 +1,33 @@
+/* Get calling thread's ID.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+/* Return the thread ID of the calling thread.  */
+pthread_t
+__pthread_self (void)
+{
+  struct __pthread *self = _pthread_self ();
+  assert (self != NULL);
+
+  return self->thread;
+}
+
+strong_alias (__pthread_self, pthread_self);
diff --git a/htl/pt-setcancelstate.c b/htl/pt-setcancelstate.c
new file mode 100644
index 0000000000..de5c6880e6
--- /dev/null
+++ b/htl/pt-setcancelstate.c
@@ -0,0 +1,46 @@
+/* Set the cancel state for the calling thread.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_setcancelstate (int state, int *oldstate)
+{
+  struct __pthread *p = _pthread_self ();
+
+  switch (state)
+    {
+    default:
+      return EINVAL;
+    case PTHREAD_CANCEL_ENABLE:
+    case PTHREAD_CANCEL_DISABLE:
+      break;
+    }
+
+  __pthread_mutex_lock (&p->cancel_lock);
+  if (oldstate != NULL)
+    *oldstate = p->cancel_state;
+  p->cancel_state = state;
+  __pthread_mutex_unlock (&p->cancel_lock);
+
+  return 0;
+}
+
+strong_alias (__pthread_setcancelstate, pthread_setcancelstate);
diff --git a/htl/pt-setcanceltype.c b/htl/pt-setcanceltype.c
new file mode 100644
index 0000000000..0f29a43a9a
--- /dev/null
+++ b/htl/pt-setcanceltype.c
@@ -0,0 +1,46 @@
+/* Set the cancel type for the calling thread.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_setcanceltype (int type, int *oldtype)
+{
+  struct __pthread *p = _pthread_self ();
+
+  switch (type)
+    {
+    default:
+      return EINVAL;
+    case PTHREAD_CANCEL_DEFERRED:
+    case PTHREAD_CANCEL_ASYNCHRONOUS:
+      break;
+    }
+
+  __pthread_mutex_lock (&p->cancel_lock);
+  if (oldtype != NULL)
+    *oldtype = p->cancel_type;
+  p->cancel_type = type;
+  __pthread_mutex_unlock (&p->cancel_lock);
+
+  return 0;
+}
+
+strong_alias (__pthread_setcanceltype, pthread_setcanceltype);
diff --git a/htl/pt-sigmask.c b/htl/pt-sigmask.c
new file mode 100644
index 0000000000..f55c508dfb
--- /dev/null
+++ b/htl/pt-sigmask.c
@@ -0,0 +1,31 @@
+/* Get or set a thread's signal mask.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <signal.h>
+
+#include <pt-internal.h>
+
+int
+pthread_sigmask (int how, const sigset_t *set, sigset_t *oset)
+{
+  struct __pthread *self = _pthread_self ();
+
+  /* Do not clear SELF's pending signals.  */
+  return __pthread_sigstate (self, how, set, oset, 0);
+}
diff --git a/htl/pt-spin-inlines.c b/htl/pt-spin-inlines.c
new file mode 100644
index 0000000000..379723524e
--- /dev/null
+++ b/htl/pt-spin-inlines.c
@@ -0,0 +1,33 @@
+/* Spin locks non-inline functions.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+/* <bits/types/__pthread_spinlock_t.h> declares some extern inline functions.  These
+   functions are declared additionally here for use when inlining is
+   not possible.  */
+
+#define _FORCE_INLINES
+#define __PT_SPIN_INLINE	/* empty */
+
+#include <pthread.h>
+
+/* Weak aliases for the spin lock functions.  */
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy);
+weak_alias (__pthread_spin_init, pthread_spin_init);
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock);
+weak_alias (__pthread_spin_lock, pthread_spin_lock);
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock);
diff --git a/htl/pt-testcancel.c b/htl/pt-testcancel.c
new file mode 100644
index 0000000000..783a6a6001
--- /dev/null
+++ b/htl/pt-testcancel.c
@@ -0,0 +1,35 @@
+/* Add an explicit cancelation point.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+void
+pthread_testcancel (void)
+{
+  struct __pthread *p = _pthread_self ();
+  int cancelled;
+
+  __pthread_mutex_lock (&p->cancel_lock);
+  cancelled = (p->cancel_state == PTHREAD_CANCEL_ENABLE) && p->cancel_pending;
+  __pthread_mutex_unlock (&p->cancel_lock);
+
+  if (cancelled)
+    pthread_exit (PTHREAD_CANCELED);
+}
diff --git a/htl/pt-yield.c b/htl/pt-yield.c
new file mode 100644
index 0000000000..0dee959b87
--- /dev/null
+++ b/htl/pt-yield.c
@@ -0,0 +1,26 @@
+/* Yield the processor to another thread or process.
+   Copyright (C) 2010-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <sched.h>
+
+int
+pthread_yield (void)
+{
+  return sched_yield ();
+}
diff --git a/htl/shlib-versions b/htl/shlib-versions
new file mode 100644
index 0000000000..98e07a6c33
--- /dev/null
+++ b/htl/shlib-versions
@@ -0,0 +1 @@
+libpthread=0.3
diff --git a/htl/tests/Makefile b/htl/tests/Makefile
new file mode 100644
index 0000000000..7177ad181e
--- /dev/null
+++ b/htl/tests/Makefile
@@ -0,0 +1,40 @@
+ifdef INSTALL_ROOT
+INSTALL_ROOT_CPPFLAGS = -isystem $(INSTALL_ROOT)/include
+INSTALL_ROOT_LDFLAGS = -L$(INSTALL_ROOT)/lib -Wl,-rpath,$(INSTALL_ROOT)/lib
+endif
+
+CFLAGS=-Wall -g
+
+LDLIBS = -lpthread
+
+CHECK_SRC := test-1.c test-2.c test-3.c test-6.c test-7.c test-8.c	\
+	test-9.c test-10.c test-11.c test-12.c test-13.c test-14.c	\
+	test-15.c test-16.c test-17.c test-__pthread_destroy_specific-skip.c
+
+CHECK_OBJS := $(addsuffix .o,$(basename $(notdir $(CHECK_SRC))))
+CHECK_PROGS := $(basename $(notdir $(CHECK_SRC))) \
+	$(addsuffix -static, $(basename $(CHECK_SRC)))
+
+%.o: %.c
+	$(CC) $(INSTALL_ROOT_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $< -c -o $@
+
+%: %.o
+	$(CC) $(INSTALL_ROOT_LDFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS)
+
+%-static: %.o
+	$(CC) -static $(INSTALL_ROOT_LDFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS)
+
+check: $(CHECK_OBJS) $(CHECK_PROGS)
+	for i in $(CHECK_PROGS); do		\
+	  echo -n Running $$i...\ ;		\
+	  if ./$$i 2>&1 > $$i.out;		\
+	  then					\
+	    echo Success.;			\
+	  else					\
+	    echo Failure.;			\
+	  fi					\
+	done
+
+clean:
+	rm -f $(CHECK_OBJS) $(CHECK_PROGS) \
+	  $(addsuffix .out,$(basename $(notdir $(CHECK_PROGS))))
\ No newline at end of file
diff --git a/htl/tests/README b/htl/tests/README
new file mode 100644
index 0000000000..230f1b24f0
--- /dev/null
+++ b/htl/tests/README
@@ -0,0 +1,6 @@
+Testing of installed package:
+
+    $ [libpthread]/configure --prefix=[install_root]
+    $ make
+    $ make install
+    $ make -C [libpthread]/tests/ INSTALL_ROOT=[install_root] clean check
diff --git a/htl/tests/test-1.c b/htl/tests/test-1.c
new file mode 100644
index 0000000000..25263ee2f2
--- /dev/null
+++ b/htl/tests/test-1.c
@@ -0,0 +1,68 @@
+/* Test mutexes.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <unistd.h>
+#include <error.h>
+#include <errno.h>
+#include <stdio.h>
+
+#define THREADS 500
+
+void *
+foo (void *arg)
+{
+  pthread_mutex_t *mutex = arg;
+  pthread_mutex_lock (mutex);
+  pthread_mutex_unlock (mutex);
+  return mutex;
+}
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  error_t err;
+  pthread_t tid[THREADS];
+  pthread_mutex_t mutex[THREADS];
+
+  for (i = 0; i < THREADS; i++)
+    {
+      pthread_mutex_init (&mutex[i], 0);
+      pthread_mutex_lock (&mutex[i]);
+      err = pthread_create (&tid[i], 0, foo, &mutex[i]);
+      if (err)
+	error (1, err, "pthread_create");
+      sched_yield ();
+    }
+
+  for (i = THREADS - 1; i >= 0; i--)
+    {
+      void *ret;
+      pthread_mutex_unlock (&mutex[i]);
+      err = pthread_join (tid[i], &ret);
+      if (err)
+	error (1, err, "pthread_join");
+      assert (ret == &mutex[i]);
+    }
+
+  return 0;
+}
diff --git a/htl/tests/test-10.c b/htl/tests/test-10.c
new file mode 100644
index 0000000000..31d3449d04
--- /dev/null
+++ b/htl/tests/test-10.c
@@ -0,0 +1,62 @@
+/* Test error checking mutexes.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  pthread_mutexattr_t mattr;
+  pthread_mutex_t mutex;
+
+  err = pthread_mutexattr_init (&mattr);
+  if (err)
+    error (1, err, "pthread_mutexattr_init");
+
+  err = pthread_mutexattr_settype (&mattr, PTHREAD_MUTEX_ERRORCHECK);
+  if (err)
+    error (1, err, "pthread_mutexattr_settype");
+
+  err = pthread_mutex_init (&mutex, &mattr);
+  if (err)
+    error (1, err, "pthread_mutex_init");
+
+  err = pthread_mutexattr_destroy (&mattr);
+  if (err)
+    error (1, err, "pthread_mutexattr_destroy");
+
+  err = pthread_mutex_lock (&mutex);
+  assert (err == 0);
+
+  err = pthread_mutex_lock (&mutex);
+  assert (err == EDEADLK);
+
+  err = pthread_mutex_unlock (&mutex);
+  assert (err == 0);
+
+  err = pthread_mutex_unlock (&mutex);
+  assert (err == EPERM);
+
+  return 0;
+}
diff --git a/htl/tests/test-11.c b/htl/tests/test-11.c
new file mode 100644
index 0000000000..f8c7a427e8
--- /dev/null
+++ b/htl/tests/test-11.c
@@ -0,0 +1,159 @@
+/* Test rwlocks.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 1
+
+int a;
+int b;
+
+/* Get a read lock and assert that a == b.  */
+void *
+test1 (void *arg)
+{
+  error_t err;
+  pthread_rwlock_t *lock = arg;
+  int i;
+
+  for (i = 0; i < 200; i++)
+    {
+      err = pthread_rwlock_rdlock (lock);
+      assert (err == 0);
+
+      assert (a == b);
+
+      sched_yield ();
+
+      assert (a == b);
+
+      err = pthread_rwlock_unlock (lock);
+      assert (err == 0);
+    }
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  pthread_rwlockattr_t attr;
+  pthread_rwlock_t lock;
+  int pshared;
+
+  int i;
+  pthread_t tid[THREADS];
+  void *ret;
+
+  err = pthread_rwlockattr_init (&attr);
+  if (err)
+    error (1, err, "pthread_rwlockattr_init");
+
+  err = pthread_rwlockattr_getpshared (&attr, &pshared);
+  if (err)
+    error (1, err, "pthread_rwlockattr_getpshared");
+
+  /* Assert the default state as mandated by POSIX.  */
+  assert (pshared == PTHREAD_PROCESS_PRIVATE);
+
+  err = pthread_rwlockattr_setpshared (&attr, pshared);
+  if (err)
+    error (1, err, "pthread_rwlockattr_setpshared");
+
+  err = pthread_rwlock_init (&lock, &attr);
+  if (err)
+    error (1, err, "pthread_rwlock_init");
+
+  err = pthread_rwlockattr_destroy (&attr);
+  if (err)
+    error (1, err, "pthread_rwlockattr_destroy");
+
+  /* Now test the lock.  */
+
+  for (i = 0; i < THREADS; i++)
+    {
+      err = pthread_create (&tid[i], 0, test1, &lock);
+      if (err)
+	error (1, err, "pthread_create");
+    }
+
+  for (i = 0; i < 10; i++)
+    {
+      sched_yield ();
+
+      /* Get a write lock.  */
+      pthread_rwlock_wrlock (&lock);
+      /* Increment a and b giving other threads a chance to run in
+         between.  */
+      sched_yield ();
+      a++;
+      sched_yield ();
+      b++;
+      sched_yield ();
+      /* Unlock.  */
+      pthread_rwlock_unlock (&lock);
+    }
+
+  for (i = 0; i < THREADS; i++)
+    {
+      err = pthread_join (tid[i], &ret);
+      if (err)
+	error (1, err, "pthread_join");
+    }
+
+  /* Read lock it.  */
+  err = pthread_rwlock_tryrdlock (&lock);
+  assert (err == 0);
+
+  /* Try to write lock it.  It should fail with EBUSY.  */
+  err = pthread_rwlock_trywrlock (&lock);
+  assert (err == EBUSY);
+
+  /* Drop the read lock.  */
+  err = pthread_rwlock_unlock (&lock);
+  assert (err == 0);
+
+  /* Get a write lock.  */
+  err = pthread_rwlock_trywrlock (&lock);
+  assert (err == 0);
+
+  /* Fail trying to acquire another write lock.  */
+  err = pthread_rwlock_trywrlock (&lock);
+  assert (err == EBUSY);
+
+  /* Try to get a read lock which should also fail.  */
+  err = pthread_rwlock_tryrdlock (&lock);
+  assert (err == EBUSY);
+
+  /* Unlock it.  */
+  err = pthread_rwlock_unlock (&lock);
+  assert (err == 0);
+
+
+  err = pthread_rwlock_destroy (&lock);
+  if (err)
+    error (1, err, "pthread_rwlock_destroy");
+
+  return 0;
+}
diff --git a/htl/tests/test-12.c b/htl/tests/test-12.c
new file mode 100644
index 0000000000..9676446182
--- /dev/null
+++ b/htl/tests/test-12.c
@@ -0,0 +1,45 @@
+/* Test concurrency level.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  int err;
+
+  i = pthread_getconcurrency ();
+  assert (i == 0);
+
+  err = pthread_setconcurrency (-1);
+  assert (err == EINVAL);
+
+  err = pthread_setconcurrency (4);
+  assert (err == 0);
+
+  i = pthread_getconcurrency ();
+  assert (i == 4);
+
+  return 0;
+}
diff --git a/htl/tests/test-13.c b/htl/tests/test-13.c
new file mode 100644
index 0000000000..d14214981e
--- /dev/null
+++ b/htl/tests/test-13.c
@@ -0,0 +1,82 @@
+/* Test condition attributes and pthread_cond_timedwait.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <sys/time.h>
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  int i;
+  pthread_condattr_t attr;
+  pthread_cond_t cond;
+  struct timespec ts;
+  pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+  struct timeval before, after;
+  int diff;
+
+  err = pthread_condattr_init (&attr);
+  if (err)
+    error (1, err, "pthread_condattr_init");
+
+  err = pthread_condattr_getpshared (&attr, &i);
+  if (err)
+    error (1, err, "pthread_condattr_getpshared");
+  assert (i == PTHREAD_PROCESS_PRIVATE);
+
+  err = pthread_condattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE);
+  assert (err == 0);
+
+  err = pthread_cond_init (&cond, &attr);
+  if (err)
+    error (1, err, "pthread_cond_init");
+
+  err = pthread_condattr_destroy (&attr);
+  if (err)
+    error (1, err, "pthread_condattr_destroy");
+
+  gettimeofday (&before, 0);
+  ts.tv_sec = before.tv_sec + 1;
+  ts.tv_nsec = before.tv_usec * 1000;
+
+  printf ("Starting wait @ %d\n", (int) before.tv_sec);
+
+  pthread_mutex_lock (&m);
+  err = pthread_cond_timedwait (&cond, &m, &ts);
+
+  gettimeofday (&after, 0);
+
+  printf ("End wait @ %d (err = %d)\n", (int) after.tv_sec, err);
+
+  assert (err == ETIMEDOUT);
+
+  diff = after.tv_sec * 1000000 + after.tv_usec
+      - before.tv_sec * 1000000 - before.tv_usec;
+
+  if (diff < 900000 || diff > 1100000)
+    error (1, EGRATUITOUS, "pthread_cond_timedwait waited %d us", diff);
+
+  return 0;
+}
diff --git a/htl/tests/test-14.c b/htl/tests/test-14.c
new file mode 100644
index 0000000000..6e7cef12fe
--- /dev/null
+++ b/htl/tests/test-14.c
@@ -0,0 +1,60 @@
+/* Test pthread_mutex_timedlock.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <sys/time.h>
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  struct timespec ts;
+  pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+  struct timeval before, after;
+  int diff;
+
+  gettimeofday (&before, 0);
+  ts.tv_sec = before.tv_sec + 1;
+  ts.tv_nsec = before.tv_usec * 1000;
+
+  printf ("Starting wait @ %d\n", (int) before.tv_sec);
+
+  pthread_mutex_lock (&m);
+  /* A default mutex shall dead lock if locked twice.  As such we do
+     not need spawn a second thread.  */
+  err = pthread_mutex_timedlock (&m, &ts);
+  assert (err == ETIMEDOUT);
+
+  gettimeofday (&after, 0);
+
+  printf ("End wait @ %d\n", (int) after.tv_sec);
+
+  diff = after.tv_sec * 1000000 + after.tv_usec
+      - before.tv_sec * 1000000 - before.tv_usec;
+
+  if (diff < 900000 || diff > 1100000)
+    error (1, EGRATUITOUS, "pthread_mutex_timedlock waited %d us", diff);
+
+  return 0;
+}
diff --git a/htl/tests/test-15.c b/htl/tests/test-15.c
new file mode 100644
index 0000000000..baf866aae4
--- /dev/null
+++ b/htl/tests/test-15.c
@@ -0,0 +1,102 @@
+/* Test pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#define THREADS 10
+
+pthread_rwlock_t rwlock;
+
+void *
+test (void *arg)
+{
+  error_t err;
+  int foo = (int) arg;
+  struct timespec ts;
+  struct timeval before, after;
+  int diff;
+
+  gettimeofday (&before, 0);
+  ts.tv_sec = before.tv_sec + 1;
+  ts.tv_nsec = before.tv_usec * 1000;
+
+  printf ("Thread %d starting wait @ %d\n", pthread_self (),
+	  (int) before.tv_sec);
+
+  if (foo % 2 == 0)
+    err = pthread_rwlock_timedrdlock (&rwlock, &ts);
+  else
+    err = pthread_rwlock_timedwrlock (&rwlock, &ts);
+
+  assert (err == ETIMEDOUT);
+
+  gettimeofday (&after, 0);
+
+  printf ("Thread %d ending wait @ %d\n", pthread_self (), (int) after.tv_sec);
+
+  diff = after.tv_sec * 1000000 + after.tv_usec
+      - before.tv_sec * 1000000 - before.tv_usec;
+
+  if (diff < 900000 || diff > 1100000)
+    error (1, EGRATUITOUS, "pthread_mutex_timedlock waited %d us", diff);
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  int i;
+  pthread_t tid[THREADS];
+
+  err = pthread_rwlock_init (&rwlock, 0);
+  if (err)
+    error (1, err, "pthread_rwlock_init");
+
+  /* Lock it so all the threads will block.  */
+  err = pthread_rwlock_wrlock (&rwlock);
+  assert (err == 0);
+
+  for (i = 0; i < THREADS; i++)
+    {
+      err = pthread_create (&tid[i], 0, test, (void *) i);
+      if (err)
+	error (1, err, "pthread_create");
+    }
+
+  for (i = 0; i < THREADS; i++)
+    {
+      void *ret;
+
+      err = pthread_join (tid[i], &ret);
+      if (err)
+	error (1, err, "pthread_join");
+
+      assert (ret == 0);
+    }
+
+  return 0;
+}
diff --git a/htl/tests/test-16.c b/htl/tests/test-16.c
new file mode 100644
index 0000000000..519aa84547
--- /dev/null
+++ b/htl/tests/test-16.c
@@ -0,0 +1,87 @@
+/* Test pthread_kill.c.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <hurd/signal.h>
+
+pthread_t testthread;
+
+int i;
+
+void *
+test (void *arg)
+{
+  error_t err;
+
+  printf ("test: %d\n", pthread_self ());
+
+  err = pthread_kill (pthread_self (), SIGINFO);
+  if (err)
+    error (1, err, "pthread_kill");
+
+  /* To avoid using condition variables in a signal handler.  */
+  while (i == 0)
+    sched_yield ();
+
+  return 0;
+}
+
+static void
+handler (int sig)
+{
+  assert (pthread_equal (pthread_self (), testthread));
+  printf ("handler: %d\n", pthread_self ());
+  i = 1;
+}
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  struct sigaction sa;
+  void *ret;
+
+  printf ("main: %d\n", pthread_self ());
+
+  sa.sa_handler = handler;
+  sa.sa_mask = 0;
+  sa.sa_flags = 0;
+
+  err = sigaction (SIGINFO, &sa, 0);
+  if (err)
+    error (1, err, "sigaction");
+
+  err = pthread_create (&testthread, 0, test, 0);
+  if (err)
+    error (1, err, "pthread_create");
+
+  err = pthread_join (testthread, &ret);
+  if (err)
+    error (1, err, "pthread_join");
+
+  assert (ret == 0);
+
+  return 0;
+}
diff --git a/htl/tests/test-17.c b/htl/tests/test-17.c
new file mode 100644
index 0000000000..ffc90b5f74
--- /dev/null
+++ b/htl/tests/test-17.c
@@ -0,0 +1,73 @@
+/* Test that the key reuse inside libpthread does not cause thread
+   specific values to persist.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE 1
+
+#include <pthread.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+void
+work (int iter)
+{
+  error_t err;
+  pthread_key_t key1;
+  pthread_key_t key2;
+  void *value1;
+  void *value2;
+
+  printf ("work/%d: start\n", iter);
+  err = pthread_key_create (&key1, NULL);
+  assert (err == 0);
+  err = pthread_key_create (&key2, NULL);
+  assert (err == 0);
+
+  value1 = pthread_getspecific (key1);
+  value2 = pthread_getspecific (key2);
+  printf ("work/%d: pre-setspecific: %p,%p\n", iter, value1, value2);
+  assert (value1 == NULL);
+  assert (value2 == NULL);
+  err = pthread_setspecific (key1, (void *) (0x100 + iter));
+  assert (err == 0);
+  err = pthread_setspecific (key2, (void *) (0x200 + iter));
+  assert (err == 0);
+
+  value1 = pthread_getspecific (key1);
+  value2 = pthread_getspecific (key2);
+  printf ("work/%d: post-setspecific: %p,%p\n", iter, value1, value2);
+  assert (value1 == (void *) (0x100 + iter));
+  assert (value2 == (void *) (0x200 + iter));
+
+  err = pthread_key_delete (key1);
+  assert (err == 0);
+  err = pthread_key_delete (key2);
+  assert (err == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int i;
+
+  for (i = 0; i < 8; ++i)
+    work (i + 1);
+
+  return 0;
+}
diff --git a/htl/tests/test-2.c b/htl/tests/test-2.c
new file mode 100644
index 0000000000..1194a3427a
--- /dev/null
+++ b/htl/tests/test-2.c
@@ -0,0 +1,56 @@
+/* Test detachability.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+
+void *
+thread (void *arg)
+{
+  while (1)
+    sched_yield ();
+}
+
+int
+main (int argc, char **argv)
+{
+  int err;
+  pthread_t tid;
+  void *ret;
+
+  err = pthread_create (&tid, 0, thread, 0);
+  if (err)
+    error (1, err, "pthread_create");
+
+  err = pthread_detach (tid);
+  if (err)
+    error (1, err, "pthread_detach");
+
+  err = pthread_detach (tid);
+  assert (err == EINVAL);
+
+  err = pthread_join (tid, &ret);
+  assert (err == EINVAL);
+
+  return 0;
+}
diff --git a/htl/tests/test-3.c b/htl/tests/test-3.c
new file mode 100644
index 0000000000..beed473d3c
--- /dev/null
+++ b/htl/tests/test-3.c
@@ -0,0 +1,71 @@
+/* Test the thread attribute get and set methods.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <sched.h>
+#include <assert.h>
+#include <errno.h>
+
+int
+main (int argc, char *argv[])
+{
+  error_t err;
+  pthread_attr_t attr;
+
+  int i;
+  struct sched_param sp;
+  void *p;
+  size_t sz;
+
+  err = pthread_attr_init (&attr);
+  assert_perror (err);
+
+  err = pthread_attr_destroy (&attr);
+  assert_perror (err);
+
+  err = pthread_attr_init (&attr);
+  assert_perror (err);
+
+#define TEST1(foo, rv, v) \
+	err = pthread_attr_get##foo (&attr, rv); \
+	assert_perror (err); \
+	\
+	err = pthread_attr_set##foo (&attr, v); \
+	assert_perror (err);
+
+#define TEST(foo, rv, v) TEST1(foo, rv, v)
+
+  TEST (inheritsched, &i, i);
+  TEST (schedparam, &sp, &sp);
+  TEST (schedpolicy, &i, i);
+  TEST (scope, &i, i);
+  TEST (stackaddr, &p, p);
+  TEST (detachstate, &i, i);
+  TEST (guardsize, &sz, sz);
+  TEST (stacksize, &sz, sz);
+
+  err = pthread_attr_getstack (&attr, &p, &sz);
+  assert_perror (err);
+
+  err = pthread_attr_setstack (&attr, p, sz);
+  assert_perror (err);
+
+  return 0;
+}
diff --git a/htl/tests/test-4.c b/htl/tests/test-4.c
new file mode 100644
index 0000000000..b8c24b78f1
--- /dev/null
+++ b/htl/tests/test-4.c
@@ -0,0 +1,102 @@
+/* Test the stack guard.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+size_t stacksize;
+
+void *
+thr (void *arg)
+{
+  int i;
+  char *foo;
+
+  foo = alloca (3 * stacksize / 4);
+  for (i = 0; i < sizeof foo; i++)
+    foo[i] = -1;
+
+  return (void *) 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  error_t err;
+  pid_t child;
+
+  child = fork ();
+  switch (child)
+    {
+    case -1:
+      error (1, errno, "fork");
+      break;
+
+    case 0:
+      {
+	pthread_attr_t attr;
+	pthread_t tid;
+	void *ret;
+
+	err = pthread_attr_init (&attr);
+	assert_perror (err);
+
+	err = pthread_attr_getstacksize (&attr, &stacksize);
+	assert_perror (err);
+
+	err = pthread_attr_setguardsize (&attr, stacksize / 2);
+	if (err == ENOTSUP)
+	  {
+	    printf ("Stack guard attribute not supported.\n");
+	    return 1;
+	  }
+	assert_perror (err);
+
+	err = pthread_create (&tid, &attr, thr, 0);
+	assert_perror (err);
+
+	err = pthread_attr_destroy (&attr);
+	assert_perror (err);
+
+	err = pthread_join (tid, &ret);
+	/* Should never be successful.  */
+	printf ("Thread did not segfault!?!\n");
+	assert_perror (err);
+	return 0;
+      }
+
+    default:
+      {
+	pid_t pid;
+	int status;
+
+	pid = waitpid (child, &status, 0);
+	printf ("pid = %d; child = %d; status = %d\n", pid, child, status);
+	assert (pid == child);
+	assert (status != 0);
+      }
+    }
+
+  return 0;
+}
diff --git a/htl/tests/test-5.c b/htl/tests/test-5.c
new file mode 100644
index 0000000000..ef9691c869
--- /dev/null
+++ b/htl/tests/test-5.c
@@ -0,0 +1,91 @@
+/* Test signals.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <assert.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+void *
+thr (void *arg)
+{
+  *(int *) 0 = 0;
+  return 0;
+}
+
+int foobar;
+
+int
+main (int argc, char *argv[])
+{
+  error_t err;
+  pid_t child;
+
+  struct rlimit limit;
+
+  limit.rlim_cur = 0;
+  limit.rlim_max = 0;
+
+  err = setrlimit (RLIMIT_CORE, &limit);
+  if (err)
+    error (1, err, "setrlimit");
+
+  child = fork ();
+  switch (child)
+    {
+    case -1:
+      error (1, errno, "fork");
+      break;
+
+    case 0:
+      {
+	pthread_t tid;
+	void *ret;
+
+	err = pthread_create (&tid, 0, thr, 0);
+	if (err)
+	  error (1, err, "pthread_create");
+
+	err = pthread_join (tid, &ret);
+	assert_perror (err);
+
+	/* Should have never returned.  Our parent expects us to fail
+	   thus we succeed and indicate the error.  */
+	return 0;
+      }
+
+    default:
+      {
+	pid_t pid;
+	int status;
+
+	pid = waitpid (child, &status, 0);
+	printf ("pid = %d; child = %d; status = %d\n", pid, child, status);
+	assert (pid == child);
+	assert (status != 0);
+      }
+    }
+
+  return 0;
+}
diff --git a/htl/tests/test-6.c b/htl/tests/test-6.c
new file mode 100644
index 0000000000..e25d419e6f
--- /dev/null
+++ b/htl/tests/test-6.c
@@ -0,0 +1,114 @@
+/* Test barriers.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <error.h>
+#include <assert.h>
+#include <errno.h>
+
+#define THREADS 500
+#define WAITS 3
+
+void *
+dowait (void *arg)
+{
+  pthread_barrier_t *barrier = arg;
+  int ret;
+
+  ret = pthread_barrier_wait (barrier);
+  printf ("%d ", pthread_self ());
+  return (void *) ret;
+}
+
+int
+main (int argc, char **argv)
+{
+  pthread_barrierattr_t attr;
+  pthread_barrier_t barrier;
+
+  int i, j;
+  error_t err;
+  pthread_t tid[THREADS];
+
+  int havesyncs;
+
+  err = pthread_barrierattr_init (&attr);
+  if (err)
+    error (1, err, "pthread_barrierattr_init");
+
+  err = pthread_barrierattr_getpshared (&attr, &i);
+  if (err)
+    error (1, err, "pthread_barrierattr_getpshared");
+  assert (i == PTHREAD_PROCESS_PRIVATE || i == PTHREAD_PROCESS_SHARED);
+
+  err = pthread_barrierattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE);
+  if (err)
+    error (1, err, "pthread_barrierattr_setpshared");
+
+  err = pthread_barrier_init (&barrier, &attr, THREADS + 1);
+  if (err)
+    error (1, err, "pthread_barrier_init");
+
+  for (j = 0; j < WAITS; j++)
+    {
+
+      for (i = 0; i < THREADS; i++)
+	{
+	  err = pthread_create (&tid[i], 0, dowait, &barrier);
+	  if (err)
+	    error (1, err, "pthread_create (%d)", i);
+	}
+
+      printf ("Manager will now call pthread_barrier_wait.\n");
+
+      havesyncs
+	  = pthread_barrier_wait (&barrier) == PTHREAD_BARRIER_SERIAL_THREAD
+	  ? 1 : 0;
+
+      for (i = THREADS - 1; i >= 0; i--)
+	{
+	  void *ret;
+	  err = pthread_join (tid[i], &ret);
+	  if (err)
+	    error (1, err, "pthread_join");
+
+	  switch ((int) ret)
+	    {
+	    case 0:
+	      break;
+
+	    case PTHREAD_BARRIER_SERIAL_THREAD:
+	      havesyncs++;
+	      break;
+
+	    default:
+	      assert (!"Unknown value returned from pthread_barrier_wait.");
+	      break;
+	    }
+	}
+
+      printf ("\n");
+
+      assert (havesyncs == 1);
+    }
+
+  return 0;
+}
diff --git a/htl/tests/test-7.c b/htl/tests/test-7.c
new file mode 100644
index 0000000000..4823de2486
--- /dev/null
+++ b/htl/tests/test-7.c
@@ -0,0 +1,89 @@
+/* Test Thread-Specific Data.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 10
+#define KEYS 400
+
+pthread_key_t key[KEYS];
+
+void *
+thr (void *arg)
+{
+  error_t err;
+  int i;
+
+  for (i = 0; i < KEYS; i++)
+    {
+      printf ("pthread_getspecific(%d).\n", key[i]);
+      assert (pthread_getspecific (key[i]) == NULL);
+      printf ("pthread_setspecific(%d, %d).\n", key[i], pthread_self ());
+      err = pthread_setspecific (key[i], (void *) pthread_self ());
+      printf ("pthread_setspecific(%d, %d) => %d.\n", key[i], pthread_self (),
+	      err);
+      assert_perror (err);
+    }
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  int i;
+  pthread_t tid[THREADS];
+
+  void des (void *val)
+  {
+    assert ((pthread_t) val == pthread_self ());
+  }
+
+  assert (pthread_getspecific ((pthread_key_t) 0) == NULL);
+  assert (pthread_setspecific ((pthread_key_t) 0, (void *) 0x1) == EINVAL);
+
+  for (i = 0; i < KEYS; i++)
+    err = pthread_key_create (&key[i], des);
+
+  for (i = 0; i < THREADS; i++)
+    {
+      err = pthread_create (&tid[i], 0, thr, 0);
+      if (err)
+	error (1, err, "pthread_create (%d)", i);
+    }
+
+  for (i = 0; i < THREADS; i++)
+    {
+      void *ret;
+
+      err = pthread_join (tid[i], &ret);
+      if (err)
+	error (1, err, "pthread_join");
+
+      assert (ret == 0);
+    }
+
+  return 0;
+}
diff --git a/htl/tests/test-8.c b/htl/tests/test-8.c
new file mode 100644
index 0000000000..9cf74a70c4
--- /dev/null
+++ b/htl/tests/test-8.c
@@ -0,0 +1,78 @@
+/* Test pthread_once.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 10
+
+pthread_once_t inc_var_once = PTHREAD_ONCE_INIT;
+int var;
+
+void
+inc_var (void)
+{
+  var++;
+}
+
+void *
+thr (void *arg)
+{
+  int i;
+
+  for (i = 0; i < 500; i++)
+    pthread_once (&inc_var_once, inc_var);
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  int i;
+  pthread_t tid[THREADS];
+
+  for (i = 0; i < THREADS; i++)
+    {
+      err = pthread_create (&tid[i], 0, thr, 0);
+      if (err)
+	error (1, err, "pthread_create (%d)", i);
+    }
+
+  assert (thr (0) == 0);
+
+  for (i = 0; i < THREADS; i++)
+    {
+      void *ret;
+
+      err = pthread_join (tid[i], &ret);
+      if (err)
+	error (1, err, "pthread_join");
+
+      assert (ret == 0);
+    }
+
+  assert (var == 1);
+
+  return 0;
+}
diff --git a/htl/tests/test-9.c b/htl/tests/test-9.c
new file mode 100644
index 0000000000..ad6bc36de5
--- /dev/null
+++ b/htl/tests/test-9.c
@@ -0,0 +1,104 @@
+/* Test recursive mutexes.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 10
+
+int foo;
+
+void *
+thr (void *arg)
+{
+  int i;
+
+  pthread_mutex_lock (arg);
+
+  foo = pthread_self ();
+
+  for (i = 0; i < 500; i++)
+    pthread_mutex_lock (arg);
+  for (i = 0; i < 500; i++)
+    pthread_mutex_unlock (arg);
+
+  assert (foo == pthread_self ());
+
+  pthread_mutex_unlock (arg);
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  error_t err;
+  int i;
+  pthread_t tid[THREADS];
+  pthread_mutexattr_t mattr;
+  pthread_mutex_t mutex;
+
+  err = pthread_mutexattr_init (&mattr);
+  if (err)
+    error (1, err, "pthread_mutexattr_init");
+
+  err = pthread_mutexattr_settype (&mattr, PTHREAD_MUTEX_RECURSIVE);
+  if (err)
+    error (1, err, "pthread_mutexattr_settype");
+
+  err = pthread_mutex_init (&mutex, &mattr);
+  if (err)
+    error (1, err, "pthread_mutex_init");
+
+  err = pthread_mutexattr_destroy (&mattr);
+  if (err)
+    error (1, err, "pthread_mutexattr_destroy");
+
+  pthread_mutex_lock (&mutex);
+  pthread_mutex_lock (&mutex);
+  pthread_mutex_unlock (&mutex);
+  pthread_mutex_unlock (&mutex);
+
+  for (i = 0; i < THREADS; i++)
+    {
+      err = pthread_create (&tid[i], 0, thr, &mutex);
+      if (err)
+	error (1, err, "pthread_create (%d)", i);
+    }
+
+  for (i = 0; i < THREADS; i++)
+    {
+      void *ret;
+
+      err = pthread_join (tid[i], &ret);
+      if (err)
+	error (1, err, "pthread_join");
+
+      assert (ret == 0);
+    }
+
+  err = pthread_mutex_destroy (&mutex);
+  if (err)
+    error (1, err, "pthread_mutex_destroy");
+
+  return 0;
+}
diff --git a/htl/tests/test-__pthread_destroy_specific-skip.c b/htl/tests/test-__pthread_destroy_specific-skip.c
new file mode 100644
index 0000000000..c54ccad88d
--- /dev/null
+++ b/htl/tests/test-__pthread_destroy_specific-skip.c
@@ -0,0 +1,100 @@
+/* Check that __pthread_destroy_specific works correctly if it has to skip
+   unused slots.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+
+#include <error.h>
+#include <pthread.h>
+#include <stdio.h>
+
+
+#define N_k 42
+
+static volatile int v;
+
+static void
+d (void *x)
+{
+  int *i = (int *) x;
+
+  if (v != *i)
+    error (1, 0, "FAILED %d %d", v, *i);
+  v += 2;
+
+  printf ("%s %d\n", __FUNCTION__, *i);
+  fflush (stdout);
+}
+
+static void *
+test (void *x)
+{
+  pthread_key_t k[N_k];
+  static int k_v[N_k];
+
+  int err, i;
+
+  for (i = 0; i < N_k; i += 1)
+    {
+      err = pthread_key_create (&k[i], &d);
+      if (err != 0)
+	error (1, err, "pthread_key_create %d", i);
+    }
+
+  for (i = 0; i < N_k; i += 1)
+    {
+      k_v[i] = i;
+      err = pthread_setspecific (k[i], &k_v[i]);
+      if (err != 0)
+	error (1, err, "pthread_setspecific %d", i);
+    }
+
+  /* Delete every even key.  */
+  for (i = 0; i < N_k; i += 2)
+    {
+      err = pthread_key_delete (k[i]);
+      if (err != 0)
+	error (1, err, "pthread_key_delete %d", i);
+    }
+
+  v = 1;
+  pthread_exit (NULL);
+
+  return NULL;
+}
+
+
+int
+main (void)
+{
+  pthread_t tid;
+  int err;
+
+  err = pthread_create (&tid, 0, test, NULL);
+  if (err != 0)
+    error (1, err, "pthread_create");
+
+  err = pthread_join (tid, NULL);
+  if (err)
+    error (1, err, "pthread_join");
+
+  if (v != N_k + 1)
+    error (1, 0, "FAILED END %d %d", v, N_k + 1);
+
+  return 0;
+}
diff --git a/nscd/Depend b/nscd/Depend
index 6c1aa44e6e..ba64a2d899 100644
--- a/nscd/Depend
+++ b/nscd/Depend
@@ -1 +1,2 @@
 nptl
+htl
diff --git a/resolv/Depend b/resolv/Depend
index 6c1aa44e6e..ba64a2d899 100644
--- a/resolv/Depend
+++ b/resolv/Depend
@@ -1 +1,2 @@
 nptl
+htl
diff --git a/rt/Depend b/rt/Depend
index 6c1aa44e6e..ba64a2d899 100644
--- a/rt/Depend
+++ b/rt/Depend
@@ -1 +1,2 @@
 nptl
+htl
diff --git a/sysdeps/htl/Implies b/sysdeps/htl/Implies
new file mode 100644
index 0000000000..f1b3e8939c
--- /dev/null
+++ b/sysdeps/htl/Implies
@@ -0,0 +1 @@
+pthread
diff --git a/sysdeps/htl/Makeconfig b/sysdeps/htl/Makeconfig
new file mode 100644
index 0000000000..3af4c1de35
--- /dev/null
+++ b/sysdeps/htl/Makeconfig
@@ -0,0 +1,11 @@
+# Makeconfig fragment for Hurd libpthread add-on.
+# This gets included at the end of the main glibc Makeconfig.
+
+have-thread-library = yes
+
+shared-thread-library = $(common-objpfx)htl/libpthread_nonshared.a \
+			$(common-objpfx)htl/libpthread.so
+static-thread-library = $(common-objpfx)htl/libpthread.a
+bounded-thread-library = $(static-thread-library)
+
+rpath-dirs += htl
diff --git a/sysdeps/htl/Makefile b/sysdeps/htl/Makefile
new file mode 100644
index 0000000000..12bb54ebf4
--- /dev/null
+++ b/sysdeps/htl/Makefile
@@ -0,0 +1,7 @@
+ifeq ($(subdir),rt)
+librt-sysdep_routines += timer_routines
+endif
+
+ifeq ($(subdir),posix)
+CFLAGS-confstr.c += -DLIBPTHREAD_VERSION='"HTL $(version)"'
+endif
diff --git a/sysdeps/htl/Subdirs b/sysdeps/htl/Subdirs
new file mode 100644
index 0000000000..5215f33d98
--- /dev/null
+++ b/sysdeps/htl/Subdirs
@@ -0,0 +1 @@
+htl
diff --git a/sysdeps/htl/Versions b/sysdeps/htl/Versions
new file mode 100644
index 0000000000..3a3b1e8b3d
--- /dev/null
+++ b/sysdeps/htl/Versions
@@ -0,0 +1,15 @@
+libc {
+  GLIBC_2.2 {
+    # XXX
+    __vm_deallocate; __mach_port_insert_right; __mach_reply_port;
+    __mig_init; __vm_allocate; __mach_port_allocate;
+
+    # functions used in inline functions or macros
+    __pthread_spin_destroy; __pthread_spin_init; __pthread_spin_lock;
+    _pthread_spin_lock; __pthread_spin_trylock; __pthread_spin_unlock;
+
+    # p*
+    pthread_spin_destroy; pthread_spin_init; pthread_spin_lock;
+    pthread_spin_trylock; pthread_spin_unlock;
+  }
+}
diff --git a/sysdeps/htl/bits/cancelation.h b/sysdeps/htl/bits/cancelation.h
new file mode 100644
index 0000000000..56cf1af154
--- /dev/null
+++ b/sysdeps/htl/bits/cancelation.h
@@ -0,0 +1,50 @@
+/* Cancelation.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_CANCELATION_H
+#define _BITS_CANCELATION_H	1
+
+struct __pthread_cancelation_handler
+{
+  void (*__handler) (void *);
+  void *__arg;
+  struct __pthread_cancelation_handler *__next;
+};
+
+/* Returns the thread local location of the cleanup handler stack.  */
+struct __pthread_cancelation_handler **__pthread_get_cleanup_stack (void);
+
+#define __pthread_cleanup_push(rt, rtarg) \
+	{ \
+	  struct __pthread_cancelation_handler **__handlers \
+	    = __pthread_get_cleanup_stack (); \
+	  struct __pthread_cancelation_handler __handler = \
+	    { \
+	      (rt), \
+	      (rtarg), \
+	      *__handlers \
+	    }; \
+	  *__handlers = &__handler;
+
+#define __pthread_cleanup_pop(execute) \
+	  if (execute) \
+	    __handler.__handler (__handler.__arg); \
+	  *__handlers = __handler.__next; \
+	}
+
+#endif /* _BITS_CANCELATION_H */
diff --git a/sysdeps/htl/bits/pthread-np.h b/sysdeps/htl/bits/pthread-np.h
new file mode 100644
index 0000000000..b9587efba8
--- /dev/null
+++ b/sysdeps/htl/bits/pthread-np.h
@@ -0,0 +1,26 @@
+/* Non-portable functions. Generic version.
+   Copyright (C) 2008-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+/*
+ * Never include this file directly; use <pthread.h> or <cthreads.h> instead.
+ */
+
+#ifndef _BITS_PTHREAD_NP_H
+#define _BITS_PTHREAD_NP_H	1
+
+#endif /* bits/pthread-np.h */
diff --git a/sysdeps/htl/bits/pthread.h b/sysdeps/htl/bits/pthread.h
new file mode 100644
index 0000000000..593ab06ba8
--- /dev/null
+++ b/sysdeps/htl/bits/pthread.h
@@ -0,0 +1,36 @@
+/* Pthread data structures.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_PTHREAD_H
+#define _BITS_PTHREAD_H	1
+
+typedef int __pthread_t;
+
+/* Return true if __T1 and __T2 both name the same thread.  Otherwise,
+   false.  */
+extern int __pthread_equal (__pthread_t __t1, __pthread_t __t2);
+
+#ifdef __USE_EXTERN_INLINES
+__extern_inline int
+__pthread_equal (__pthread_t __t1, __pthread_t __t2)
+{
+  return __t1 == __t2;
+}
+#endif
+
+#endif /* bits/pthread.h */
diff --git a/sysdeps/htl/bits/pthreadtypes.h b/sysdeps/htl/bits/pthreadtypes.h
new file mode 100644
index 0000000000..95ccf513ff
--- /dev/null
+++ b/sysdeps/htl/bits/pthreadtypes.h
@@ -0,0 +1,131 @@
+/* Declaration of common pthread types for all architectures.  Hurd version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#if !defined _BITS_TYPES_H && !defined _PTHREAD_H
+# error "Never include <bits/pthreadtypes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H    1
+
+#include <bits/thread-shared-types.h>
+
+#include <features.h>
+
+#include <bits/types.h>
+
+__BEGIN_DECLS
+#include <bits/pthread.h>
+typedef __pthread_t pthread_t;
+
+/* Possible values for the process shared attribute.  */
+enum __pthread_process_shared
+{
+  __PTHREAD_PROCESS_PRIVATE = 0,
+  __PTHREAD_PROCESS_SHARED
+};
+
+/* Possible values for the inheritsched attribute.  */
+enum __pthread_inheritsched
+{
+  __PTHREAD_EXPLICIT_SCHED = 0,
+  __PTHREAD_INHERIT_SCHED
+};
+
+/* Possible values for the `contentionscope' attribute.  */
+enum __pthread_contentionscope
+{
+  __PTHREAD_SCOPE_SYSTEM = 0,
+  __PTHREAD_SCOPE_PROCESS
+};
+
+/* Possible values for the `detachstate' attribute.  */
+enum __pthread_detachstate
+{
+  __PTHREAD_CREATE_JOINABLE = 0,
+  __PTHREAD_CREATE_DETACHED
+};
+
+#include <bits/types/struct___pthread_attr.h>
+typedef struct __pthread_attr pthread_attr_t;
+
+enum __pthread_mutex_protocol
+{
+  __PTHREAD_PRIO_NONE = 0,
+  __PTHREAD_PRIO_INHERIT,
+  __PTHREAD_PRIO_PROTECT
+};
+
+enum __pthread_mutex_type
+{
+  __PTHREAD_MUTEX_TIMED,
+  __PTHREAD_MUTEX_ERRORCHECK,
+  __PTHREAD_MUTEX_RECURSIVE
+};
+
+enum __pthread_mutex_robustness
+{
+  __PTHREAD_MUTEX_STALLED,
+  __PTHREAD_MUTEX_ROBUST = 0x100
+};
+
+#include <bits/types/struct___pthread_mutexattr.h>
+typedef struct __pthread_mutexattr pthread_mutexattr_t;
+
+#include <bits/types/struct___pthread_mutex.h>
+typedef struct __pthread_mutex pthread_mutex_t;
+
+#include <bits/types/struct___pthread_condattr.h>
+typedef struct __pthread_condattr pthread_condattr_t;
+
+#include <bits/types/struct___pthread_cond.h>
+typedef struct __pthread_cond pthread_cond_t;
+
+#ifdef __USE_XOPEN2K
+# include <bits/types/__pthread_spinlock_t.h>
+typedef __pthread_spinlock_t pthread_spinlock_t;
+#endif /* XPG6.  */
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+
+# include <bits/types/struct___pthread_rwlockattr.h>
+typedef struct __pthread_rwlockattr pthread_rwlockattr_t;
+
+# include <bits/types/struct___pthread_rwlock.h>
+typedef struct __pthread_rwlock pthread_rwlock_t;
+
+#endif /* __USE_UNIX98 || __USE_XOPEN2K */
+
+#ifdef __USE_XOPEN2K
+
+# include <bits/types/struct___pthread_barrierattr.h>
+typedef struct __pthread_barrierattr pthread_barrierattr_t;
+
+# include <bits/types/struct___pthread_barrier.h>
+typedef struct __pthread_barrier pthread_barrier_t;
+
+#endif /* __USE_XOPEN2K */
+
+#include <bits/types/__pthread_key.h>
+typedef __pthread_key pthread_key_t;
+
+#include <bits/types/struct___pthread_once.h>
+typedef struct __pthread_once pthread_once_t;
+
+__END_DECLS
+#endif /* bits/pthreadtypes.h */
diff --git a/sysdeps/htl/bits/semaphore.h b/sysdeps/htl/bits/semaphore.h
new file mode 100644
index 0000000000..b1789be55f
--- /dev/null
+++ b/sysdeps/htl/bits/semaphore.h
@@ -0,0 +1,47 @@
+/* Semaphore type.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_SEMAPHORE_H
+#define _BITS_SEMAPHORE_H	1
+
+#ifndef _SEMAPHORE_H
+# error Never include <bits/semaphore.h> directly.
+#endif
+
+#include <bits/types/__pthread_spinlock_t.h>
+#include <bits/pthread.h>
+
+/* User visible part of a semaphore.  */
+struct __semaphore
+{
+  __pthread_spinlock_t __lock;
+  struct __pthread *__queue;
+  int __pshared;
+  int __value;
+  void *__data;
+};
+
+typedef struct __semaphore sem_t;
+
+#define SEM_FAILED ((void *) 0)
+
+/* Initializer for a semaphore.  */
+#define __SEMAPHORE_INITIALIZER(pshared, value) \
+  { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, (pshared), (value), NULL }
+
+#endif /* bits/semaphore.h */
diff --git a/sysdeps/htl/bits/thread-shared-types.h b/sysdeps/htl/bits/thread-shared-types.h
new file mode 100644
index 0000000000..054cbf201f
--- /dev/null
+++ b/sysdeps/htl/bits/thread-shared-types.h
@@ -0,0 +1,24 @@
+/* Common threading primitives definitions for both POSIX and C11.
+   Copyright (C) 2017-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _THREAD_SHARED_TYPES_H
+#define _THREAD_SHARED_TYPES_H 1
+
+#include <bits/pthreadtypes-arch.h>
+
+#endif /* _THREAD_SHARED_TYPES_H  */
diff --git a/sysdeps/htl/bits/types/__pthread_key.h b/sysdeps/htl/bits/types/__pthread_key.h
new file mode 100644
index 0000000000..c558f478b0
--- /dev/null
+++ b/sysdeps/htl/bits/types/__pthread_key.h
@@ -0,0 +1,24 @@
+/* Thread specific data.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES___PTHREAD_KEY_H
+#define _BITS_TYPES___PTHREAD_KEY_H	1
+
+typedef int __pthread_key;
+
+#endif /* bits/types/__pthread_key.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_attr.h b/sysdeps/htl/bits/types/struct___pthread_attr.h
new file mode 100644
index 0000000000..44f9543a84
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_attr.h
@@ -0,0 +1,45 @@
+/* Thread attribute type.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_ATTR
+#define _BITS_TYPES_STRUCT___PTHREAD_ATTR	1
+
+#include <sched.h>
+
+#define __need_size_t
+#include <stddef.h>
+
+enum __pthread_detachstate;
+enum __pthread_inheritsched;
+enum __pthread_contentionscope;
+
+/* This structure describes the attributes of a POSIX thread.  Note
+   that not all of them are supported on all systems.  */
+struct __pthread_attr
+{
+  struct sched_param __schedparam;
+  void *__stackaddr;
+  size_t __stacksize;
+  size_t __guardsize;
+  enum __pthread_detachstate __detachstate;
+  enum __pthread_inheritsched __inheritsched;
+  enum __pthread_contentionscope __contentionscope;
+  int __schedpolicy;
+};
+
+#endif /* bits/types/struct___pthread_attr.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_barrier.h b/sysdeps/htl/bits/types/struct___pthread_barrier.h
new file mode 100644
index 0000000000..27a6b84212
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_barrier.h
@@ -0,0 +1,38 @@
+/* Thread barrier attribute type.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_BARRIER_H
+#define _BITS_TYPES_STRUCT___PTHREAD_BARRIER_H	1
+
+#include <bits/types/__pthread_spinlock_t.h>
+
+/* This structure describes the attributes of a POSIX barrier.  */
+struct __pthread_barrier
+{
+  __pthread_spinlock_t __lock;
+  struct __pthread *__queue;	/* List of waiters.  */
+  unsigned __pending;		/* Number of that still need to wait on
+				   barrier.  */
+  unsigned __count;		/* Number of threads that must wait before
+				   barrier is passed.  */
+  struct __pthread_barrierattr *__attr;
+  void *__data;
+};
+
+
+#endif /* bits/types/struct___pthread_barrier.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_barrierattr.h b/sysdeps/htl/bits/types/struct___pthread_barrierattr.h
new file mode 100644
index 0000000000..5ac2c34d88
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_barrierattr.h
@@ -0,0 +1,31 @@
+/* Thread barrier attribute type.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_BARRIERATTR_H
+#define _BITS_TYPES_STRUCT___PTHREAD_BARRIERATTR_H	1
+
+enum __pthread_process_shared;
+
+/* This structure describes the attributes of a POSIX thread barrier.
+   Note that not all of them are supported on all systems.  */
+struct __pthread_barrierattr
+{
+  enum __pthread_process_shared __pshared;
+};
+
+#endif /* bits/types/struct___pthread_barrierattr.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_cond.h b/sysdeps/htl/bits/types/struct___pthread_cond.h
new file mode 100644
index 0000000000..d84cde0887
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_cond.h
@@ -0,0 +1,38 @@
+/* Condition type.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_COND_H
+#define _BITS_TYPES_STRUCT___PTHREAD_COND_H	1
+
+#include <bits/types/__pthread_spinlock_t.h>
+
+/* User visible part of a condition variable.  */
+struct __pthread_cond
+{
+  __pthread_spinlock_t __lock;
+  struct __pthread *__queue;
+  struct __pthread_condattr *__attr;
+  struct __pthread_condimpl *__impl;
+  void *__data;
+};
+
+/* Initializer for a condition variable.  */
+#define __PTHREAD_COND_INITIALIZER \
+  { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL }
+
+#endif /* bits/types/struct___pthread_cond.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_condattr.h b/sysdeps/htl/bits/types/struct___pthread_condattr.h
new file mode 100644
index 0000000000..4d5450168c
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_condattr.h
@@ -0,0 +1,33 @@
+/* Condition attribute type.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_CONDATTR
+#define _BITS_TYPES_STRUCT___PTHREAD_CONDATTR	1
+
+#include <bits/types.h>
+
+enum __pthread_process_shared;
+
+/* User visible part of a condition attribute variable.  */
+struct __pthread_condattr
+{
+  enum __pthread_process_shared __pshared;
+  __clockid_t __clock;
+};
+
+#endif /* bits/types/struct___pthread_condattr.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_mutex.h b/sysdeps/htl/bits/types/struct___pthread_mutex.h
new file mode 100644
index 0000000000..0a89ded73c
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_mutex.h
@@ -0,0 +1,62 @@
+/* Mutex type.  Generic version.
+
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H
+#define _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H	1
+
+#include <bits/types/__pthread_spinlock_t.h>
+#include <bits/types/struct___pthread_mutexattr.h>
+
+/* User visible part of a mutex.  */
+struct __pthread_mutex
+{
+  __pthread_spinlock_t __held;
+  __pthread_spinlock_t __lock;
+  /* In cthreads, mutex_init does not initialized thre third
+     pointer, as such, we cannot rely on its value for anything.  */
+  char *__cthreadscompat1;
+  struct __pthread *__queue;
+  struct __pthread_mutexattr *__attr;
+  void *__data;
+  /*  Up to this point, we are completely compatible with cthreads
+     and what libc expects.  */
+  void *__owner;
+  unsigned __locks;
+  /* If NULL then the default attributes apply.  */
+};
+
+/* Initializer for a mutex.  N.B.  this also happens to be compatible
+   with the cthread mutex initializer.  */
+#define __PTHREAD_MUTEX_INITIALIZER \
+    { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 }
+
+#define __PTHREAD_ERRORCHECK_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_ERRORCHECK + 1))
+
+#define __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER \
+    { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0,	\
+	__PTHREAD_ERRORCHECK_MUTEXATTR, 0, 0, 0 }
+
+#define __PTHREAD_RECURSIVE_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_RECURSIVE + 1))
+
+#define __PTHREAD_RECURSIVE_MUTEX_INITIALIZER \
+    { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0,	\
+	__PTHREAD_RECURSIVE_MUTEXATTR, 0, 0, 0 }
+
+#endif /* bits/types/struct___pthread_mutex.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_mutexattr.h b/sysdeps/htl/bits/types/struct___pthread_mutexattr.h
new file mode 100644
index 0000000000..c77458ac21
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_mutexattr.h
@@ -0,0 +1,40 @@
+/* Mutex attribute type.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_MUTEXATTR_H
+#define _BITS_TYPES_STRUCT___PTHREAD_MUTEXATTR_H	1
+
+enum __pthread_mutex_protocol;
+enum __pthread_process_shared;
+enum __pthread_mutex_type;
+
+/* This structure describes the attributes of a POSIX mutex
+   attribute.  */
+struct __pthread_mutexattr
+{
+  int __prioceiling;
+  enum __pthread_mutex_protocol __protocol;
+  enum __pthread_process_shared __pshared;
+  enum __pthread_mutex_type __mutex_type;
+};
+
+/* Attributes for a recursive mutex.  */
+extern const struct __pthread_mutexattr __pthread_errorcheck_mutexattr;
+extern const struct __pthread_mutexattr __pthread_recursive_mutexattr;
+
+#endif /* bits/types/struct___pthread_mutexattr.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_once.h b/sysdeps/htl/bits/types/struct___pthread_once.h
new file mode 100644
index 0000000000..5b99658938
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_once.h
@@ -0,0 +1,33 @@
+/* Dynamic package initialization data structures.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_ONCE_H
+#define _BITS_TYPES_STRUCT___PTHREAD_ONCE_H	1
+
+#include <bits/types/__pthread_spinlock_t.h>
+
+struct __pthread_once
+{
+  int __run;
+  __pthread_spinlock_t __lock;
+};
+
+#define __PTHREAD_ONCE_INIT \
+	(struct __pthread_once) { 0, __PTHREAD_SPIN_LOCK_INITIALIZER }
+
+#endif /* bits/types/struct___pthread_once.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_rwlock.h b/sysdeps/htl/bits/types/struct___pthread_rwlock.h
new file mode 100644
index 0000000000..cf47671240
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_rwlock.h
@@ -0,0 +1,45 @@
+/* rwlock type.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_RWLOCK_H
+#define _BITS_TYPES_STRUCT___PTHREAD_RWLOCK_H
+
+#include <bits/types/__pthread_spinlock_t.h>
+
+/* User visible part of a rwlock.  If __held is not held and readers
+   is 0, then the lock is unlocked.  If __held is held and readers is
+   0, then the lock is held by a writer.  If __held is held and
+   readers is greater than 0, then the lock is held by READERS
+   readers.  */
+struct __pthread_rwlock
+{
+  __pthread_spinlock_t __held;
+  __pthread_spinlock_t __lock;
+  int __readers;
+  struct __pthread *__readerqueue;
+  struct __pthread *__writerqueue;
+  struct __pthread_rwlockattr *__attr;
+  void *__data;
+};
+
+/* Initializer for a rwlock.  */
+#define __PTHREAD_RWLOCK_INITIALIZER \
+    { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 }
+
+
+#endif /* bits/types/struct___pthread_rwlock.h */
diff --git a/sysdeps/htl/bits/types/struct___pthread_rwlockattr.h b/sysdeps/htl/bits/types/struct___pthread_rwlockattr.h
new file mode 100644
index 0000000000..7df532ee04
--- /dev/null
+++ b/sysdeps/htl/bits/types/struct___pthread_rwlockattr.h
@@ -0,0 +1,31 @@
+/* Thread rwlock attribute type.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_RWLOCKATTR_H
+#define _BITS_TYPES_STRUCT___PTHREAD_RWLOCKATTR_H	1
+
+enum __pthread_process_shared;
+
+/* This structure describes the attributes of a POSIX thread rwlock.
+   Note that not all of them are supported on all systems.  */
+struct __pthread_rwlockattr
+{
+  enum __pthread_process_shared __pshared;
+};
+
+#endif /* bits/types/struct___pthread_rwlockattr.h */
diff --git a/sysdeps/htl/flockfile.c b/sysdeps/htl/flockfile.c
new file mode 100644
index 0000000000..f9df093767
--- /dev/null
+++ b/sysdeps/htl/flockfile.c
@@ -0,0 +1,31 @@
+/* Lock I/O stream.  Hurd version.
+   Copyright (C) 2002-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <libc-lock.h>
+
+
+void
+__flockfile (FILE *stream)
+{
+#ifdef SHARED
+  __libc_ptf_call (_IO_flockfile, (stream), 0);
+#endif
+}
+weak_alias (__flockfile, _IO_flockfile)
+weak_alias (__flockfile, flockfile)
diff --git a/sysdeps/htl/fork.h b/sysdeps/htl/fork.h
new file mode 100644
index 0000000000..f944a741ee
--- /dev/null
+++ b/sysdeps/htl/fork.h
@@ -0,0 +1,29 @@
+/* Register fork handlers.  Generic version.
+   Copyright (C) 2002-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Function to call to unregister fork handlers.  */
+extern void __unregister_atfork (void *dso_handle) attribute_hidden;
+#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
+
+
+/* C library side function to register new fork handlers.  */
+extern int __register_atfork (void (*__prepare) (void),
+			      void (*__parent) (void),
+			      void (*__child) (void),
+			      void *dso_handle);
+libc_hidden_proto (__register_atfork)
diff --git a/sysdeps/htl/ftrylockfile.c b/sysdeps/htl/ftrylockfile.c
new file mode 100644
index 0000000000..7de42c7b3d
--- /dev/null
+++ b/sysdeps/htl/ftrylockfile.c
@@ -0,0 +1,35 @@
+/* Try locking I/O stream.  Hurd version
+   Copyright (C) 2002-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdio-lock.h>
+
+
+int
+__ftrylockfile (FILE *stream)
+{
+#ifdef SHARED
+  return __libc_ptf_call (_IO_ftrylockfile, (stream), 0);
+#else
+  return 0;
+#endif
+}
+weak_alias (__ftrylockfile, _IO_ftrylockfile)
+weak_alias (__ftrylockfile, ftrylockfile)
diff --git a/sysdeps/htl/funlockfile.c b/sysdeps/htl/funlockfile.c
new file mode 100644
index 0000000000..bc7da12c34
--- /dev/null
+++ b/sysdeps/htl/funlockfile.c
@@ -0,0 +1,32 @@
+/* Unlock I/O stream.  Hurd version.
+   Copyright (C) 2002-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdio-lock.h>
+
+
+void
+__funlockfile (FILE *stream)
+{
+#ifdef SHARED
+  __libc_ptf_call (_IO_funlockfile, (stream), 0);
+#endif
+}
+weak_alias (__funlockfile, _IO_funlockfile)
+weak_alias (__funlockfile, funlockfile)
diff --git a/sysdeps/htl/libc-lockP.h b/sysdeps/htl/libc-lockP.h
new file mode 100644
index 0000000000..944c0e5931
--- /dev/null
+++ b/sysdeps/htl/libc-lockP.h
@@ -0,0 +1,180 @@
+/* Private libc-internal interface for mutex locks.
+   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_LIBC_LOCKP_H
+#define _BITS_LIBC_LOCKP_H 1
+
+#include <pthread.h>
+#include <pthread-functions.h>
+
+/* Type for key to thread-specific data.  */
+typedef pthread_key_t __libc_key_t;
+
+/* If we check for a weakly referenced symbol and then perform a
+   normal jump to it te code generated for some platforms in case of
+   PIC is unnecessarily slow.  What would happen is that the function
+   is first referenced as data and then it is called indirectly
+   through the PLT.  We can make this a direct jump.  */
+#ifdef __PIC__
+# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+  (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
+		    _fn != NULL ? (*_fn) ARGS : ELSE; }))
+#else
+# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+  (FUNC != NULL ? FUNC ARGS : ELSE)
+#endif
+
+/* Call thread functions through the function pointer table.  */
+#if defined SHARED && IS_IN (libc)
+# define PTFAVAIL(NAME) __libc_pthread_functions_init
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+  (__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+  PTHFCT_CALL (ptr_##FUNC, ARGS)
+#elif IS_IN (libpthread)
+# define PTFAVAIL(NAME) 1
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+  FUNC ARGS
+# define __libc_ptf_call_always(FUNC, ARGS) \
+  FUNC ARGS
+#else
+# define PTFAVAIL(NAME) (NAME != NULL)
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+  __libc_maybe_call (FUNC, ARGS, ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+  FUNC ARGS
+#endif
+
+/* Create thread-specific key.  */
+#define __libc_key_create(KEY, DESTRUCTOR) \
+  __libc_ptf_call (__pthread_key_create, (KEY, DESTRUCTOR), 1)
+
+/* Get thread-specific data.  */
+#define __libc_getspecific(KEY) \
+  __libc_ptf_call (__pthread_getspecific, (KEY), NULL)
+
+/* Set thread-specific data.  */
+#define __libc_setspecific(KEY, VALUE) \
+  __libc_ptf_call (__pthread_setspecific, (KEY, VALUE), 0)
+
+
+/* Functions that are used by this file and are internal to the GNU C
+   library.  */
+
+extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
+				 const pthread_mutexattr_t *__mutex_attr);
+
+extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr,
+					int __kind);
+
+extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock,
+				  const pthread_rwlockattr_t *__attr);
+
+extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_key_create (pthread_key_t *__key,
+				 void (*__destr_function) (void *));
+
+extern int __pthread_setspecific (pthread_key_t __key,
+				  const void *__pointer);
+
+extern void *__pthread_getspecific (pthread_key_t __key);
+
+extern int __pthread_once (pthread_once_t *__once_control,
+			   void (*__init_routine) (void));
+
+extern int __pthread_atfork (void (*__prepare) (void),
+			     void (*__parent) (void),
+			     void (*__child) (void));
+
+
+
+/* Make the pthread functions weak so that we can elide them from
+   single-threaded processes.  */
+#if !defined(__NO_WEAK_PTHREAD_ALIASES) && !IS_IN (libpthread)
+# ifdef weak_extern
+weak_extern (__pthread_mutex_init)
+weak_extern (__pthread_mutex_destroy)
+weak_extern (__pthread_mutex_lock)
+weak_extern (__pthread_mutex_trylock)
+weak_extern (__pthread_mutex_unlock)
+weak_extern (__pthread_mutexattr_init)
+weak_extern (__pthread_mutexattr_destroy)
+weak_extern (__pthread_mutexattr_settype)
+weak_extern (__pthread_rwlock_init)
+weak_extern (__pthread_rwlock_destroy)
+weak_extern (__pthread_rwlock_rdlock)
+weak_extern (__pthread_rwlock_tryrdlock)
+weak_extern (__pthread_rwlock_wrlock)
+weak_extern (__pthread_rwlock_trywrlock)
+weak_extern (__pthread_rwlock_unlock)
+weak_extern (__pthread_key_create)
+weak_extern (__pthread_setspecific)
+weak_extern (__pthread_getspecific)
+weak_extern (__pthread_once)
+weak_extern (__pthread_initialize)
+weak_extern (__pthread_atfork)
+weak_extern (__pthread_setcancelstate)
+# else
+#  pragma weak __pthread_mutex_init
+#  pragma weak __pthread_mutex_destroy
+#  pragma weak __pthread_mutex_lock
+#  pragma weak __pthread_mutex_trylock
+#  pragma weak __pthread_mutex_unlock
+#  pragma weak __pthread_mutexattr_init
+#  pragma weak __pthread_mutexattr_destroy
+#  pragma weak __pthread_mutexattr_settype
+#  pragma weak __pthread_rwlock_destroy
+#  pragma weak __pthread_rwlock_rdlock
+#  pragma weak __pthread_rwlock_tryrdlock
+#  pragma weak __pthread_rwlock_wrlock
+#  pragma weak __pthread_rwlock_trywrlock
+#  pragma weak __pthread_rwlock_unlock
+#  pragma weak __pthread_key_create
+#  pragma weak __pthread_setspecific
+#  pragma weak __pthread_getspecific
+#  pragma weak __pthread_once
+#  pragma weak __pthread_initialize
+#  pragma weak __pthread_atfork
+#  pragma weak __pthread_setcancelstate
+# endif
+#endif
+
+#endif	/* bits/libc-lockP.h */
diff --git a/sysdeps/htl/old_pt-atfork.c b/sysdeps/htl/old_pt-atfork.c
new file mode 100644
index 0000000000..dfb7e983fe
--- /dev/null
+++ b/sysdeps/htl/old_pt-atfork.c
@@ -0,0 +1,26 @@
+/* Register fork handlers.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_12, GLIBC_2_23)
+# define pthread_atfork __dyn_pthread_atfork
+# include "pt-atfork.c"
+# undef pthread_atfork
+compat_symbol (libpthread, __dyn_pthread_atfork, pthread_atfork, GLIBC_2_12);
+#endif
diff --git a/sysdeps/htl/pt-atfork.c b/sysdeps/htl/pt-atfork.c
new file mode 100644
index 0000000000..036427dbbc
--- /dev/null
+++ b/sysdeps/htl/pt-atfork.c
@@ -0,0 +1,33 @@
+/* Register fork handlers.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+#include <fork.h>
+
+/* This is defined by newer gcc version unique for each module.  */
+extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
+
+int
+pthread_atfork (void (*prepare) (void),
+		void (*parent) (void),
+		void (*child) (void))
+{
+  return __register_atfork (prepare, parent, child,
+			    &__dso_handle == NULL ? NULL : __dso_handle);
+}
diff --git a/sysdeps/htl/pt-attr-destroy.c b/sysdeps/htl/pt-attr-destroy.c
new file mode 100644
index 0000000000..a538201eb5
--- /dev/null
+++ b/sysdeps/htl/pt-attr-destroy.c
@@ -0,0 +1,27 @@
+/* pthread_attr_destroy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_destroy (pthread_attr_t *attr)
+{
+  return 0;
+}
+strong_alias (__pthread_attr_destroy, pthread_attr_destroy);
diff --git a/sysdeps/htl/pt-attr-getdetachstate.c b/sysdeps/htl/pt-attr-getdetachstate.c
new file mode 100644
index 0000000000..5520305292
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getdetachstate.c
@@ -0,0 +1,29 @@
+/* pthread_attr_getdetachstate.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstate)
+{
+  *detachstate = attr->__detachstate;
+  return 0;
+}
+
+strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate);
diff --git a/sysdeps/htl/pt-attr-getguardsize.c b/sysdeps/htl/pt-attr-getguardsize.c
new file mode 100644
index 0000000000..38c4f78c18
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getguardsize.c
@@ -0,0 +1,27 @@
+/* pthread_attr_getguardsize.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_getguardsize (const pthread_attr_t *attr, size_t * guardsize)
+{
+  *guardsize = attr->__guardsize;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-attr-getinheritsched.c b/sysdeps/htl/pt-attr-getinheritsched.c
new file mode 100644
index 0000000000..1187dfa641
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getinheritsched.c
@@ -0,0 +1,29 @@
+/* pthread_attr_getinheritsched.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_getinheritsched (const pthread_attr_t *attr, int *inheritsched)
+{
+  *inheritsched = attr->__inheritsched;
+  return 0;
+}
+
+strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched);
diff --git a/sysdeps/htl/pt-attr-getschedparam.c b/sysdeps/htl/pt-attr-getschedparam.c
new file mode 100644
index 0000000000..cd86d61aca
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getschedparam.c
@@ -0,0 +1,33 @@
+/* pthread_attr_getschedparam.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <sched.h>
+#include <string.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_attr_getschedparam (const pthread_attr_t *attr,
+			      struct sched_param *param)
+{
+  memcpy (param, &attr->__schedparam, sizeof *param);
+  return 0;
+}
+
+strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam);
diff --git a/sysdeps/htl/pt-attr-getschedpolicy.c b/sysdeps/htl/pt-attr-getschedpolicy.c
new file mode 100644
index 0000000000..49e1fedb0c
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getschedpolicy.c
@@ -0,0 +1,29 @@
+/* pthread_attr_getschedpolicy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy)
+{
+  *policy = attr->__schedpolicy;
+  return 0;
+}
+
+strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy);
diff --git a/sysdeps/htl/pt-attr-getscope.c b/sysdeps/htl/pt-attr-getscope.c
new file mode 100644
index 0000000000..a48ec6d827
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getscope.c
@@ -0,0 +1,29 @@
+/* pthread_attr_getscope.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_getscope (const pthread_attr_t *attr, int *contentionscope)
+{
+  *contentionscope = attr->__contentionscope;
+  return 0;
+}
+
+strong_alias (__pthread_attr_getscope, pthread_attr_getscope);
diff --git a/sysdeps/htl/pt-attr-getstack.c b/sysdeps/htl/pt-attr-getstack.c
new file mode 100644
index 0000000000..4367c2f747
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getstack.c
@@ -0,0 +1,30 @@
+/* pthread_attr_getstack.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_getstack (const pthread_attr_t *attr,
+			 void **stackaddr, size_t * stacksize)
+{
+  pthread_attr_getstackaddr (attr, stackaddr);
+  pthread_attr_getstacksize (attr, stacksize);
+  return 0;
+}
+weak_alias (__pthread_attr_getstack, pthread_attr_getstack)
diff --git a/sysdeps/htl/pt-attr-getstackaddr.c b/sysdeps/htl/pt-attr-getstackaddr.c
new file mode 100644
index 0000000000..a043d788a7
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getstackaddr.c
@@ -0,0 +1,27 @@
+/* pthread_attr_getstackaddr.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_getstackaddr (const pthread_attr_t *attr, void **stackaddr)
+{
+  *stackaddr = attr->__stackaddr;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-attr-getstacksize.c b/sysdeps/htl/pt-attr-getstacksize.c
new file mode 100644
index 0000000000..59c9c645db
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getstacksize.c
@@ -0,0 +1,27 @@
+/* pthread_attr_getstacksize.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_getstacksize (const pthread_attr_t *attr, size_t * stacksize)
+{
+  *stacksize = attr->__stacksize;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-attr-init.c b/sysdeps/htl/pt-attr-init.c
new file mode 100644
index 0000000000..e6ccc82a64
--- /dev/null
+++ b/sysdeps/htl/pt-attr-init.c
@@ -0,0 +1,28 @@
+/* pthread_attr_init.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_init (pthread_attr_t *attr)
+{
+  *attr = __pthread_default_attr;
+  return 0;
+}
+strong_alias (__pthread_attr_init, pthread_attr_init);
diff --git a/sysdeps/htl/pt-attr-setdetachstate.c b/sysdeps/htl/pt-attr-setdetachstate.c
new file mode 100644
index 0000000000..4907f4b56a
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setdetachstate.c
@@ -0,0 +1,38 @@
+/* pthread_attr_setdetachstate.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate)
+{
+  switch (detachstate)
+    {
+    case PTHREAD_CREATE_DETACHED:
+    case PTHREAD_CREATE_JOINABLE:
+      attr->__detachstate = detachstate;
+      break;
+    default:
+      return EINVAL;
+    }
+
+  return 0;
+}
+
+strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate);
diff --git a/sysdeps/htl/pt-attr-setguardsize.c b/sysdeps/htl/pt-attr-setguardsize.c
new file mode 100644
index 0000000000..97f9d3b06e
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setguardsize.c
@@ -0,0 +1,27 @@
+/* pthread_attr_setguardsize.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_setguardsize (pthread_attr_t *attr, size_t guardsize)
+{
+  attr->__guardsize = guardsize;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-attr-setinheritsched.c b/sysdeps/htl/pt-attr-setinheritsched.c
new file mode 100644
index 0000000000..abbb9cb8a9
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setinheritsched.c
@@ -0,0 +1,38 @@
+/* pthread_attr_setinheritsched.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_setinheritsched (pthread_attr_t *attr, int inheritsched)
+{
+  switch (inheritsched)
+    {
+    case PTHREAD_INHERIT_SCHED:
+    case PTHREAD_EXPLICIT_SCHED:
+      attr->__inheritsched = inheritsched;
+      break;
+    default:
+      return EINVAL;
+    }
+
+  return 0;
+}
+
+strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched);
diff --git a/sysdeps/htl/pt-attr-setschedparam.c b/sysdeps/htl/pt-attr-setschedparam.c
new file mode 100644
index 0000000000..c382f55499
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setschedparam.c
@@ -0,0 +1,38 @@
+/* pthread_attr_getschedparam.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <sched.h>
+#include <string.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_attr_setschedparam (pthread_attr_t *attr,
+			      const struct sched_param *param)
+{
+  if (memcmp (param, &__pthread_default_attr.__schedparam, sizeof *param) == 0)
+    {
+      memcpy (&attr->__schedparam, param, sizeof *param);
+      return 0;
+    }
+
+  return ENOTSUP;
+}
+
+strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam);
diff --git a/sysdeps/htl/pt-attr-setschedpolicy.c b/sysdeps/htl/pt-attr-setschedpolicy.c
new file mode 100644
index 0000000000..411fc0be3c
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setschedpolicy.c
@@ -0,0 +1,42 @@
+/* pthread_attr_getschedpolicy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy)
+{
+  switch (policy)
+    {
+    case SCHED_OTHER:
+      attr->__schedpolicy = policy;
+      break;
+
+    case SCHED_FIFO:
+    case SCHED_RR:
+      return ENOTSUP;
+
+    default:
+      return EINVAL;
+    }
+
+  return 0;
+}
+
+strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
diff --git a/sysdeps/htl/pt-attr-setscope.c b/sysdeps/htl/pt-attr-setscope.c
new file mode 100644
index 0000000000..4e20d24de1
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setscope.c
@@ -0,0 +1,41 @@
+/* pthread_attr_setscope.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_attr_setscope (pthread_attr_t *attr, int contentionscope)
+{
+  if (contentionscope == __pthread_default_attr.__contentionscope)
+    {
+      attr->__contentionscope = contentionscope;
+      return 0;
+    }
+
+  switch (contentionscope)
+    {
+    case PTHREAD_SCOPE_PROCESS:
+    case PTHREAD_SCOPE_SYSTEM:
+      return ENOTSUP;
+    default:
+      return EINVAL;
+    }
+}
+
+strong_alias (__pthread_attr_setscope, pthread_attr_setscope);
diff --git a/sysdeps/htl/pt-attr-setstack.c b/sysdeps/htl/pt-attr-setstack.c
new file mode 100644
index 0000000000..e538283459
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setstack.c
@@ -0,0 +1,48 @@
+/* pthread_attr_setstack.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize)
+{
+  int err;
+  size_t s;
+
+  /* pthread_attr_setstack should always succeed, thus we set the size
+     first as it is more discriminating.  */
+  pthread_attr_getstacksize (attr, &s);
+
+  err = pthread_attr_setstacksize (attr, stacksize);
+  if (err)
+    return err;
+
+  err = pthread_attr_setstackaddr (attr, stackaddr);
+  if (err)
+    {
+      int e = pthread_attr_setstacksize (attr, s);
+      assert_perror (e);
+
+      return err;
+    }
+
+  return 0;
+}
diff --git a/sysdeps/htl/pt-attr-setstackaddr.c b/sysdeps/htl/pt-attr-setstackaddr.c
new file mode 100644
index 0000000000..e3ca583375
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setstackaddr.c
@@ -0,0 +1,27 @@
+/* pthread_attr_setstackaddr.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr)
+{
+  attr->__stackaddr = stackaddr;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-attr-setstacksize.c b/sysdeps/htl/pt-attr-setstacksize.c
new file mode 100644
index 0000000000..547bf675ca
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setstacksize.c
@@ -0,0 +1,28 @@
+/* pthread_attr_setstacksize.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize)
+{
+  attr->__stacksize = stacksize;
+
+  return 0;
+}
diff --git a/sysdeps/htl/pt-attr.c b/sysdeps/htl/pt-attr.c
new file mode 100644
index 0000000000..f1877fdaa2
--- /dev/null
+++ b/sysdeps/htl/pt-attr.c
@@ -0,0 +1,39 @@
+/* Default attributes.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <sched.h>
+#include <stddef.h>
+#include <limits.h>
+
+#include <pt-internal.h>
+
+const struct __pthread_attr __pthread_default_attr = {
+  __schedparam: { sched_priority: 0 },
+  __stacksize: 0,
+  __stackaddr: NULL,
+#ifdef PAGESIZE
+  __guardsize: PAGESIZE,
+#else
+  __guardsize: 1,
+#endif /* PAGESIZE */
+  __detachstate: PTHREAD_CREATE_JOINABLE,
+  __inheritsched: PTHREAD_EXPLICIT_SCHED,
+  __contentionscope: PTHREAD_SCOPE_SYSTEM,
+  __schedpolicy: SCHED_OTHER
+};
diff --git a/sysdeps/htl/pt-barrier-destroy.c b/sysdeps/htl/pt-barrier-destroy.c
new file mode 100644
index 0000000000..7d4f03ea37
--- /dev/null
+++ b/sysdeps/htl/pt-barrier-destroy.c
@@ -0,0 +1,26 @@
+/* pthread_barrier_destroy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_barrier_destroy (pthread_barrier_t *barrier)
+{
+  return 0;
+}
diff --git a/sysdeps/htl/pt-barrier-init.c b/sysdeps/htl/pt-barrier-init.c
new file mode 100644
index 0000000000..8f652d7d27
--- /dev/null
+++ b/sysdeps/htl/pt-barrier-init.c
@@ -0,0 +1,51 @@
+/* pthread_barrier_init.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <string.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+pthread_barrier_init (pthread_barrier_t *barrier,
+		      const pthread_barrierattr_t *attr, unsigned count)
+{
+  if (count == 0)
+    return EINVAL;
+
+  memset (barrier, 0, sizeof *barrier);
+
+  barrier->__lock = PTHREAD_SPINLOCK_INITIALIZER;
+  barrier->__pending = count;
+  barrier->__count = count;
+
+  if (attr == NULL
+      || memcmp (attr, &__pthread_default_barrierattr, sizeof (*attr) == 0))
+    /* Use the default attributes.  */
+    return 0;
+
+  /* Non-default attributes.  */
+
+  barrier->__attr = malloc (sizeof *attr);
+  if (barrier->__attr == NULL)
+    return ENOMEM;
+
+  *barrier->__attr = *attr;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-barrier-wait.c b/sysdeps/htl/pt-barrier-wait.c
new file mode 100644
index 0000000000..faac1f9d5a
--- /dev/null
+++ b/sysdeps/htl/pt-barrier-wait.c
@@ -0,0 +1,68 @@
+/* pthread_barrier_wait.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+pthread_barrier_wait (pthread_barrier_t *barrier)
+{
+  __pthread_spin_lock (&barrier->__lock);
+  if (--barrier->__pending == 0)
+    {
+      barrier->__pending = barrier->__count;
+
+      if (barrier->__count > 1)
+	{
+	  struct __pthread *wakeup;
+	  unsigned n = 0;
+
+	  __pthread_queue_iterate (barrier->__queue, wakeup)
+	    n++;
+
+	  {
+	    struct __pthread *wakeups[n];
+	    unsigned i = 0;
+
+	    __pthread_dequeuing_iterate (barrier->__queue, wakeup)
+	      wakeups[i++] = wakeup;
+
+	    barrier->__queue = NULL;
+	    __pthread_spin_unlock (&barrier->__lock);
+
+	    for (i = 0; i < n; i++)
+	      __pthread_wakeup (wakeups[i]);
+	  }
+	}
+
+      return PTHREAD_BARRIER_SERIAL_THREAD;
+    }
+  else
+    {
+      struct __pthread *self = _pthread_self ();
+
+      /* Add ourselves to the list of waiters.  */
+      __pthread_enqueue (&barrier->__queue, self);
+      __pthread_spin_unlock (&barrier->__lock);
+
+      __pthread_block (self);
+      return 0;
+    }
+}
diff --git a/sysdeps/htl/pt-barrier.c b/sysdeps/htl/pt-barrier.c
new file mode 100644
index 0000000000..0990ce9798
--- /dev/null
+++ b/sysdeps/htl/pt-barrier.c
@@ -0,0 +1,24 @@
+/* Default barrier attributes.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+const struct __pthread_barrierattr __pthread_default_barrierattr = {
+  __pshared: PTHREAD_PROCESS_PRIVATE
+};
diff --git a/sysdeps/htl/pt-barrierattr-destroy.c b/sysdeps/htl/pt-barrierattr-destroy.c
new file mode 100644
index 0000000000..c99227b7a3
--- /dev/null
+++ b/sysdeps/htl/pt-barrierattr-destroy.c
@@ -0,0 +1,26 @@
+/* pthread_barrierattr_destroy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_barrierattr_destroy (pthread_barrierattr_t *attr)
+{
+  return 0;
+}
diff --git a/sysdeps/htl/pt-barrierattr-getpshared.c b/sysdeps/htl/pt-barrierattr-getpshared.c
new file mode 100644
index 0000000000..3015f1c107
--- /dev/null
+++ b/sysdeps/htl/pt-barrierattr-getpshared.c
@@ -0,0 +1,28 @@
+/* pthread_barrierattr_getpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_barrierattr_getpshared (const pthread_barrierattr_t *attr,
+				int *pshared)
+{
+  *pshared = attr->__pshared;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-barrierattr-init.c b/sysdeps/htl/pt-barrierattr-init.c
new file mode 100644
index 0000000000..b5236287cf
--- /dev/null
+++ b/sysdeps/htl/pt-barrierattr-init.c
@@ -0,0 +1,27 @@
+/* pthread_barrierattr_init.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_barrierattr_init (pthread_barrierattr_t *attr)
+{
+  *attr = __pthread_default_barrierattr;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-barrierattr-setpshared.c b/sysdeps/htl/pt-barrierattr-setpshared.c
new file mode 100644
index 0000000000..52a5040b73
--- /dev/null
+++ b/sysdeps/htl/pt-barrierattr-setpshared.c
@@ -0,0 +1,37 @@
+/* pthread_barrierattr_setpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_barrierattr_setpshared (pthread_barrierattr_t *attr, int pshared)
+{
+  switch (pshared)
+    {
+    case PTHREAD_PROCESS_PRIVATE:
+      attr->__pshared = pshared;
+      return 0;
+
+    case PTHREAD_PROCESS_SHARED:
+      return ENOTSUP;
+
+    default:
+      return EINVAL;
+    }
+}
diff --git a/sysdeps/htl/pt-cond-brdcast.c b/sysdeps/htl/pt-cond-brdcast.c
new file mode 100644
index 0000000000..fc1d65352a
--- /dev/null
+++ b/sysdeps/htl/pt-cond-brdcast.c
@@ -0,0 +1,44 @@
+/* Broadcast a condition.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+/* Unblock all threads that are blocked on condition variable COND.  */
+int
+__pthread_cond_broadcast (pthread_cond_t *cond)
+{
+  struct __pthread *wakeup;
+
+  __pthread_spin_lock (&cond->__lock);
+  while ((wakeup = cond->__queue))
+    {
+      __pthread_dequeue (wakeup);
+      __pthread_spin_unlock (&cond->__lock);
+      /* Wake it up without spin held, so it may have a chance to really
+         preempt us */
+      __pthread_wakeup (wakeup);
+      __pthread_spin_lock (&cond->__lock);
+    }
+  __pthread_spin_unlock (&cond->__lock);
+
+  return 0;
+}
+
+strong_alias (__pthread_cond_broadcast, pthread_cond_broadcast);
diff --git a/sysdeps/htl/pt-cond-destroy.c b/sysdeps/htl/pt-cond-destroy.c
new file mode 100644
index 0000000000..81c4ccfd20
--- /dev/null
+++ b/sysdeps/htl/pt-cond-destroy.c
@@ -0,0 +1,28 @@
+/* pthread_cond_destroy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_cond_destroy (pthread_cond_t *cond)
+{
+  return 0;
+}
+
+strong_alias (__pthread_cond_destroy, pthread_cond_destroy);
diff --git a/sysdeps/htl/pt-cond-init.c b/sysdeps/htl/pt-cond-init.c
new file mode 100644
index 0000000000..4c128ac86c
--- /dev/null
+++ b/sysdeps/htl/pt-cond-init.c
@@ -0,0 +1,45 @@
+/* pthread_cond_init.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+#include <string.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t * attr)
+{
+  *cond = (pthread_cond_t) __PTHREAD_COND_INITIALIZER;
+
+  if (attr == NULL
+      || memcmp (attr, &__pthread_default_condattr, sizeof (*attr) == 0))
+    /* Use the default attributes.  */
+    return 0;
+
+  /* Non-default attributes.  */
+
+  cond->__attr = malloc (sizeof *attr);
+  if (cond->__attr == NULL)
+    return ENOMEM;
+
+  *cond->__attr = *attr;
+  return 0;
+}
+
+strong_alias (__pthread_cond_init, pthread_cond_init);
diff --git a/sysdeps/htl/pt-cond-signal.c b/sysdeps/htl/pt-cond-signal.c
new file mode 100644
index 0000000000..a1c0c2adcf
--- /dev/null
+++ b/sysdeps/htl/pt-cond-signal.c
@@ -0,0 +1,42 @@
+/* Signal a condition.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+/* Unblock at least one of the threads that are blocked on condition
+   variable COND.  */
+int
+__pthread_cond_signal (pthread_cond_t *cond)
+{
+  struct __pthread *wakeup;
+
+  __pthread_spin_lock (&cond->__lock);
+  wakeup = cond->__queue;
+  if (wakeup != NULL)
+    __pthread_dequeue (wakeup);
+  __pthread_spin_unlock (&cond->__lock);
+
+  if (wakeup != NULL)
+    __pthread_wakeup (wakeup);
+
+  return 0;
+}
+
+strong_alias (__pthread_cond_signal, pthread_cond_signal);
diff --git a/sysdeps/htl/pt-cond-timedwait.c b/sysdeps/htl/pt-cond-timedwait.c
new file mode 100644
index 0000000000..525e63dd42
--- /dev/null
+++ b/sysdeps/htl/pt-cond-timedwait.c
@@ -0,0 +1,177 @@
+/* Wait on a condition.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond,
+					      pthread_mutex_t *mutex,
+					      const struct timespec *abstime);
+
+int
+__pthread_cond_timedwait (pthread_cond_t *cond,
+			  pthread_mutex_t *mutex,
+			  const struct timespec *abstime)
+{
+  return __pthread_cond_timedwait_internal (cond, mutex, abstime);
+}
+
+strong_alias (__pthread_cond_timedwait, pthread_cond_timedwait);
+
+struct cancel_ctx
+{
+  struct __pthread *wakeup;
+  pthread_cond_t *cond;
+};
+
+static void
+cancel_hook (void *arg)
+{
+  struct cancel_ctx *ctx = arg;
+  struct __pthread *wakeup = ctx->wakeup;
+  pthread_cond_t *cond = ctx->cond;
+  int unblock;
+
+  __pthread_spin_lock (&cond->__lock);
+  /* The thread only needs to be awaken if it's blocking or about to block.
+     If it was already unblocked, it's not queued any more.  */
+  unblock = wakeup->prevp != NULL;
+  if (unblock)
+    __pthread_dequeue (wakeup);
+  __pthread_spin_unlock (&cond->__lock);
+
+  if (unblock)
+    __pthread_wakeup (wakeup);
+}
+
+/* Block on condition variable COND until ABSTIME.  As a GNU
+   extension, if ABSTIME is NULL, then wait forever.  MUTEX should be
+   held by the calling thread.  On return, MUTEX will be held by the
+   calling thread.  */
+int
+__pthread_cond_timedwait_internal (pthread_cond_t *cond,
+				   pthread_mutex_t *mutex,
+				   const struct timespec *abstime)
+{
+  error_t err;
+  int cancelled, oldtype, drain;
+  clockid_t clock_id = __pthread_default_condattr.__clock;
+
+  if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+    return EINVAL;
+
+  struct __pthread *self = _pthread_self ();
+  struct cancel_ctx ctx;
+  ctx.wakeup = self;
+  ctx.cond = cond;
+
+  /* Test for a pending cancellation request, switch to deferred mode for
+     safer resource handling, and prepare the hook to call in case we're
+     cancelled while blocking.  Once CANCEL_LOCK is released, the cancellation
+     hook can be called by another thread at any time.  Whatever happens,
+     this function must exit with MUTEX locked.
+
+     This function contains inline implementations of pthread_testcancel and
+     pthread_setcanceltype to reduce locking overhead.  */
+  __pthread_mutex_lock (&self->cancel_lock);
+  cancelled = (self->cancel_state == PTHREAD_CANCEL_ENABLE)
+      && self->cancel_pending;
+
+  if (!cancelled)
+    {
+      self->cancel_hook = cancel_hook;
+      self->cancel_hook_arg = &ctx;
+      oldtype = self->cancel_type;
+
+      if (oldtype != PTHREAD_CANCEL_DEFERRED)
+	self->cancel_type = PTHREAD_CANCEL_DEFERRED;
+
+      /* Add ourselves to the list of waiters.  This is done while setting
+         the cancellation hook to simplify the cancellation procedure, i.e.
+         if the thread is queued, it can be cancelled, otherwise it is
+         already unblocked, progressing on the return path.  */
+      __pthread_spin_lock (&cond->__lock);
+      __pthread_enqueue (&cond->__queue, self);
+      if (cond->__attr != NULL)
+	clock_id = cond->__attr->__clock;
+      __pthread_spin_unlock (&cond->__lock);
+    }
+  __pthread_mutex_unlock (&self->cancel_lock);
+
+  if (cancelled)
+    pthread_exit (PTHREAD_CANCELED);
+
+  /* Release MUTEX before blocking.  */
+  __pthread_mutex_unlock (mutex);
+
+  /* Block the thread.  */
+  if (abstime != NULL)
+    err = __pthread_timedblock (self, abstime, clock_id);
+  else
+    {
+      err = 0;
+      __pthread_block (self);
+    }
+
+  __pthread_spin_lock (&cond->__lock);
+  if (self->prevp == NULL)
+    {
+      /* Another thread removed us from the list of waiters, which means a
+         wakeup message has been sent.  It was either consumed while we were
+         blocking, or queued after we timed out and before we acquired the
+         condition lock, in which case the message queue must be drained.  */
+      if (!err)
+	drain = 0;
+      else
+	{
+	  assert (err == ETIMEDOUT);
+	  drain = 1;
+	}
+    }
+  else
+    {
+      /* We're still in the list of waiters.  Noone attempted to wake us up,
+         i.e. we timed out.  */
+      assert (err == ETIMEDOUT);
+      __pthread_dequeue (self);
+      drain = 0;
+    }
+  __pthread_spin_unlock (&cond->__lock);
+
+  if (drain)
+    __pthread_block (self);
+
+  /* We're almost done.  Remove the unblock hook, restore the previous
+     cancellation type, and check for a pending cancellation request.  */
+  __pthread_mutex_lock (&self->cancel_lock);
+  self->cancel_hook = NULL;
+  self->cancel_hook_arg = NULL;
+  self->cancel_type = oldtype;
+  cancelled = (self->cancel_state == PTHREAD_CANCEL_ENABLE)
+      && self->cancel_pending;
+  __pthread_mutex_unlock (&self->cancel_lock);
+
+  /* Reacquire MUTEX before returning/cancelling.  */
+  __pthread_mutex_lock (mutex);
+
+  if (cancelled)
+    pthread_exit (PTHREAD_CANCELED);
+
+  return err;
+}
diff --git a/sysdeps/htl/pt-cond-wait.c b/sysdeps/htl/pt-cond-wait.c
new file mode 100644
index 0000000000..8ea7c8e980
--- /dev/null
+++ b/sysdeps/htl/pt-cond-wait.c
@@ -0,0 +1,38 @@
+/* Wait on a condition.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+/* Implemented in pt-cond-timedwait.c.  */
+extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond,
+					      pthread_mutex_t *mutex,
+					      const struct timespec *abstime);
+
+
+/* Block on condition variable COND.  MUTEX should be held by the
+   calling thread.  On return, MUTEX will be held by the calling
+   thread.  */
+int
+__pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+  return __pthread_cond_timedwait_internal (cond, mutex, 0);
+}
+
+strong_alias (__pthread_cond_wait, pthread_cond_wait);
diff --git a/sysdeps/htl/pt-cond.c b/sysdeps/htl/pt-cond.c
new file mode 100644
index 0000000000..2dc6c51f29
--- /dev/null
+++ b/sysdeps/htl/pt-cond.c
@@ -0,0 +1,27 @@
+/* Default condition attributes.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <time.h>
+
+#include <pt-internal.h>
+
+const struct __pthread_condattr __pthread_default_condattr = {
+  __pshared: PTHREAD_PROCESS_PRIVATE,
+  __clock: CLOCK_REALTIME
+};
diff --git a/sysdeps/htl/pt-condattr-destroy.c b/sysdeps/htl/pt-condattr-destroy.c
new file mode 100644
index 0000000000..7399858d45
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-destroy.c
@@ -0,0 +1,28 @@
+/* pthread_condattr_destroy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_condattr_destroy (pthread_condattr_t *cond)
+{
+  return 0;
+}
+
+strong_alias (__pthread_condattr_destroy, pthread_condattr_destroy);
diff --git a/sysdeps/htl/pt-condattr-getclock.c b/sysdeps/htl/pt-condattr-getclock.c
new file mode 100644
index 0000000000..6c603e1b0b
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-getclock.c
@@ -0,0 +1,29 @@
+/* pthread_condattr_getclock.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <time.h>
+
+#include <pt-internal.h>
+
+int
+pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t * clock)
+{
+  *clock = attr->__clock;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-condattr-getpshared.c b/sysdeps/htl/pt-condattr-getpshared.c
new file mode 100644
index 0000000000..4f51f7ed43
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-getpshared.c
@@ -0,0 +1,27 @@
+/* pthread_condattr_getpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
+{
+  *pshared = attr->__pshared;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-condattr-init.c b/sysdeps/htl/pt-condattr-init.c
new file mode 100644
index 0000000000..ec392e13d7
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-init.c
@@ -0,0 +1,29 @@
+/* pthread_condattr_init.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_condattr_init (pthread_condattr_t *attr)
+{
+  *attr = __pthread_default_condattr;
+  return 0;
+}
+
+strong_alias (__pthread_condattr_init, pthread_condattr_init);
diff --git a/sysdeps/htl/pt-condattr-setclock.c b/sysdeps/htl/pt-condattr-setclock.c
new file mode 100644
index 0000000000..fa3e14a0d3
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-setclock.c
@@ -0,0 +1,51 @@
+/* pthread_condattr_setclock.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock)
+{
+  /* Only a few clocks are allowed.  CLOCK_REALTIME is always allowed.
+     CLOCK_MONOTONIC only if the kernel has the necessary support.  */
+  if (clock == CLOCK_MONOTONIC)
+    {
+      /* Check whether the clock is available.  */
+      static int avail;
+
+      if (avail == 0)
+	{
+	  struct timespec ts;
+	  int res;
+
+	  res = clock_gettime (CLOCK_MONOTONIC, &ts);
+	  avail = res < 0 ? -1 : 1;
+	}
+
+      if (avail < 0)
+	/* Not available.  */
+	return EINVAL;
+    }
+  else if (clock != CLOCK_REALTIME)
+    return EINVAL;
+
+  attr->__clock = clock;
+
+  return 0;
+}
diff --git a/sysdeps/htl/pt-condattr-setpshared.c b/sysdeps/htl/pt-condattr-setpshared.c
new file mode 100644
index 0000000000..9283a681fe
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-setpshared.c
@@ -0,0 +1,37 @@
+/* pthread_condattr_setpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared)
+{
+  switch (pshared)
+    {
+    case PTHREAD_PROCESS_PRIVATE:
+      attr->__pshared = pshared;
+      return 0;
+
+    case PTHREAD_PROCESS_SHARED:
+      return ENOTSUP;
+
+    default:
+      return EINVAL;
+    }
+}
diff --git a/sysdeps/htl/pt-destroy-specific.c b/sysdeps/htl/pt-destroy-specific.c
new file mode 100644
index 0000000000..523a62007d
--- /dev/null
+++ b/sysdeps/htl/pt-destroy-specific.c
@@ -0,0 +1,77 @@
+/* __pthread_destory_specific.  Hurd version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <pt-internal.h>
+
+void
+__pthread_destroy_specific (struct __pthread *thread)
+{
+  int i;
+  int seen_one;
+
+  /* Check if there is any thread specific data.  */
+  if (thread->thread_specifics == NULL)
+    return;
+
+  __pthread_key_lock_ready ();
+
+  /* Iterate and call the destructors on any thread specific data.  */
+  for (;;)
+    {
+      seen_one = 0;
+
+      __pthread_mutex_lock (&__pthread_key_lock);
+
+      for (i = 0; i < __pthread_key_count && i < thread->thread_specifics_size;
+	   i++)
+	{
+	  void *value;
+
+	  if (__pthread_key_destructors[i] == PTHREAD_KEY_INVALID)
+	    continue;
+
+	  value = thread->thread_specifics[i];
+	  if (value != NULL)
+	    {
+	      thread->thread_specifics[i] = 0;
+
+	      if (__pthread_key_destructors[i])
+		{
+		  seen_one = 1;
+		  __pthread_key_destructors[i] (value);
+		}
+	    }
+	}
+
+      __pthread_mutex_unlock (&__pthread_key_lock);
+
+      if (!seen_one)
+	break;
+
+      /* This may take a very long time.  Let those blocking on
+         pthread_key_create or pthread_key_delete make progress.  */
+      sched_yield ();
+    }
+
+  free (thread->thread_specifics);
+  thread->thread_specifics = 0;
+  thread->thread_specifics_size = 0;
+}
diff --git a/sysdeps/htl/pt-equal.c b/sysdeps/htl/pt-equal.c
new file mode 100644
index 0000000000..11ded7adf5
--- /dev/null
+++ b/sysdeps/htl/pt-equal.c
@@ -0,0 +1,30 @@
+/* Default attributes.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+/* Return true if __T1 and __T2 both name the same thread.  Otherwise,
+   false.  */
+int
+__pthread_equal (pthread_t __t1, pthread_t __t2)
+{
+  return __t1 == __t2;
+}
+
+strong_alias (__pthread_equal, pthread_equal);
diff --git a/sysdeps/htl/pt-getconcurrency.c b/sysdeps/htl/pt-getconcurrency.c
new file mode 100644
index 0000000000..4b959019a1
--- /dev/null
+++ b/sysdeps/htl/pt-getconcurrency.c
@@ -0,0 +1,26 @@
+/* Get the current level of desired concurrency.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_getconcurrency (void)
+{
+  return __pthread_concurrency;
+}
diff --git a/sysdeps/htl/pt-getcpuclockid.c b/sysdeps/htl/pt-getcpuclockid.c
new file mode 100644
index 0000000000..e4c7e87a3e
--- /dev/null
+++ b/sysdeps/htl/pt-getcpuclockid.c
@@ -0,0 +1,35 @@
+/* Return a thread's cpu clockid.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <time.h>
+
+#include <pt-internal.h>
+
+int
+pthread_getcpuclockid (pthread_t thread, clockid_t *clock)
+{
+#ifdef CLOCK_THREAD_CPUTIME_ID
+  *clock = CLOCK_THREAD_CPUTIME_ID;
+  return 0;
+#else
+  return ENOSYS;
+#endif
+}
+
+stub_warning (pthread_getcpuclockid)
diff --git a/sysdeps/htl/pt-getschedparam.c b/sysdeps/htl/pt-getschedparam.c
new file mode 100644
index 0000000000..2d8328719e
--- /dev/null
+++ b/sysdeps/htl/pt-getschedparam.c
@@ -0,0 +1,31 @@
+/* Get the scheduling parameters for a thread.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_getschedparam (pthread_t thread, int *policy,
+			 struct sched_param *param)
+{
+  *policy = SCHED_OTHER;
+  param->sched_priority = 0;
+  return 0;
+}
+
+strong_alias (__pthread_getschedparam, pthread_getschedparam);
diff --git a/sysdeps/htl/pt-getspecific.c b/sysdeps/htl/pt-getspecific.c
new file mode 100644
index 0000000000..70e1f6c01d
--- /dev/null
+++ b/sysdeps/htl/pt-getspecific.c
@@ -0,0 +1,38 @@
+/* pthread_getspecific.  Hurd version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+void *
+__pthread_getspecific (pthread_key_t key)
+{
+  struct __pthread *self;
+
+  if (key < 0 || key >= __pthread_key_count
+      || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID)
+    return NULL;
+
+  self = _pthread_self ();
+  if (key >= self->thread_specifics_size)
+    return 0;
+
+  return self->thread_specifics[key];
+}
+strong_alias (__pthread_getspecific, pthread_getspecific);
diff --git a/sysdeps/htl/pt-init-specific.c b/sysdeps/htl/pt-init-specific.c
new file mode 100644
index 0000000000..841ba27c42
--- /dev/null
+++ b/sysdeps/htl/pt-init-specific.c
@@ -0,0 +1,30 @@
+/* __pthread_init_specific.  Hurd version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <pt-internal.h>
+
+error_t
+__pthread_init_specific (struct __pthread *thread)
+{
+  thread->thread_specifics = 0;
+  thread->thread_specifics_size = 0;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-key-create.c b/sysdeps/htl/pt-key-create.c
new file mode 100644
index 0000000000..194acc3cea
--- /dev/null
+++ b/sysdeps/htl/pt-key-create.c
@@ -0,0 +1,108 @@
+/* pthread_key_create.  Hurd version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+pthread_mutex_t __pthread_key_lock;
+
+void (**__pthread_key_destructors) (void *arg);
+int __pthread_key_size;
+int __pthread_key_count;
+int __pthread_key_invalid_count;
+
+int
+__pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
+{
+  /* Where to look for the next key slot.  */
+  static int index;
+
+  __pthread_key_lock_ready ();
+
+  __pthread_mutex_lock (&__pthread_key_lock);
+
+do_search:
+  /* Use the search hint and try to find a free slot.  */
+  for (; index < __pthread_key_count
+       && __pthread_key_destructors[index] != PTHREAD_KEY_INVALID; index++)
+    ;
+
+  /* See if we actually found a free element.  */
+  if (index < __pthread_key_count)
+    {
+      assert (__pthread_key_destructors[index] == PTHREAD_KEY_INVALID);
+      assert (__pthread_key_invalid_count > 0);
+
+      __pthread_key_invalid_count--;
+      __pthread_key_destructors[index] = destructor;
+      *key = index++;
+
+      __pthread_mutex_unlock (&__pthread_key_lock);
+      return 0;
+    }
+
+  assert (index == __pthread_key_count);
+
+  /* No space at the end.  */
+  if (__pthread_key_size == __pthread_key_count)
+    {
+      /* See if it is worth looking for a free element.  */
+      if (__pthread_key_invalid_count > 4
+	  && __pthread_key_invalid_count > __pthread_key_size / 8)
+	{
+	  index = 0;
+	  goto do_search;
+	}
+
+
+      /* Resize the array.  */
+      {
+	void *t;
+	int newsize;
+
+	if (__pthread_key_size == 0)
+	  newsize = 8;
+	else
+	  newsize = __pthread_key_size * 2;
+
+	t = realloc (__pthread_key_destructors,
+		     newsize * sizeof (*__pthread_key_destructors));
+	if (t == NULL)
+	  {
+	    __pthread_mutex_unlock (&__pthread_key_lock);
+	    return ENOMEM;
+	  }
+
+	__pthread_key_size = newsize;
+	__pthread_key_destructors = t;
+      }
+    }
+
+  __pthread_key_destructors[index] = destructor;
+  *key = index;
+
+  index++;
+  __pthread_key_count++;
+
+  __pthread_mutex_unlock (&__pthread_key_lock);
+  return 0;
+}
+strong_alias (__pthread_key_create, pthread_key_create)
diff --git a/sysdeps/htl/pt-key-delete.c b/sysdeps/htl/pt-key-delete.c
new file mode 100644
index 0000000000..e9b5665c31
--- /dev/null
+++ b/sysdeps/htl/pt-key-delete.c
@@ -0,0 +1,63 @@
+/* pthread_key_delete.  Hurd version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+int
+pthread_key_delete (pthread_key_t key)
+{
+  error_t err = 0;
+
+  __pthread_key_lock_ready ();
+
+  __pthread_mutex_lock (&__pthread_key_lock);
+
+  if (key < 0 || key >= __pthread_key_count
+      || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID)
+    err = EINVAL;
+  else
+    {
+      int i;
+
+      __pthread_key_destructors[key] = PTHREAD_KEY_INVALID;
+      __pthread_key_invalid_count++;
+
+      __pthread_rwlock_rdlock (&__pthread_threads_lock);
+      for (i = 0; i < __pthread_num_threads; ++i)
+	{
+	  struct __pthread *t;
+
+	  t = __pthread_threads[i];
+
+	  if (t == NULL)
+	    continue;
+
+	  /* Just remove the key, no need to care whether it was
+	     already there. */
+	  if (key < t->thread_specifics_size)
+	    t->thread_specifics[key] = 0;
+	}
+      __pthread_rwlock_unlock (&__pthread_threads_lock);
+    }
+
+  __pthread_mutex_unlock (&__pthread_key_lock);
+
+  return err;
+}
diff --git a/sysdeps/htl/pt-key.h b/sysdeps/htl/pt-key.h
new file mode 100644
index 0000000000..d1d4b765a5
--- /dev/null
+++ b/sysdeps/htl/pt-key.h
@@ -0,0 +1,76 @@
+/* pthread_key internal declatations for the Hurd version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <libc-lockP.h>
+
+#define PTHREAD_KEY_MEMBERS \
+  void **thread_specifics;		/* This is only resized by the thread, and always growing */ \
+  unsigned thread_specifics_size;	/* Number of entries in thread_specifics */
+
+#define PTHREAD_KEY_INVALID (void *) (-1)
+
+
+/* __PTHREAD_KEY_DESTRUCTORS is an array of destructors with
+   __PTHREAD_KEY_SIZE elements.  If an element with index less than
+   __PTHREAD_KEY_COUNT is invalid, it shall contain the value
+   PTHREAD_KEY_INVALID which shall be distinct from NULL.
+
+   Normally, we just add new keys to the end of the array and realloc
+   it as necessary.  The pthread_key_create routine may decide to
+   rescan the array if __PTHREAD_KEY_FREE is large.  */
+extern void (**__pthread_key_destructors) (void *arg);
+extern int __pthread_key_size;
+extern int __pthread_key_count;
+/* Number of invalid elements in the array.  Does not include elements
+   for which memory has been allocated but which have not yet been
+   used (i.e. those elements with indexes greater than
+   __PTHREAD_KEY_COUNT).  */
+extern int __pthread_key_invalid_count;
+
+/* Protects the above variables.  This must be a recursive lock: the
+   destructors may call pthread_key_delete.  */
+extern pthread_mutex_t __pthread_key_lock;
+
+#include <assert.h>
+
+static inline void
+__pthread_key_lock_ready (void)
+{
+  static pthread_once_t o = PTHREAD_ONCE_INIT;
+
+  void do_init (void)
+  {
+    int err;
+    pthread_mutexattr_t attr;
+
+    err = __pthread_mutexattr_init (&attr);
+    assert_perror (err);
+
+    err = __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+    assert_perror (err);
+
+    err = _pthread_mutex_init (&__pthread_key_lock, &attr);
+    assert_perror (err);
+
+    err = __pthread_mutexattr_destroy (&attr);
+    assert_perror (err);
+  }
+
+  __pthread_once (&o, do_init);
+}
diff --git a/sysdeps/htl/pt-kill.c b/sysdeps/htl/pt-kill.c
new file mode 100644
index 0000000000..7f7a39eb57
--- /dev/null
+++ b/sysdeps/htl/pt-kill.c
@@ -0,0 +1,33 @@
+/* pthread-kill.c - Generic pthread-kill implementation.
+   Copyright (C) 2008-2018 Free Software Foundation, Inc.
+   Written by Neal H. Walfield <neal@gnu.org>.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation; either version 3 of
+   the License, or (at your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <pthreadP.h>
+#include "sig-internal.h"
+
+int
+__pthread_kill (pthread_t tid, int signo)
+{
+  siginfo_t si;
+  memset (&si, 0, sizeof (si));
+  si.si_signo = signo;
+
+  return pthread_kill_siginfo_np (tid, si);
+}
+strong_alias (__pthread_kill, pthread_kill)
diff --git a/sysdeps/htl/pt-mutex-destroy.c b/sysdeps/htl/pt-mutex-destroy.c
new file mode 100644
index 0000000000..17b30838d0
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-destroy.c
@@ -0,0 +1,38 @@
+/* Destroy a mutex.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+_pthread_mutex_destroy (pthread_mutex_t *mutex)
+{
+  if (mutex->__attr == __PTHREAD_ERRORCHECK_MUTEXATTR
+      || mutex->__attr == __PTHREAD_RECURSIVE_MUTEXATTR)
+    /* Static attributes.  */
+    ;
+  else
+    free (mutex->__attr);
+
+  return 0;
+}
+
+strong_alias (_pthread_mutex_destroy, pthread_mutex_destroy);
diff --git a/sysdeps/htl/pt-mutex-getprioceiling.c b/sysdeps/htl/pt-mutex-getprioceiling.c
new file mode 100644
index 0000000000..66833b857f
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-getprioceiling.c
@@ -0,0 +1,28 @@
+/* Get a mutex' priority ceiling.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling)
+{
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutex_getprioceiling)
diff --git a/sysdeps/htl/pt-mutex-init.c b/sysdeps/htl/pt-mutex-init.c
new file mode 100644
index 0000000000..ee3ca9aec4
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-init.c
@@ -0,0 +1,48 @@
+/* Initialize a mutex.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+_pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+{
+  *mutex = (pthread_mutex_t) __PTHREAD_MUTEX_INITIALIZER;
+
+  if (attr == NULL
+      || memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0))
+    /* The default attributes.  */
+    return 0;
+
+  if (mutex->__attr == NULL
+      || mutex->__attr == __PTHREAD_ERRORCHECK_MUTEXATTR
+      || mutex->__attr == __PTHREAD_RECURSIVE_MUTEXATTR)
+    mutex->__attr = malloc (sizeof *attr);
+
+  if (mutex->__attr == NULL)
+    return ENOMEM;
+
+  *mutex->__attr = *attr;
+  return 0;
+}
+
+strong_alias (_pthread_mutex_init, pthread_mutex_init);
diff --git a/sysdeps/htl/pt-mutex-lock.c b/sysdeps/htl/pt-mutex-lock.c
new file mode 100644
index 0000000000..6a82627c0f
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-lock.c
@@ -0,0 +1,36 @@
+/* Lock a mutex.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+/* Implemented in pt-mutex-timedlock.c.  */
+extern int __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
+					       const struct timespec *abstime);
+
+/* Lock MUTEX, block if we can't get it.  */
+int
+__pthread_mutex_lock (struct __pthread_mutex *mutex)
+{
+  return __pthread_mutex_timedlock_internal (mutex, 0);
+}
+
+strong_alias (__pthread_mutex_lock, _pthread_mutex_lock);
+strong_alias (__pthread_mutex_lock, pthread_mutex_lock);
diff --git a/sysdeps/htl/pt-mutex-setprioceiling.c b/sysdeps/htl/pt-mutex-setprioceiling.c
new file mode 100644
index 0000000000..ea02188bf5
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-setprioceiling.c
@@ -0,0 +1,28 @@
+/* Set a mutex' priority ceiling.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prio, int *oldprio)
+{
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutex_setprioceiling)
diff --git a/sysdeps/htl/pt-mutex-timedlock.c b/sysdeps/htl/pt-mutex-timedlock.c
new file mode 100644
index 0000000000..2a64c53e9e
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-timedlock.c
@@ -0,0 +1,195 @@
+/* Lock a mutex with a timeout.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+#define LOSE do { * (int *) 0 = 0; } while (1)
+
+/* Try to lock MUTEX, block until *ABSTIME if it is already held.  As
+   a GNU extension, if TIMESPEC is NULL then wait forever.  */
+int
+__pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
+				    const struct timespec *abstime)
+{
+  error_t err;
+  int drain;
+  struct __pthread *self;
+  const struct __pthread_mutexattr *attr = mutex->__attr;
+
+  if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR)
+    attr = &__pthread_errorcheck_mutexattr;
+  if (attr == __PTHREAD_RECURSIVE_MUTEXATTR)
+    attr = &__pthread_recursive_mutexattr;
+
+  __pthread_spin_lock (&mutex->__lock);
+  if (__pthread_spin_trylock (&mutex->__held) == 0)
+    /* Successfully acquired the lock.  */
+    {
+#ifdef ALWAYS_TRACK_MUTEX_OWNER
+# ifndef NDEBUG
+      self = _pthread_self ();
+      if (self != NULL)
+	/* The main thread may take a lock before the library is fully
+	   initialized, in particular, before the main thread has a
+	   TCB.  */
+	{
+	  assert (mutex->__owner == NULL);
+	  mutex->__owner = _pthread_self ();
+	}
+# endif
+#endif
+
+      if (attr != NULL)
+	switch (attr->__mutex_type)
+	  {
+	  case PTHREAD_MUTEX_NORMAL:
+	    break;
+
+	  case PTHREAD_MUTEX_RECURSIVE:
+	    mutex->__locks = 1;
+	  case PTHREAD_MUTEX_ERRORCHECK:
+	    mutex->__owner = _pthread_self ();
+	    break;
+
+	  default:
+	    LOSE;
+	  }
+
+      __pthread_spin_unlock (&mutex->__lock);
+      return 0;
+    }
+
+  /* The lock is busy.  */
+
+  self = _pthread_self ();
+  assert (self);
+
+  if (attr == NULL || attr->__mutex_type == PTHREAD_MUTEX_NORMAL)
+    {
+#if defined(ALWAYS_TRACK_MUTEX_OWNER)
+      assert (mutex->__owner != self);
+#endif
+    }
+  else
+    {
+      switch (attr->__mutex_type)
+	{
+	case PTHREAD_MUTEX_ERRORCHECK:
+	  if (mutex->__owner == self)
+	    {
+	      __pthread_spin_unlock (&mutex->__lock);
+	      return EDEADLK;
+	    }
+	  break;
+
+	case PTHREAD_MUTEX_RECURSIVE:
+	  if (mutex->__owner == self)
+	    {
+	      mutex->__locks++;
+	      __pthread_spin_unlock (&mutex->__lock);
+	      return 0;
+	    }
+	  break;
+
+	default:
+	  LOSE;
+	}
+    }
+
+#if !defined(ALWAYS_TRACK_MUTEX_OWNER)
+  if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL)
+#endif
+    assert (mutex->__owner);
+
+  if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+    return EINVAL;
+
+  /* Add ourselves to the queue.  */
+  __pthread_enqueue (&mutex->__queue, self);
+  __pthread_spin_unlock (&mutex->__lock);
+
+  /* Block the thread.  */
+  if (abstime != NULL)
+    err = __pthread_timedblock (self, abstime, CLOCK_REALTIME);
+  else
+    {
+      err = 0;
+      __pthread_block (self);
+    }
+
+  __pthread_spin_lock (&mutex->__lock);
+  if (self->prevp == NULL)
+    /* Another thread removed us from the queue, which means a wakeup message
+       has been sent.  It was either consumed while we were blocking, or
+       queued after we timed out and before we acquired the mutex lock, in
+       which case the message queue must be drained.  */
+    drain = err ? 1 : 0;
+  else
+    {
+      /* We're still in the queue.  Noone attempted to wake us up, i.e. we
+         timed out.  */
+      __pthread_dequeue (self);
+      drain = 0;
+    }
+  __pthread_spin_unlock (&mutex->__lock);
+
+  if (drain)
+    __pthread_block (self);
+
+  if (err)
+    {
+      assert (err == ETIMEDOUT);
+      return err;
+    }
+
+#if !defined(ALWAYS_TRACK_MUTEX_OWNER)
+  if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL)
+#endif
+    {
+      assert (mutex->__owner == self);
+    }
+
+  if (attr != NULL)
+    switch (attr->__mutex_type)
+      {
+      case PTHREAD_MUTEX_NORMAL:
+	break;
+
+      case PTHREAD_MUTEX_RECURSIVE:
+	assert (mutex->__locks == 0);
+	mutex->__locks = 1;
+      case PTHREAD_MUTEX_ERRORCHECK:
+	mutex->__owner = self;
+	break;
+
+      default:
+	LOSE;
+      }
+
+  return 0;
+}
+
+int
+pthread_mutex_timedlock (struct __pthread_mutex *mutex,
+			 const struct timespec *abstime)
+{
+  return __pthread_mutex_timedlock_internal (mutex, abstime);
+}
diff --git a/sysdeps/htl/pt-mutex-transfer-np.c b/sysdeps/htl/pt-mutex-transfer-np.c
new file mode 100644
index 0000000000..e208ac1b58
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-transfer-np.c
@@ -0,0 +1,66 @@
+/* Transfer ownership of a mutex.  Generic version.
+   Copyright (C) 2008-2018 Free Software Foundation, Inc.
+   Written by Neal H. Walfield <neal@gnu.org>.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation; either version 3 of
+   the License, or (at your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_mutex_transfer_np (struct __pthread_mutex *mutex, pthread_t tid)
+{
+  assert (mutex->__owner == _pthread_self ());
+
+  struct __pthread *thread = __pthread_getid (tid);
+  const struct __pthread_mutexattr *attr = mutex->__attr;
+
+  if (thread == NULL)
+    return ESRCH;
+
+  if (thread == _pthread_self ())
+    return 0;
+
+  if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR)
+    attr = &__pthread_errorcheck_mutexattr;
+  if (attr == __PTHREAD_RECURSIVE_MUTEXATTR)
+    attr = &__pthread_recursive_mutexattr;
+
+  if (attr != NULL && attr->__mutex_type == PTHREAD_MUTEX_ERRORCHECK)
+    {
+
+      if (mutex->__owner != _pthread_self ())
+	return EPERM;
+
+      mutex->__owner = thread;
+    }
+
+#ifndef NDEBUG
+# if !defined(ALWAYS_TRACK_MUTEX_OWNER)
+  if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL)
+# endif
+    {
+      mutex->__owner = thread;
+    }
+#endif
+
+  return 0;
+}
+
+strong_alias (__pthread_mutex_transfer_np, pthread_mutex_transfer_np)
diff --git a/sysdeps/htl/pt-mutex-trylock.c b/sysdeps/htl/pt-mutex-trylock.c
new file mode 100644
index 0000000000..b19611b229
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-trylock.c
@@ -0,0 +1,111 @@
+/* Try to Lock a mutex.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+#define LOSE do { * (int *) 0 = 0; } while (1)
+
+/* Lock MUTEX, return EBUSY if we can't get it.  */
+int
+__pthread_mutex_trylock (struct __pthread_mutex *mutex)
+{
+  int err;
+  struct __pthread *self;
+  const struct __pthread_mutexattr *attr = mutex->__attr;
+
+  if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR)
+    attr = &__pthread_errorcheck_mutexattr;
+  if (attr == __PTHREAD_RECURSIVE_MUTEXATTR)
+    attr = &__pthread_recursive_mutexattr;
+
+  __pthread_spin_lock (&mutex->__lock);
+  if (__pthread_spin_trylock (&mutex->__held) == 0)
+    /* Acquired the lock.  */
+    {
+#if defined(ALWAYS_TRACK_MUTEX_OWNER)
+# ifndef NDEBUG
+      self = _pthread_self ();
+      if (self != NULL)
+	/* The main thread may take a lock before the library is fully
+	   initialized, in particular, before the main thread has a
+	   TCB.  */
+	{
+	  assert (mutex->__owner == NULL);
+	  mutex->__owner = _pthread_self ();
+	}
+# endif
+#endif
+
+      if (attr != NULL)
+	switch (attr->__mutex_type)
+	  {
+	  case PTHREAD_MUTEX_NORMAL:
+	    break;
+
+	  case PTHREAD_MUTEX_RECURSIVE:
+	    mutex->__locks = 1;
+	  case PTHREAD_MUTEX_ERRORCHECK:
+	    mutex->__owner = _pthread_self ();
+	    break;
+
+	  default:
+	    LOSE;
+	  }
+
+      __pthread_spin_unlock (&mutex->__lock);
+      return 0;
+    }
+
+  err = EBUSY;
+
+  if (attr != NULL)
+    {
+      self = _pthread_self ();
+      switch (attr->__mutex_type)
+	{
+	case PTHREAD_MUTEX_NORMAL:
+	  break;
+
+	case PTHREAD_MUTEX_ERRORCHECK:
+	  /* We could check if MUTEX->OWNER is SELF, however, POSIX
+	     does not permit pthread_mutex_trylock to return EDEADLK
+	     instead of EBUSY, only pthread_mutex_lock.  */
+	  break;
+
+	case PTHREAD_MUTEX_RECURSIVE:
+	  if (mutex->__owner == self)
+	    {
+	      mutex->__locks++;
+	      err = 0;
+	    }
+	  break;
+
+	default:
+	  LOSE;
+	}
+    }
+
+  __pthread_spin_unlock (&mutex->__lock);
+
+  return err;
+}
+
+strong_alias (__pthread_mutex_trylock, _pthread_mutex_trylock);
+strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock);
diff --git a/sysdeps/htl/pt-mutex-unlock.c b/sysdeps/htl/pt-mutex-unlock.c
new file mode 100644
index 0000000000..e46a913965
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-unlock.c
@@ -0,0 +1,107 @@
+/* Unlock a mutex.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+#define LOSE do { * (int *) 0 = 0; } while (1)
+
+/* Unlock MUTEX, rescheduling a waiting thread.  */
+int
+__pthread_mutex_unlock (pthread_mutex_t *mutex)
+{
+  struct __pthread *wakeup;
+  const struct __pthread_mutexattr *attr = mutex->__attr;
+
+  if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR)
+    attr = &__pthread_errorcheck_mutexattr;
+  if (attr == __PTHREAD_RECURSIVE_MUTEXATTR)
+    attr = &__pthread_recursive_mutexattr;
+
+  __pthread_spin_lock (&mutex->__lock);
+
+  if (attr == NULL || attr->__mutex_type == PTHREAD_MUTEX_NORMAL)
+    {
+#if defined(ALWAYS_TRACK_MUTEX_OWNER)
+# ifndef NDEBUG
+      if (_pthread_self ())
+	{
+	  assert (mutex->__owner);
+	  assert (mutex->__owner == _pthread_self ());
+	  mutex->__owner = NULL;
+	}
+# endif
+#endif
+    }
+  else
+    switch (attr->__mutex_type)
+      {
+      case PTHREAD_MUTEX_ERRORCHECK:
+      case PTHREAD_MUTEX_RECURSIVE:
+	if (mutex->__owner != _pthread_self ())
+	  {
+	    __pthread_spin_unlock (&mutex->__lock);
+	    return EPERM;
+	  }
+
+	if (attr->__mutex_type == PTHREAD_MUTEX_RECURSIVE)
+	  if (--mutex->__locks > 0)
+	    {
+	      __pthread_spin_unlock (&mutex->__lock);
+	      return 0;
+	    }
+
+	mutex->__owner = 0;
+	break;
+
+      default:
+	LOSE;
+      }
+
+
+  if (mutex->__queue == NULL)
+    {
+      __pthread_spin_unlock (&mutex->__held);
+      __pthread_spin_unlock (&mutex->__lock);
+      return 0;
+    }
+
+  wakeup = mutex->__queue;
+  __pthread_dequeue (wakeup);
+
+#ifndef NDEBUG
+# if !defined (ALWAYS_TRACK_MUTEX_OWNER)
+  if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL)
+# endif
+    {
+      mutex->__owner = wakeup;
+    }
+#endif
+
+  /* We do not unlock MUTEX->held: we are transferring the ownership
+     to the thread that we are waking up.  */
+
+  __pthread_spin_unlock (&mutex->__lock);
+  __pthread_wakeup (wakeup);
+
+  return 0;
+}
+
+strong_alias (__pthread_mutex_unlock, _pthread_mutex_unlock);
+strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock);
diff --git a/sysdeps/htl/pt-mutexattr-destroy.c b/sysdeps/htl/pt-mutexattr-destroy.c
new file mode 100644
index 0000000000..a43cf7d028
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-destroy.c
@@ -0,0 +1,27 @@
+/* pthread_mutexattr_destroy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
+{
+  return 0;
+}
+weak_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy)
diff --git a/sysdeps/htl/pt-mutexattr-getprioceiling.c b/sysdeps/htl/pt-mutexattr-getprioceiling.c
new file mode 100644
index 0000000000..9e13910afd
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-getprioceiling.c
@@ -0,0 +1,29 @@
+/* pthread_mutexattr_getprioceiling.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr,
+				  int *prioceiling)
+{
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutexattr_getprioceiling)
diff --git a/sysdeps/htl/pt-mutexattr-getprotocol.c b/sysdeps/htl/pt-mutexattr-getprotocol.c
new file mode 100644
index 0000000000..cef51d2073
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-getprotocol.c
@@ -0,0 +1,27 @@
+/* pthread_mutexattr_getprotocol.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr, int *protocol)
+{
+  *protocol = attr->__protocol;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-mutexattr-getpshared.c b/sysdeps/htl/pt-mutexattr-getpshared.c
new file mode 100644
index 0000000000..3afcb50918
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-getpshared.c
@@ -0,0 +1,27 @@
+/* pthread_mutexattr_getpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr, int *pshared)
+{
+  *pshared = attr->__pshared;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-mutexattr-gettype.c b/sysdeps/htl/pt-mutexattr-gettype.c
new file mode 100644
index 0000000000..aa5639c44e
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-gettype.c
@@ -0,0 +1,27 @@
+/* pthread_mutexattr_gettype.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)
+{
+  *type = attr->__mutex_type;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-mutexattr-init.c b/sysdeps/htl/pt-mutexattr-init.c
new file mode 100644
index 0000000000..bb90ce7221
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-init.c
@@ -0,0 +1,28 @@
+/* pthread_mutexattr_init.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_mutexattr_init (pthread_mutexattr_t *attr)
+{
+  *attr = __pthread_default_mutexattr;
+  return 0;
+}
+weak_alias (__pthread_mutexattr_init, pthread_mutexattr_init)
diff --git a/sysdeps/htl/pt-mutexattr-setprioceiling.c b/sysdeps/htl/pt-mutexattr-setprioceiling.c
new file mode 100644
index 0000000000..8a0f86f3fb
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-setprioceiling.c
@@ -0,0 +1,28 @@
+/* pthread_mutexattr_setprioceiling.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr, int prioceiling)
+{
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutexattr_setprioceiling)
diff --git a/sysdeps/htl/pt-mutexattr-setprotocol.c b/sysdeps/htl/pt-mutexattr-setprotocol.c
new file mode 100644
index 0000000000..ffd21c26d7
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-setprotocol.c
@@ -0,0 +1,40 @@
+/* pthread_mutexattr_setprotocol.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int protocol)
+{
+  if (protocol == __pthread_default_mutexattr.__protocol)
+    {
+      attr->__protocol = protocol;
+      return 0;
+    }
+
+  switch (protocol)
+    {
+    case PTHREAD_PRIO_NONE:
+    case PTHREAD_PRIO_INHERIT:
+    case PTHREAD_PRIO_PROTECT:
+      return ENOTSUP;
+    default:
+      return EINVAL;
+    }
+}
diff --git a/sysdeps/htl/pt-mutexattr-setpshared.c b/sysdeps/htl/pt-mutexattr-setpshared.c
new file mode 100644
index 0000000000..759def04f0
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-setpshared.c
@@ -0,0 +1,37 @@
+/* pthread_mutexattr_setpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
+{
+  switch (pshared)
+    {
+    case PTHREAD_PROCESS_PRIVATE:
+      attr->__pshared = pshared;
+      return 0;
+
+    case PTHREAD_PROCESS_SHARED:
+      return ENOTSUP;
+
+    default:
+      return EINVAL;
+    }
+}
diff --git a/sysdeps/htl/pt-mutexattr-settype.c b/sysdeps/htl/pt-mutexattr-settype.c
new file mode 100644
index 0000000000..9dc5ba01cd
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-settype.c
@@ -0,0 +1,37 @@
+/* pthread_mutexattr_settype.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
+{
+  switch (type)
+    {
+    case PTHREAD_MUTEX_NORMAL:
+    case PTHREAD_MUTEX_ERRORCHECK:
+    case PTHREAD_MUTEX_RECURSIVE:
+      attr->__mutex_type = type;
+      return 0;
+
+    default:
+      return EINVAL;
+    }
+}
+weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype)
diff --git a/sysdeps/htl/pt-mutexattr.c b/sysdeps/htl/pt-mutexattr.c
new file mode 100644
index 0000000000..ba55ebd7ad
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr.c
@@ -0,0 +1,41 @@
+/* Default mutex attributes.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+const struct __pthread_mutexattr __pthread_default_mutexattr = {
+  __prioceiling: 0,
+  __protocol: PTHREAD_PRIO_NONE,
+  __pshared: PTHREAD_PROCESS_PRIVATE,
+  __mutex_type: PTHREAD_MUTEX_DEFAULT
+};
+
+const struct __pthread_mutexattr __pthread_errorcheck_mutexattr = {
+  __prioceiling: 0,
+  __protocol: PTHREAD_PRIO_NONE,
+  __pshared: PTHREAD_PROCESS_PRIVATE,
+  __mutex_type: PTHREAD_MUTEX_ERRORCHECK
+};
+
+const struct __pthread_mutexattr __pthread_recursive_mutexattr = {
+  __prioceiling: 0,
+  __protocol: PTHREAD_PRIO_NONE,
+  __pshared: PTHREAD_PROCESS_PRIVATE,
+  __mutex_type: PTHREAD_MUTEX_RECURSIVE
+};
diff --git a/sysdeps/htl/pt-once.c b/sysdeps/htl/pt-once.c
new file mode 100644
index 0000000000..a3a139adc8
--- /dev/null
+++ b/sysdeps/htl/pt-once.c
@@ -0,0 +1,44 @@
+/* pthread_once.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <atomic.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+{
+  atomic_full_barrier ();
+  if (once_control->__run == 0)
+    {
+      __pthread_spin_lock (&once_control->__lock);
+
+      if (once_control->__run == 0)
+	{
+	  init_routine ();
+	  atomic_full_barrier ();
+	  once_control->__run = 1;
+	}
+
+      __pthread_spin_unlock (&once_control->__lock);
+    }
+
+  return 0;
+}
+strong_alias (__pthread_once, pthread_once);
diff --git a/sysdeps/htl/pt-rwlock-attr.c b/sysdeps/htl/pt-rwlock-attr.c
new file mode 100644
index 0000000000..a4814fc72c
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-attr.c
@@ -0,0 +1,24 @@
+/* Default rwlock attributes.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+const struct __pthread_rwlockattr __pthread_default_rwlockattr = {
+  __pshared: PTHREAD_PROCESS_PRIVATE
+};
diff --git a/sysdeps/htl/pt-rwlock-destroy.c b/sysdeps/htl/pt-rwlock-destroy.c
new file mode 100644
index 0000000000..8261a184c6
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-destroy.c
@@ -0,0 +1,28 @@
+/* Destroy a rwlock.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+_pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+  return 0;
+}
+
+strong_alias (_pthread_rwlock_destroy, pthread_rwlock_destroy);
diff --git a/sysdeps/htl/pt-rwlock-init.c b/sysdeps/htl/pt-rwlock-init.c
new file mode 100644
index 0000000000..0ef84320f9
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-init.c
@@ -0,0 +1,44 @@
+/* Initialize a rwlock.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <string.h>
+#include <pt-internal.h>
+
+int
+_pthread_rwlock_init (pthread_rwlock_t *rwlock,
+		      const pthread_rwlockattr_t *attr)
+{
+  *rwlock = (pthread_rwlock_t) __PTHREAD_RWLOCK_INITIALIZER;
+
+  if (attr == NULL
+      || memcmp (attr, &__pthread_default_rwlockattr, sizeof (*attr) == 0))
+    /* Use the default attributes.  */
+    return 0;
+
+  /* Non-default attributes.  */
+
+  rwlock->__attr = malloc (sizeof *attr);
+  if (rwlock->__attr == NULL)
+    return ENOMEM;
+
+  *rwlock->__attr = *attr;
+  return 0;
+}
+
+strong_alias (_pthread_rwlock_init, pthread_rwlock_init);
diff --git a/sysdeps/htl/pt-rwlock-rdlock.c b/sysdeps/htl/pt-rwlock-rdlock.c
new file mode 100644
index 0000000000..4592e1ae2c
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-rdlock.c
@@ -0,0 +1,34 @@
+/* Acquire a rwlock for reading.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+/* Implemented in pt-rwlock-timedrdlock.c.  */
+extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock
+						  *rwlock,
+						  const struct timespec
+						  *abstime);
+
+/* Acquire RWLOCK for reading, block if we can't get it.  */
+int
+__pthread_rwlock_rdlock (struct __pthread_rwlock *rwlock)
+{
+  return __pthread_rwlock_timedrdlock_internal (rwlock, 0);
+}
+weak_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock);
diff --git a/sysdeps/htl/pt-rwlock-timedrdlock.c b/sysdeps/htl/pt-rwlock-timedrdlock.c
new file mode 100644
index 0000000000..60dd97f28a
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-timedrdlock.c
@@ -0,0 +1,120 @@
+/* Acquire a rwlock for reading.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+/* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if
+   it is already held.  As a GNU extension, if TIMESPEC is NULL then
+   wait forever.  */
+int
+__pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
+				       const struct timespec *abstime)
+{
+  error_t err;
+  int drain;
+  struct __pthread *self;
+
+  __pthread_spin_lock (&rwlock->__lock);
+  if (__pthread_spin_trylock (&rwlock->__held) == 0)
+    /* Successfully acquired the lock.  */
+    {
+      assert (rwlock->__readerqueue == 0);
+      assert (rwlock->__writerqueue == 0);
+      assert (rwlock->__readers == 0);
+
+      rwlock->__readers = 1;
+      __pthread_spin_unlock (&rwlock->__lock);
+      return 0;
+    }
+  else
+    /* Lock is held, but is held by a reader?  */
+  if (rwlock->__readers > 0)
+    /* Just add ourself to number of readers.  */
+    {
+      assert (rwlock->__readerqueue == 0);
+      rwlock->__readers++;
+      __pthread_spin_unlock (&rwlock->__lock);
+      return 0;
+    }
+
+  /* The lock is busy.  */
+
+  /* Better be blocked by a writer.  */
+  assert (rwlock->__readers == 0);
+
+  if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+    return EINVAL;
+
+  self = _pthread_self ();
+
+  /* Add ourself to the queue.  */
+  __pthread_enqueue (&rwlock->__readerqueue, self);
+  __pthread_spin_unlock (&rwlock->__lock);
+
+  /* Block the thread.  */
+  if (abstime != NULL)
+    err = __pthread_timedblock (self, abstime, CLOCK_REALTIME);
+  else
+    {
+      err = 0;
+      __pthread_block (self);
+    }
+
+  __pthread_spin_lock (&rwlock->__lock);
+  if (self->prevp == NULL)
+    /* Another thread removed us from the queue, which means a wakeup message
+       has been sent.  It was either consumed while we were blocking, or
+       queued after we timed out and before we acquired the rwlock lock, in
+       which case the message queue must be drained.  */
+    drain = err ? 1 : 0;
+  else
+    {
+      /* We're still in the queue.  Noone attempted to wake us up, i.e. we
+         timed out.  */
+      __pthread_dequeue (self);
+      drain = 0;
+    }
+  __pthread_spin_unlock (&rwlock->__lock);
+
+  if (drain)
+    __pthread_block (self);
+
+  if (err)
+    {
+      assert (err == ETIMEDOUT);
+      return err;
+    }
+
+  /* The reader count has already been increment by whoever woke us
+     up.  */
+
+  assert (rwlock->__readers > 0);
+
+  return 0;
+}
+
+int
+__pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock,
+			      const struct timespec *abstime)
+{
+  return __pthread_rwlock_timedrdlock_internal (rwlock, abstime);
+}
+weak_alias (__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock)
diff --git a/sysdeps/htl/pt-rwlock-timedwrlock.c b/sysdeps/htl/pt-rwlock-timedwrlock.c
new file mode 100644
index 0000000000..b30c250d97
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-timedwrlock.c
@@ -0,0 +1,103 @@
+/* Acquire a rwlock for writing.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+/* Acquire RWLOCK for writing blocking until *ABSTIME if we cannot get
+   it.  As a special GNU extension, if ABSTIME is NULL then the wait
+   shall not time out.  */
+int
+__pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
+				       const struct timespec *abstime)
+{
+  error_t err;
+  int drain;
+  struct __pthread *self;
+
+  __pthread_spin_lock (&rwlock->__lock);
+  if (__pthread_spin_trylock (&rwlock->__held) == 0)
+    /* Successfully acquired the lock.  */
+    {
+      assert (rwlock->__readerqueue == 0);
+      assert (rwlock->__writerqueue == 0);
+      assert (rwlock->__readers == 0);
+
+      __pthread_spin_unlock (&rwlock->__lock);
+      return 0;
+    }
+
+  /* The lock is busy.  */
+
+  if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+    return EINVAL;
+
+  self = _pthread_self ();
+
+  /* Add ourselves to the queue.  */
+  __pthread_enqueue (&rwlock->__writerqueue, self);
+  __pthread_spin_unlock (&rwlock->__lock);
+
+  /* Block the thread.  */
+  if (abstime != NULL)
+    err = __pthread_timedblock (self, abstime, CLOCK_REALTIME);
+  else
+    {
+      err = 0;
+      __pthread_block (self);
+    }
+
+  __pthread_spin_lock (&rwlock->__lock);
+  if (self->prevp == NULL)
+    /* Another thread removed us from the queue, which means a wakeup message
+       has been sent.  It was either consumed while we were blocking, or
+       queued after we timed out and before we acquired the rwlock lock, in
+       which case the message queue must be drained.  */
+    drain = err ? 1 : 0;
+  else
+    {
+      /* We're still in the queue.  Noone attempted to wake us up, i.e. we
+         timed out.  */
+      __pthread_dequeue (self);
+      drain = 0;
+    }
+  __pthread_spin_unlock (&rwlock->__lock);
+
+  if (drain)
+    __pthread_block (self);
+
+  if (err)
+    {
+      assert (err == ETIMEDOUT);
+      return err;
+    }
+
+  assert (rwlock->__readers == 0);
+
+  return 0;
+}
+
+int
+__pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock,
+			      const struct timespec *abstime)
+{
+  return __pthread_rwlock_timedwrlock_internal (rwlock, abstime);
+}
+weak_alias (__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock)
diff --git a/sysdeps/htl/pt-rwlock-tryrdlock.c b/sysdeps/htl/pt-rwlock-tryrdlock.c
new file mode 100644
index 0000000000..39a368c7c1
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-tryrdlock.c
@@ -0,0 +1,55 @@
+/* Try to acquire a rwlock for reading.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+/* Try to acquire RWLOCK.  */
+int
+pthread_rwlock_tryrdlock (struct __pthread_rwlock *rwlock)
+{
+  __pthread_spin_lock (&rwlock->__lock);
+  if (__pthread_spin_trylock (&rwlock->__held) == 0)
+    /* Successfully acquired the lock.  */
+    {
+      assert (rwlock->__readerqueue == 0);
+      assert (rwlock->__writerqueue == 0);
+      assert (rwlock->__readers == 0);
+
+      rwlock->__readers = 1;
+      __pthread_spin_unlock (&rwlock->__lock);
+      return 0;
+    }
+  else
+    /* Lock is held, but is held by a reader?  */
+  if (rwlock->__readers > 0)
+    {
+      assert (rwlock->__readerqueue == 0);
+      rwlock->__readers++;
+      __pthread_spin_unlock (&rwlock->__lock);
+      return 0;
+    }
+
+  /* The lock is busy.  */
+
+  __pthread_spin_unlock (&rwlock->__lock);
+
+  return EBUSY;
+}
diff --git a/sysdeps/htl/pt-rwlock-trywrlock.c b/sysdeps/htl/pt-rwlock-trywrlock.c
new file mode 100644
index 0000000000..2f6f7b93ca
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-trywrlock.c
@@ -0,0 +1,45 @@
+/* Try to acquire a rwlock for writing.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+/* Try to acquire RWLOCK for writing.  */
+int
+pthread_rwlock_trywrlock (struct __pthread_rwlock *rwlock)
+{
+  __pthread_spin_lock (&rwlock->__lock);
+  if (__pthread_spin_trylock (&rwlock->__held) == 0)
+    /* Successfully acquired the lock.  */
+    {
+      assert (rwlock->__readerqueue == 0);
+      assert (rwlock->__writerqueue == 0);
+      assert (rwlock->__readers == 0);
+
+      __pthread_spin_unlock (&rwlock->__lock);
+      return 0;
+    }
+
+  /* The lock is busy.  */
+
+  __pthread_spin_unlock (&rwlock->__lock);
+
+  return EBUSY;
+}
diff --git a/sysdeps/htl/pt-rwlock-unlock.c b/sysdeps/htl/pt-rwlock-unlock.c
new file mode 100644
index 0000000000..9fd1aa87f6
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-unlock.c
@@ -0,0 +1,98 @@
+/* Unlock a rwlock.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+/* Unlock *RWLOCK, rescheduling a waiting writer thread or, if there
+   are no threads waiting for a write lock, rescheduling the reader
+   threads.  */
+int
+__pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+  struct __pthread *wakeup;
+
+  __pthread_spin_lock (&rwlock->__lock);
+
+  assert (__pthread_spin_trylock (&rwlock->__held) == EBUSY);
+
+  if (rwlock->__readers > 1)
+    /* There are other readers.  */
+    {
+      rwlock->__readers--;
+      __pthread_spin_unlock (&rwlock->__lock);
+      return 0;
+    }
+
+  if (rwlock->__readers == 1)
+    /* Last reader.  */
+    rwlock->__readers = 0;
+
+
+  /* Wake someone else up.  Try the writer queue first, then the
+     reader queue if that is empty.  */
+
+  if (rwlock->__writerqueue)
+    {
+      wakeup = rwlock->__writerqueue;
+      __pthread_dequeue (wakeup);
+
+      /* We do not unlock RWLOCK->held: we are transferring the ownership
+         to the thread that we are waking up.  */
+
+      __pthread_spin_unlock (&rwlock->__lock);
+      __pthread_wakeup (wakeup);
+
+      return 0;
+    }
+
+  if (rwlock->__readerqueue)
+    {
+      unsigned n = 0;
+
+      __pthread_queue_iterate (rwlock->__readerqueue, wakeup)
+	n++;
+
+      {
+	struct __pthread *wakeups[n];
+	unsigned i = 0;
+
+	__pthread_dequeuing_iterate (rwlock->__readerqueue, wakeup)
+	  wakeups[i++] = wakeup;
+
+	rwlock->__readers += n;
+	rwlock->__readerqueue = 0;
+
+	__pthread_spin_unlock (&rwlock->__lock);
+
+	for (i = 0; i < n; i++)
+	  __pthread_wakeup (wakeups[i]);
+      }
+
+      return 0;
+    }
+
+
+  /* Noone is waiting.  Just unlock it.  */
+
+  __pthread_spin_unlock (&rwlock->__held);
+  __pthread_spin_unlock (&rwlock->__lock);
+  return 0;
+}
+weak_alias (__pthread_rwlock_unlock, pthread_rwlock_unlock);
diff --git a/sysdeps/htl/pt-rwlock-wrlock.c b/sysdeps/htl/pt-rwlock-wrlock.c
new file mode 100644
index 0000000000..ed129a8349
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-wrlock.c
@@ -0,0 +1,36 @@
+/* Acquire a rwlock for writing.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+/* Implemented in pt-rwlock-timedwrlock.c.  */
+extern int __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock
+						  *rwlock,
+						  const struct timespec
+						  *abstime);
+
+/* Acquire RWLOCK for writing.  */
+int
+__pthread_rwlock_wrlock (struct __pthread_rwlock *rwlock)
+{
+  return __pthread_rwlock_timedwrlock_internal (rwlock, 0);
+}
+weak_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock);
diff --git a/sysdeps/htl/pt-rwlockattr-destroy.c b/sysdeps/htl/pt-rwlockattr-destroy.c
new file mode 100644
index 0000000000..218fe88f67
--- /dev/null
+++ b/sysdeps/htl/pt-rwlockattr-destroy.c
@@ -0,0 +1,26 @@
+/* pthread_rwlockattr_destroy.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr)
+{
+  return 0;
+}
diff --git a/sysdeps/htl/pt-rwlockattr-getpshared.c b/sysdeps/htl/pt-rwlockattr-getpshared.c
new file mode 100644
index 0000000000..09f57c688f
--- /dev/null
+++ b/sysdeps/htl/pt-rwlockattr-getpshared.c
@@ -0,0 +1,27 @@
+/* pthread_rwlockattr_getpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
+{
+  *pshared = attr->__pshared;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-rwlockattr-init.c b/sysdeps/htl/pt-rwlockattr-init.c
new file mode 100644
index 0000000000..6ba3a3df8b
--- /dev/null
+++ b/sysdeps/htl/pt-rwlockattr-init.c
@@ -0,0 +1,27 @@
+/* pthread_rwlockattr_init.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t *attr)
+{
+  *attr = __pthread_default_rwlockattr;
+  return 0;
+}
diff --git a/sysdeps/htl/pt-rwlockattr-setpshared.c b/sysdeps/htl/pt-rwlockattr-setpshared.c
new file mode 100644
index 0000000000..acb5ea4e0d
--- /dev/null
+++ b/sysdeps/htl/pt-rwlockattr-setpshared.c
@@ -0,0 +1,37 @@
+/* pthread_rwlockattr_setpshared.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
+{
+  switch (pshared)
+    {
+    case PTHREAD_PROCESS_PRIVATE:
+      attr->__pshared = pshared;
+      return 0;
+
+    case PTHREAD_PROCESS_SHARED:
+      return ENOTSUP;
+
+    default:
+      return EINVAL;
+    }
+}
diff --git a/sysdeps/htl/pt-setconcurrency.c b/sysdeps/htl/pt-setconcurrency.c
new file mode 100644
index 0000000000..3f05005a2b
--- /dev/null
+++ b/sysdeps/htl/pt-setconcurrency.c
@@ -0,0 +1,33 @@
+/* Set the desired level of concurrency.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int __pthread_concurrency;
+
+int
+pthread_setconcurrency (int new_level)
+{
+  if (new_level < 0)
+    return EINVAL;
+
+  __pthread_concurrency = new_level;
+
+  return 0;
+}
diff --git a/sysdeps/htl/pt-setschedparam.c b/sysdeps/htl/pt-setschedparam.c
new file mode 100644
index 0000000000..f8bce35943
--- /dev/null
+++ b/sysdeps/htl/pt-setschedparam.c
@@ -0,0 +1,30 @@
+/* Set the scheduling parameters for a thread.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+__pthread_setschedparam (pthread_t thread, int policy,
+			 const struct sched_param *param)
+{
+  return ENOSYS;
+}
+
+strong_alias (__pthread_setschedparam, pthread_setschedparam);
+stub_warning (pthread_setschedparam)
diff --git a/sysdeps/htl/pt-setschedprio.c b/sysdeps/htl/pt-setschedprio.c
new file mode 100644
index 0000000000..1d13cbd23b
--- /dev/null
+++ b/sysdeps/htl/pt-setschedprio.c
@@ -0,0 +1,28 @@
+/* Set the scheduling priority of a thread.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_setschedprio (pthread_t thread, int prio)
+{
+  return ENOSYS;
+}
+
+stub_warning (pthread_setschedprio)
diff --git a/sysdeps/htl/pt-setspecific.c b/sysdeps/htl/pt-setspecific.c
new file mode 100644
index 0000000000..8492b5dafa
--- /dev/null
+++ b/sysdeps/htl/pt-setspecific.c
@@ -0,0 +1,50 @@
+/* pthread_setspecific.  Generic version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_setspecific (pthread_key_t key, const void *value)
+{
+  struct __pthread *self = _pthread_self ();
+
+  if (key < 0 || key >= __pthread_key_count
+      || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID)
+    return EINVAL;
+
+  if (key >= self->thread_specifics_size)
+    {
+      /* Amortize reallocation cost.  */
+      int newsize = 2 * key + 1;
+      void **new = realloc (self->thread_specifics,
+			    newsize * sizeof (new[0]));
+      if (new == NULL)
+	return ENOMEM;
+
+      memset (&new[self->thread_specifics_size], 0,
+	      (newsize - self->thread_specifics_size) * sizeof (new[0]));
+      self->thread_specifics = new;
+      self->thread_specifics_size = newsize;
+    }
+
+  self->thread_specifics[key] = (void *) value;
+  return 0;
+}
+strong_alias (__pthread_setspecific, pthread_setspecific);
diff --git a/sysdeps/htl/pt-spin.c b/sysdeps/htl/pt-spin.c
new file mode 100644
index 0000000000..0840baba0a
--- /dev/null
+++ b/sysdeps/htl/pt-spin.c
@@ -0,0 +1,50 @@
+/* Spin locks.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <sched.h>
+
+/* The default for single processor machines; don't spin, it's
+   pointless.  */
+#ifndef __PTHREAD_SPIN_COUNT
+# define __PTHREAD_SPIN_COUNT 1
+#endif
+
+/* The number of times to spin while trying to lock a spin lock object
+   before yielding the processor. */
+int __pthread_spin_count = __PTHREAD_SPIN_COUNT;
+
+
+/* Lock the spin lock object LOCK.  If the lock is held by another
+   thread spin until it becomes available.  */
+int
+_pthread_spin_lock (__pthread_spinlock_t *lock)
+{
+  int i;
+
+  while (1)
+    {
+      for (i = 0; i < __pthread_spin_count; i++)
+	{
+	  if (__pthread_spin_trylock (lock) == 0)
+	    return 0;
+	}
+
+      __sched_yield ();
+    }
+}
diff --git a/sysdeps/htl/pt-startup.c b/sysdeps/htl/pt-startup.c
new file mode 100644
index 0000000000..dc3bc596c2
--- /dev/null
+++ b/sysdeps/htl/pt-startup.c
@@ -0,0 +1,24 @@
+/* Thread initialization.  Generic version.
+   Copyright (C) 2008-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pt-internal.h>
+
+void
+__pthread_startup (void)
+{
+}
diff --git a/sysdeps/htl/pthread-functions.h b/sysdeps/htl/pthread-functions.h
new file mode 100644
index 0000000000..a0d06cc039
--- /dev/null
+++ b/sysdeps/htl/pthread-functions.h
@@ -0,0 +1,140 @@
+/* Declaration of libc stubs for pthread functions.  Hurd version.
+   Copyright (C) 2003-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PTHREAD_FUNCTIONS_H
+#define _PTHREAD_FUNCTIONS_H	1
+
+#include <pthread.h>
+
+int __pthread_attr_destroy (pthread_attr_t *);
+int __pthread_attr_init (pthread_attr_t *);
+int __pthread_attr_getdetachstate (const pthread_attr_t *, int *);
+int __pthread_attr_setdetachstate (pthread_attr_t *, int);
+int __pthread_attr_getinheritsched (const pthread_attr_t *, int *);
+int __pthread_attr_setinheritsched (pthread_attr_t *, int);
+int __pthread_attr_getschedparam (const pthread_attr_t *,
+				 struct sched_param *);
+int __pthread_attr_setschedparam (pthread_attr_t *,
+				 const struct sched_param *);
+int __pthread_attr_getschedpolicy (const pthread_attr_t *, int *);
+int __pthread_attr_setschedpolicy (pthread_attr_t *, int);
+int __pthread_attr_getscope (const pthread_attr_t *, int *);
+int __pthread_attr_setscope (pthread_attr_t *, int);
+int __pthread_condattr_destroy (pthread_condattr_t *);
+int __pthread_condattr_init (pthread_condattr_t *);
+int __pthread_cond_broadcast (pthread_cond_t *);
+int __pthread_cond_destroy (pthread_cond_t *);
+int __pthread_cond_init (pthread_cond_t *,
+		       const pthread_condattr_t *);
+int __pthread_cond_signal (pthread_cond_t *);
+int __pthread_cond_wait (pthread_cond_t *, pthread_mutex_t *);
+int __pthread_cond_timedwait (pthread_cond_t *, pthread_mutex_t *,
+			     const struct timespec *);
+int __pthread_equal (pthread_t, pthread_t);
+void __pthread_exit (void *);
+int __pthread_getschedparam (pthread_t, int *, struct sched_param *);
+int __pthread_setschedparam (pthread_t, int,
+			    const struct sched_param *);
+int _pthread_mutex_destroy (pthread_mutex_t *);
+int _pthread_mutex_init (pthread_mutex_t *,
+			 const pthread_mutexattr_t *);
+int __pthread_mutex_lock (pthread_mutex_t *);
+int __pthread_mutex_trylock (pthread_mutex_t *);
+int __pthread_mutex_unlock (pthread_mutex_t *);
+pthread_t __pthread_self (void);
+int __pthread_setcancelstate (int, int *);
+int __pthread_setcanceltype (int, int *);
+struct __pthread_cancelation_handler **__pthread_get_cleanup_stack (void);
+int __pthread_once (pthread_once_t *, void (*) (void));
+int __pthread_rwlock_rdlock (pthread_rwlock_t *);
+int __pthread_rwlock_wrlock (pthread_rwlock_t *);
+int __pthread_rwlock_unlock (pthread_rwlock_t *);
+int __pthread_key_create (pthread_key_t *, void (*) (void *));
+void *__pthread_getspecific (pthread_key_t);
+int __pthread_setspecific (pthread_key_t, const void *);
+
+void _cthreads_flockfile (FILE *);
+void _cthreads_funlockfile (FILE *);
+int _cthreads_ftrylockfile (FILE *);
+
+/* Data type shared with libc.  The libc uses it to pass on calls to
+   the thread functions.  Wine pokes directly into this structure,
+   so if possible avoid breaking it and append new hooks to the end.  */
+struct pthread_functions
+{
+  int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
+  int (*ptr_pthread_attr_init) (pthread_attr_t *);
+  int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);
+  int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);
+  int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,
+					 struct sched_param *);
+  int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,
+					 const struct sched_param *);
+  int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);
+  int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);
+  int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);
+  int (*ptr_pthread_condattr_init) (pthread_condattr_t *);
+  int (*ptr_pthread_cond_broadcast) (pthread_cond_t *);
+  int (*ptr_pthread_cond_destroy) (pthread_cond_t *);
+  int (*ptr_pthread_cond_init) (pthread_cond_t *,
+			       const pthread_condattr_t *);
+  int (*ptr_pthread_cond_signal) (pthread_cond_t *);
+  int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
+  int (*ptr_pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
+				     const struct timespec *);
+  int (*ptr_pthread_equal) (pthread_t, pthread_t);
+  void (*ptr___pthread_exit) (void *);
+  int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
+  int (*ptr_pthread_setschedparam) (pthread_t, int,
+				    const struct sched_param *);
+  int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
+  int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
+				 const pthread_mutexattr_t *);
+  int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
+  int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *);
+  int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
+  pthread_t (*ptr_pthread_self) (void);
+  int (*ptr___pthread_setcancelstate) (int, int *);
+  int (*ptr_pthread_setcanceltype) (int, int *);
+  struct __pthread_cancelation_handler **(*ptr___pthread_get_cleanup_stack) (void);
+  int (*ptr_pthread_once) (pthread_once_t *, void (*) (void));
+  int (*ptr_pthread_rwlock_rdlock) (pthread_rwlock_t *);
+  int (*ptr_pthread_rwlock_wrlock) (pthread_rwlock_t *);
+  int (*ptr_pthread_rwlock_unlock) (pthread_rwlock_t *);
+  int (*ptr___pthread_key_create) (pthread_key_t *, void (*) (void *));
+  void *(*ptr___pthread_getspecific) (pthread_key_t);
+  int (*ptr___pthread_setspecific) (pthread_key_t, const void *);
+  void (*ptr__IO_flockfile) (FILE *);
+  void (*ptr__IO_funlockfile) (FILE *);
+  int (*ptr__IO_ftrylockfile) (FILE *);
+};
+
+/* Variable in libc.so.  */
+extern struct pthread_functions __libc_pthread_functions attribute_hidden;
+extern int __libc_pthread_functions_init attribute_hidden;
+
+void __libc_pthread_init (const struct pthread_functions *functions);
+
+#define PTHFCT_CALL(fct, params) \
+    __libc_pthread_functions.fct params
+
+#endif	/* pthread-functions.h */
diff --git a/sysdeps/htl/pthread.h b/sysdeps/htl/pthread.h
new file mode 100644
index 0000000000..91ab9b319a
--- /dev/null
+++ b/sysdeps/htl/pthread.h
@@ -0,0 +1,883 @@
+/* Posix threads.  Hurd version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+/*
+ *	POSIX Threads Extension: ???			<pthread.h>
+ */
+
+#ifndef _PTHREAD_H
+#define _PTHREAD_H	1
+
+#include <features.h>
+
+#include <sys/cdefs.h>
+#ifndef __extern_inline
+/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+   inline semantics, unless -fgnu89-inline is used.  */
+# if !defined __cplusplus || __GNUC_PREREQ (4,3)
+#  if defined __GNUC_STDC_INLINE__ || defined __cplusplus
+#   define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
+#   if __GNUC_PREREQ (4,3)
+#    define __extern_always_inline \
+   extern __always_inline __attribute__ ((__gnu_inline__, __artificial__))
+#   else
+#    define __extern_always_inline \
+   extern __always_inline __attribute__ ((__gnu_inline__))
+#   endif
+#  else
+#   define __extern_inline extern __inline
+#   define __extern_always_inline extern __always_inline
+#  endif
+# endif
+#endif
+
+#include <sched.h>
+#include <time.h>
+
+__BEGIN_DECLS
+
+#include <bits/pthreadtypes.h>
+
+#include <bits/pthread.h>
+
+/* Possible values for the process shared attribute.  */
+#define PTHREAD_PROCESS_PRIVATE __PTHREAD_PROCESS_PRIVATE
+#define PTHREAD_PROCESS_SHARED __PTHREAD_PROCESS_SHARED
+
+
+/* Thread attributes.  */
+
+/* Possible values for the inheritsched attribute.  */
+#define PTHREAD_EXPLICIT_SCHED __PTHREAD_EXPLICIT_SCHED
+#define PTHREAD_INHERIT_SCHED __PTHREAD_INHERIT_SCHED
+
+/* Possible values for the `contentionscope' attribute.  */
+#define PTHREAD_SCOPE_SYSTEM __PTHREAD_SCOPE_SYSTEM
+#define PTHREAD_SCOPE_PROCESS __PTHREAD_SCOPE_PROCESS
+
+/* Possible values for the `detachstate' attribute.  */
+#define PTHREAD_CREATE_JOINABLE __PTHREAD_CREATE_JOINABLE
+#define PTHREAD_CREATE_DETACHED __PTHREAD_CREATE_DETACHED
+
+#include <bits/types/struct___pthread_attr.h>
+
+/* Initialize the thread attribute object in *ATTR to the default
+   values.  */
+extern int pthread_attr_init (pthread_attr_t *__attr) __THROW __nonnull ((1));
+
+/* Destroy the thread attribute object in *ATTR.  */
+extern int pthread_attr_destroy (pthread_attr_t *__attr)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the inheritsched attribute in *ATTR in
+   *INHERITSCHED.  */
+extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict __attr,
+					 int *__restrict __inheritsched)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the inheritsched attribute in *ATTR to
+   INHERITSCHED.  */
+extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
+					 int __inheritsched)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the schedparam attribute in *ATTR in *PARAM.  */
+extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr,
+				       struct sched_param *__restrict __param)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the schedparam attribute in *ATTR to PARAM.  */
+extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
+				       const struct sched_param *__restrict
+				       __param) __THROW __nonnull ((1, 2));
+
+
+/* Return the value of the schedpolicy attribute in *ATTR to *POLICY.  */
+extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict __attr,
+					int *__restrict __policy)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the schedpolicy attribute in *ATTR to POLICY.  */
+extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr,
+					int __policy)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the contentionscope attribute in *ATTR in
+   *CONTENTIONSCOPE.  */
+extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr,
+				  int *__restrict __contentionscope)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the contentionscope attribute in *ATTR to
+   CONTENTIONSCOPE.  */
+extern int pthread_attr_setscope (pthread_attr_t *__attr,
+				  int __contentionscope)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the stackaddr attribute in *ATTR in
+   *STACKADDR.  */
+extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict __attr,
+				      void **__restrict __stackaddr)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the stackaddr attribute in *ATTR to STACKADDR.  */
+extern int pthread_attr_setstackaddr (pthread_attr_t *__attr,
+				      void *__stackaddr)
+	__THROW __nonnull ((1));
+
+
+#ifdef __USE_XOPEN2K
+/* Return the value of the stackaddr and stacksize attributes in *ATTR
+   in *STACKADDR and *STACKSIZE respectively.  */
+extern int pthread_attr_getstack (const pthread_attr_t *__restrict __attr,
+				  void **__restrict __stackaddr,
+				  size_t *__restrict __stacksize)
+	__THROW __nonnull ((1, 2, 3));
+
+/* Set the value of the stackaddr and stacksize attributes in *ATTR to
+   STACKADDR and STACKSIZE respectively.  */
+extern int pthread_attr_setstack (pthread_attr_t *__attr,
+				  void *__stackaddr,
+				  size_t __stacksize)
+	__THROW __nonnull ((1));
+#endif
+
+
+/* Return the value of the detachstate attribute in *ATTR in
+   *DETACHSTATE.  */
+extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr,
+					int *__detachstate)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the detachstate attribute in *ATTR to
+   DETACHSTATE.  */
+extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
+					int __detachstate)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the guardsize attribute in *ATTR in
+   *GUARDSIZE.  */
+extern int pthread_attr_getguardsize (const pthread_attr_t *__restrict __attr,
+				      size_t *__restrict __guardsize)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the guardsize attribute in *ATTR to GUARDSIZE.  */
+extern int pthread_attr_setguardsize (pthread_attr_t *__attr,
+				      size_t __guardsize)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the stacksize attribute in *ATTR in
+   *STACKSIZE.  */
+extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict __attr,
+				      size_t *__restrict __stacksize)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the stacksize attribute in *ATTR to STACKSIZE.  */
+extern int pthread_attr_setstacksize (pthread_attr_t *__attr,
+				      size_t __stacksize)
+	__THROW __nonnull ((1));
+
+#ifdef __USE_GNU
+/* Initialize thread attribute *ATTR with attributes corresponding to the
+   already running thread THREAD.  It shall be called on an uninitialized ATTR
+   and destroyed with pthread_attr_destroy when no longer needed.  */
+extern int pthread_getattr_np (pthread_t __thr, pthread_attr_t *__attr)
+	__THROW __nonnull ((2));
+#endif
+
+
+/* Create a thread with attributes given by ATTR, executing
+   START_ROUTINE with argument ARG.  */
+extern int pthread_create (pthread_t *__restrict __threadp,
+			   __const pthread_attr_t *__restrict __attr,
+			   void *(*__start_routine)(void *),
+			   void *__restrict __arg) __THROWNL __nonnull ((1, 3));
+
+/* Terminate the current thread and make STATUS available to any
+   thread that might join us.  */
+extern void pthread_exit (void *__status) __attribute__ ((__noreturn__));
+
+/* Make calling thread wait for termination of thread THREAD.  Return
+   the exit status of the thread in *STATUS.  */
+extern int pthread_join (pthread_t __threadp, void **__status);
+
+/* Indicate that the storage for THREAD can be reclaimed when it
+   terminates.  */
+extern int pthread_detach (pthread_t __threadp);
+
+/* Compare thread IDs T1 and T2.  Return nonzero if they are equal, 0
+   if they are not.  */
+extern int pthread_equal (pthread_t __t1, pthread_t __t2);
+
+#ifdef __USE_EXTERN_INLINES
+
+__extern_inline int
+pthread_equal (pthread_t __t1, pthread_t __t2)
+{
+  return __pthread_equal (__t1, __t2);
+}
+
+#endif /* Use extern inlines.  */
+
+
+/* Return the thread ID of the calling thread.  */
+extern pthread_t pthread_self (void) __THROW;
+
+
+/* Mutex attributes.  */
+
+#define PTHREAD_PRIO_NONE_NP __PTHREAD_PRIO_NONE
+#define PTHREAD_PRIO_INHERIT_NP __PTHREAD_PRIO_INHERIT
+#define PTHREAD_PRIO_PROTECT_NP __PTHREAD_PRIO_PROTECT
+#ifdef __USE_UNIX98
+# define PTHREAD_PRIO_NONE PTHREAD_PRIO_NONE_NP
+# define PTHREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT_NP
+# define PTHREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT_NP
+#endif
+
+#define PTHREAD_MUTEX_TIMED_NP __PTHREAD_MUTEX_TIMED
+#define PTHREAD_MUTEX_ERRORCHECK_NP __PTHREAD_MUTEX_ERRORCHECK
+#define PTHREAD_MUTEX_RECURSIVE_NP __PTHREAD_MUTEX_RECURSIVE
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
+# define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP
+# define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP
+# define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
+# define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
+#endif
+#ifdef __USE_GNU
+/* For compatibility.  */
+# define PTHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_TIMED_NP
+#endif
+
+#ifdef __USE_XOPEN2K
+# define PTHREAD_MUTEX_STALLED __PTHREAD_MUTEX_STALLED
+# define PTHREAD_MUTEX_ROBUST __PTHREAD_MUTEX_ROBUST
+#endif
+
+#include <bits/types/struct___pthread_mutexattr.h>
+
+/* Initialize the mutex attribute object in *ATTR to the default
+   values.  */
+extern int pthread_mutexattr_init(pthread_mutexattr_t *__attr)
+	__THROW __nonnull ((1));
+
+/* Destroy the mutex attribute structure in *ATTR.  */
+extern int pthread_mutexattr_destroy(pthread_mutexattr_t *__attr)
+	__THROW __nonnull ((1));
+
+
+#ifdef __USE_UNIX98
+/* Return the value of the prioceiling attribute in *ATTR in
+   *PRIOCEILING.  */
+extern int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict __attr,
+					    int *__restrict __prioceiling)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the prioceiling attribute in *ATTR to
+   PRIOCEILING.  */
+extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *__attr,
+					    int __prioceiling)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the protocol attribute in *ATTR in
+   *PROTOCOL.  */
+extern int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict __attr,
+					 int *__restrict __protocol)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the protocol attribute in *ATTR to PROTOCOL.  */
+extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *__attr,
+					 int __protocol)
+	__THROW __nonnull ((1));
+#endif
+
+#ifdef __USE_XOPEN2K
+/* Get the robustness flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr,
+					int *__robustness)
+     __THROW __nonnull ((1, 2));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr,
+					   int *__robustness)
+     __THROW __nonnull ((1, 2));
+# endif
+
+/* Set the robustness flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
+					int __robustness)
+     __THROW __nonnull ((1));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+					   int __robustness)
+     __THROW __nonnull ((1));
+# endif
+#endif
+
+
+/* Return the value of the process shared attribute in *ATTR in
+   *PSHARED.  */
+extern int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict __attr,
+					int *__restrict __pshared)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the process shared attribute in *ATTR to
+   PSHARED.  */
+extern int pthread_mutexattr_setpshared(pthread_mutexattr_t *__attr,
+					int __pshared)
+	__THROW __nonnull ((1));
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
+/* Return the value of the type attribute in *ATTR in *TYPE.  */
+extern int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict __attr,
+				     int *__restrict __type)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the type attribute in *ATTR to TYPE.  */
+extern int pthread_mutexattr_settype(pthread_mutexattr_t *__attr,
+				     int __type)
+	__THROW __nonnull ((1));
+#endif
+
+
+/* Mutexes.  */
+
+#include <bits/types/struct___pthread_mutex.h>
+
+#define PTHREAD_MUTEX_INITIALIZER __PTHREAD_MUTEX_INITIALIZER
+/* Static initializer for recursive mutexes.  */
+
+#ifdef __USE_GNU
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+  __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+  __PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+#endif
+
+/* Create a mutex with attributes given by ATTR and store it in
+   *__MUTEX.  */
+extern int pthread_mutex_init (struct __pthread_mutex *__restrict __mutex,
+			       const pthread_mutexattr_t *__restrict __attr)
+	__THROW __nonnull ((1));
+
+/* Destroy the mutex __MUTEX.  */
+extern int pthread_mutex_destroy (struct __pthread_mutex *__mutex)
+	__THROW __nonnull ((1));
+
+/* Wait until lock for MUTEX becomes available and lock it.  */
+extern int pthread_mutex_lock (pthread_mutex_t *__mutex);
+
+/* Try to lock MUTEX.  */
+extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
+	__THROWNL __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* Try to lock MUTEX, block until *ABSTIME if it is already held.  */
+extern int pthread_mutex_timedlock (struct __pthread_mutex *__restrict __mutex,
+				    const struct timespec *__restrict __abstime)
+	__THROWNL __nonnull ((1, 2));
+#endif
+
+/* Unlock MUTEX.  */
+extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
+	__THROWNL __nonnull ((1));
+
+/* Transfer ownership of the mutex MUTEX to the thread TID.  The
+   caller must own the lock.  */
+extern int __pthread_mutex_transfer_np (struct __pthread_mutex *__mutex,
+					pthread_t __tid)
+	__THROWNL __nonnull ((1));
+
+
+#ifdef __USE_UNIX98
+/* Return the priority ceiling of mutex *MUTEX in *PRIOCEILING.  */
+extern int pthread_mutex_getprioceiling (const pthread_mutex_t *__restrict __mutex,
+					 int *__restrict __prioceiling)
+	__THROW __nonnull ((1, 2));
+
+/* After acquiring the mutex *MUTEX, set its priority ceiling to PRIO
+   and return the old priority ceiling in *OLDPRIO.  Before returning,
+   release the mutex.  */
+extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex,
+					 int __prio, int *__restrict __oldprio)
+	__THROW __nonnull ((1, 3));
+#endif
+
+#ifdef __USE_XOPEN2K8
+
+/* Declare the state protected by robust mutex MTXP as consistent. */
+extern int pthread_mutex_consistent (pthread_mutex_t *__mtxp)
+  __THROW __nonnull ((1));
+
+#  ifdef __USE_GNU
+extern int pthread_mutex_consistent_np (pthread_mutex_t *__mtxp)
+  __THROW __nonnull ((1));
+#  endif
+#endif
+
+
+
+/* Condition attributes.  */
+
+#include <bits/types/struct___pthread_condattr.h>
+
+/* Initialize the condition attribute in *ATTR to the default
+   values.  */
+extern int pthread_condattr_init (pthread_condattr_t *__attr)
+	__THROW __nonnull ((1));
+
+/* Destroy the condition attribute structure in *ATTR.  */
+extern int pthread_condattr_destroy (pthread_condattr_t *__attr)
+	__THROW __nonnull ((1));
+
+
+#ifdef __USE_XOPEN2K
+/* Return the value of the clock attribute in *ATTR in *CLOCK_ID.  */
+extern int pthread_condattr_getclock (const pthread_condattr_t *__restrict __attr,
+				      __clockid_t *__restrict __clock_id)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the clock attribute in *ATTR to CLOCK_ID.  */
+extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
+				      __clockid_t __clock_id)
+	__THROW __nonnull ((1));
+#endif
+
+
+/* Return the value of the process shared attribute in *ATTR in
+   *PSHARED.  */
+extern int pthread_condattr_getpshared (const pthread_condattr_t *__restrict __attr,
+					int *__restrict __pshared)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the process shared attribute in *ATTR to
+   PSHARED.  */
+extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
+					int __pshared)
+	__THROW __nonnull ((1));
+
+
+/* Condition variables.  */
+
+#include <bits/types/struct___pthread_cond.h>
+
+#define PTHREAD_COND_INITIALIZER __PTHREAD_COND_INITIALIZER
+
+extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
+			      const pthread_condattr_t *__restrict __attr)
+	__THROW __nonnull ((1));
+
+extern int pthread_cond_destroy (pthread_cond_t *__cond)
+	__THROW __nonnull ((1));
+
+/* Unblock at least one of the threads that are blocked on condition
+   variable COND.  */
+extern int pthread_cond_signal (pthread_cond_t *__cond)
+	__THROWNL __nonnull ((1));
+
+/* Unblock all threads that are blocked on condition variable COND.  */
+extern int pthread_cond_broadcast (pthread_cond_t *__cond)
+	__THROWNL __nonnull ((1));
+
+/* Block on condition variable COND.  MUTEX should be held by the
+   calling thread.  On success, MUTEX will be held by the calling
+   thread.  */
+extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
+			      pthread_mutex_t *__restrict __mutex)
+	 __nonnull ((1, 2));
+
+/* Block on condition variable COND.  MUTEX should be held by the
+   calling thread. On success, MUTEX will be held by the calling
+   thread.  If the time specified by ABSTIME passes, ETIMEDOUT is
+   returned, and MUTEX will nevertheless be held.  */
+extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
+				   pthread_mutex_t *__restrict __mutex,
+				   __const struct timespec *__restrict __abstime)
+	 __nonnull ((1, 2, 3));
+
+
+/* Spin locks.  */
+
+#ifdef __USE_XOPEN2K
+
+# include <bits/types/__pthread_spinlock_t.h>
+
+# define PTHREAD_SPINLOCK_INITIALIZER __PTHREAD_SPIN_LOCK_INITIALIZER
+
+/* Destroy the spin lock object LOCK.  */
+extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
+	__nonnull ((1));
+
+/* Initialize the spin lock object LOCK.  PSHARED determines whether
+   the spin lock can be operated upon by multiple processes.  */
+extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
+	__nonnull ((1));
+
+/* Lock the spin lock object LOCK.  If the lock is held by another
+   thread spin until it becomes available.  */
+extern int pthread_spin_lock (pthread_spinlock_t *__lock)
+	__nonnull ((1));
+
+/* Lock the spin lock object LOCK.  Fail if the lock is held by
+   another thread.  */
+extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
+	__nonnull ((1));
+
+/* Unlock the spin lock object LOCK.  */
+extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
+	__nonnull ((1));
+
+# if defined __USE_EXTERN_INLINES && defined _LIBC
+
+# include <bits/spin-lock-inline.h>
+
+__extern_inline int
+pthread_spin_destroy (pthread_spinlock_t *__lock)
+{
+  return __pthread_spin_destroy (__lock);
+}
+
+__extern_inline int
+pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
+{
+  return __pthread_spin_init (__lock, __pshared);
+}
+
+__extern_inline int
+pthread_spin_lock (pthread_spinlock_t *__lock)
+{
+  return __pthread_spin_lock (__lock);
+}
+
+__extern_inline int
+pthread_spin_trylock (pthread_spinlock_t *__lock)
+{
+  return __pthread_spin_trylock (__lock);
+}
+
+__extern_inline int
+pthread_spin_unlock (pthread_spinlock_t *__lock)
+{
+  return __pthread_spin_unlock (__lock);
+}
+
+# endif /* Use extern inlines.  */
+
+#endif /* XPG6.  */
+
+
+/* rwlock attributes.  */
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+
+# include <bits/types/struct___pthread_rwlockattr.h>
+
+/* Initialize rwlock attribute object in *ATTR to the default
+   values.  */
+extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr)
+	__THROW __nonnull ((1));
+
+/* Destroy the rwlock attribute object in *ATTR.  */
+extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the process shared attribute in *ATTR in
+   *PSHARED.  */
+extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *__restrict __attr,
+					  int *__restrict __pshared)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the process shared atrribute in *ATTR to
+   PSHARED.  */
+extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr,
+					  int __pshared)
+	__THROW __nonnull ((1));
+
+/* Return current setting of reader/writer preference.  */
+extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *
+					  __restrict __attr,
+					  int *__restrict __pref)
+     __THROW __nonnull ((1, 2));
+
+/* Set reader/write preference.  */
+extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
+					  int __pref) __THROW __nonnull ((1));
+
+
+/* rwlocks.  */
+
+# include <bits/types/struct___pthread_rwlock.h>
+
+# define PTHREAD_RWLOCK_INITIALIZER __PTHREAD_RWLOCK_INITIALIZER
+/* Create a rwlock object with attributes given by ATTR and strore the
+   result in *RWLOCK.  */
+extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
+				const pthread_rwlockattr_t *__restrict __attr)
+	__THROW __nonnull ((1));
+
+/* Destroy the rwlock *RWLOCK.  */
+extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
+	__THROW __nonnull ((1));
+
+/* Acquire the rwlock *RWLOCK for reading.  */
+extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
+	__THROWNL __nonnull ((1));
+
+/* Acquire the rwlock *RWLOCK for reading.  */
+extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
+	__THROWNL __nonnull ((1));
+
+# ifdef __USE_XOPEN2K
+/* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if
+   it is already held.  */
+extern int pthread_rwlock_timedrdlock (struct __pthread_rwlock *__restrict __rwlock,
+				       const struct timespec *__restrict __abstime)
+	__THROWNL __nonnull ((1, 2));
+# endif
+
+/* Acquire the rwlock *RWLOCK for writing.  */
+extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
+	__THROWNL __nonnull ((1));
+
+/* Try to acquire the rwlock *RWLOCK for writing.  */
+extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
+	__THROWNL __nonnull ((1));
+
+# ifdef __USE_XOPEN2K
+/* Acquire the rwlock *RWLOCK for writing blocking until *ABSTIME if
+   it is already held.  */
+extern int pthread_rwlock_timedwrlock (struct __pthread_rwlock *__restrict __rwlock,
+				       const struct timespec *__restrict __abstime)
+	__THROWNL __nonnull ((1, 2));
+# endif
+
+/* Release the lock held by the current thread on *RWLOCK.  */
+extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
+	__THROWNL __nonnull ((1));
+
+#endif /* __USE_UNIX98 || __USE_XOPEN2K */
+
+
+
+/* Cancelation.  */
+
+/* Register a cleanup handler.  */
+extern void pthread_cleanup_push (void (*__routine) (void *), void *__arg);
+
+/* Unregister a cleanup handler.  */
+extern void pthread_cleanup_pop (int __execute);
+
+#include <bits/cancelation.h>
+
+#define pthread_cleanup_push(rt, rtarg) __pthread_cleanup_push(rt, rtarg)
+#define pthread_cleanup_pop(execute) __pthread_cleanup_pop(execute)
+
+#define PTHREAD_CANCEL_DISABLE 0
+#define PTHREAD_CANCEL_ENABLE 1
+
+/* Return the calling thread's cancelation state in *OLDSTATE and set
+   its state to STATE.  */
+extern int pthread_setcancelstate (int __state, int *__oldstate);
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+/* Return the calling thread's cancelation type in *OLDTYPE and set
+   its type to TYPE.  */
+extern int pthread_setcanceltype (int __type, int *__oldtype);
+
+/* Value returned by pthread_join if the target thread was
+   canceled.  */
+#define PTHREAD_CANCELED ((void *) -1)
+
+/* Cancel THEAD.  */
+extern int pthread_cancel (pthread_t __thr);
+
+/* Add an explicit cancelation point.  */
+extern void pthread_testcancel (void);
+
+
+/* Barriers attributes.  */
+
+#ifdef __USE_XOPEN2K
+
+# include <bits/types/struct___pthread_barrierattr.h>
+
+/* Initialize barrier attribute object in *ATTR to the default
+   values.  */
+extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr)
+	__THROW __nonnull ((1));
+
+/* Destroy the barrier attribute object in *ATTR.  */
+extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr)
+	__THROW __nonnull ((1));
+
+
+/* Return the value of the process shared attribute in *ATTR in
+   *PSHARED.  */
+extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *__restrict __attr,
+					   int *__restrict __pshared)
+	__THROW __nonnull ((1, 2));
+
+/* Set the value of the process shared atrribute in *ATTR to
+   PSHARED.  */
+extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
+					   int __pshared)
+	__THROW __nonnull ((1));
+
+
+/* Barriers.  */
+
+# include <bits/types/struct___pthread_barrier.h>
+
+/* Returned by pthread_barrier_wait to exactly one thread each time a
+   barrier is passed.  */
+# define PTHREAD_BARRIER_SERIAL_THREAD -1
+
+/* Initialize barrier BARRIER.  */
+extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier,
+				const pthread_barrierattr_t *__restrict __attr,
+				unsigned __count)
+	__THROW __nonnull ((1));
+
+/* Destroy barrier BARRIER.  */
+extern int pthread_barrier_destroy (pthread_barrier_t *__barrier)
+	__THROW __nonnull ((1));
+
+/* Wait on barrier BARRIER.  */
+extern int pthread_barrier_wait (pthread_barrier_t *__barrier)
+	__THROWNL __nonnull ((1));
+
+#endif /* __USE_XOPEN2K */
+
+
+
+/* Thread specific data.  */
+
+#include <bits/types/__pthread_key.h>
+
+/* Create a thread specific data key in KEY visible to all threads.
+   On thread destruction, DESTRUCTOR shall be called with the thread
+   specific data associate with KEY if it is not NULL.  */
+extern int pthread_key_create (pthread_key_t *__key,
+			       void (*__destructor) (void *))
+	__THROW __nonnull ((1));
+
+/* Delete the thread specific data key KEY.  The associated destructor
+   function is not called.  */
+extern int pthread_key_delete (pthread_key_t __key) __THROW;
+
+/* Return the caller thread's thread specific value of KEY.  */
+extern void *pthread_getspecific (pthread_key_t __key) __THROW;
+
+/* Set the caller thread's thread specific value of KEY to VALUE.  */
+extern int pthread_setspecific (pthread_key_t __key, const void *__value)
+	__THROW;
+
+
+/* Dynamic package initialization.  */
+
+#include <bits/types/struct___pthread_once.h>
+
+#define PTHREAD_ONCE_INIT __PTHREAD_ONCE_INIT
+
+/* Call INIT_ROUTINE if this function has never been called with
+   *ONCE_CONTROL, otherwise do nothing.  */
+extern int pthread_once (pthread_once_t *__once_control,
+			 void (*__init_routine) (void)) __nonnull ((1, 2));
+
+
+/* Concurrency.  */
+
+#ifdef __USE_UNIX98
+/* Set the desired concurrency level to NEW_LEVEL.  */
+extern int pthread_setconcurrency (int __new_level) __THROW;
+
+/* Get the current concurrency level.  */
+extern int pthread_getconcurrency (void) __THROW;
+#endif
+
+
+/* Forking.  */
+
+/* Register the function PREPARE to be run before the process forks,
+   the function PARENT to be run after a fork in the parent and the
+   function CHILD to be run in the child after the fork.  If no
+   handling is desired then any of PREPARE, PARENT and CHILD may be
+   NULL.  The prepare handles will be called in the reverse order
+   which they were registered and the parent and child handlers in the
+   order in which they were registered.  */
+extern int pthread_atfork (void (*__prepare) (void), void (*__parent) (void),
+			   void (*__child) (void)) __THROW;
+
+
+/* Signals (should be in <signal.h>).  */
+
+/* Send signal SIGNO to thread THREAD.  */
+extern int pthread_kill (pthread_t __thr, int __signo) __THROW;
+
+
+/* Time.  */
+
+#ifdef __USE_XOPEN2K
+/* Return the thread cpu clock.  */
+extern int pthread_getcpuclockid (pthread_t __thr, __clockid_t *__clock)
+	__THROW __nonnull ((2));
+#endif
+
+
+/* Scheduling.  */
+
+/* Return thread THREAD's scheduling paramters.  */
+extern int pthread_getschedparam (pthread_t __thr, int *__restrict __policy,
+				  struct sched_param *__restrict __param)
+	__THROW __nonnull ((2, 3));
+
+/* Set thread THREAD's scheduling paramters.  */
+extern int pthread_setschedparam (pthread_t __thr, int __policy,
+				  const struct sched_param *__param)
+	__THROW __nonnull ((3));
+
+/* Set thread THREAD's scheduling priority.  */
+extern int pthread_setschedprio (pthread_t __thr, int __prio) __THROW;
+
+#ifdef __USE_GNU
+/* Yield the processor to another thread or process.
+   This function is similar to the POSIX `sched_yield' function but
+   might be differently implemented in the case of a m-on-n thread
+   implementation.  */
+extern int pthread_yield (void) __THROW;
+#endif
+
+
+/* Kernel-specific interfaces.  */
+
+#include <bits/pthread-np.h>
+
+
+__END_DECLS
+
+#endif /* pthread.h */
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
new file mode 100644
index 0000000000..c37974945a
--- /dev/null
+++ b/sysdeps/htl/pthreadP.h
@@ -0,0 +1,46 @@
+/* Declarations of internal pthread functions used by libc.  Hurd version.
+   Copyright (C) 2016-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PTHREADP_H
+#define _PTHREADP_H	1
+
+#include <pthread.h>
+
+/* These represent the interface used by glibc itself.  */
+
+extern pthread_t __pthread_self (void);
+extern int __pthread_kill (pthread_t threadid, int signo);
+extern struct __pthread **__pthread_threads;
+
+extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
+
+typedef struct __cthread *__cthread_t;
+typedef int __cthread_key_t;
+typedef void *	(*__cthread_fn_t)(void *__arg);
+
+__cthread_t __cthread_fork (__cthread_fn_t, void *);
+void __cthread_detach (__cthread_t);
+int __cthread_keycreate (__cthread_key_t *);
+int __cthread_getspecific (__cthread_key_t, void **);
+int __cthread_setspecific (__cthread_key_t, void *);
+
+int __pthread_getattr_np (pthread_t, pthread_attr_t *);
+int __pthread_attr_getstack (const pthread_attr_t *, void **, size_t *);
+
+#endif	/* pthreadP.h */
diff --git a/sysdeps/htl/raise.c b/sysdeps/htl/raise.c
new file mode 100644
index 0000000000..d2f21c8a3f
--- /dev/null
+++ b/sysdeps/htl/raise.c
@@ -0,0 +1,51 @@
+/* raise.c - Generic raise implementation.
+   Copyright (C) 2008-2018 Free Software Foundation, Inc.
+   Written by Neal H. Walfield <neal@gnu.org>.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation; either version 3 of
+   the License, or (at your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <pthreadP.h>
+#include <signal.h>
+#include <unistd.h>
+
+#pragma weak __pthread_kill
+#pragma weak __pthread_self
+#pragma weak __pthread_threads
+int
+raise (int signo)
+{
+  /* According to POSIX, if we implement threads (and we do), then
+     "the effect of the raise() function shall be equivalent to
+     calling: pthread_kill(pthread_self(), sig);"  */
+
+  if (__pthread_kill != NULL && __pthread_threads != NULL)
+    {
+      int err;
+      err = __pthread_kill (__pthread_self (), signo);
+      if (err)
+	{
+	  errno = err;
+	  return -1;
+	}
+      return 0;
+    }
+  else
+    return __kill (__getpid (), signo);
+}
+
+libc_hidden_def (raise)
+weak_alias (raise, gsignal)
diff --git a/sysdeps/htl/sem-close.c b/sysdeps/htl/sem-close.c
new file mode 100644
index 0000000000..10a96ca836
--- /dev/null
+++ b/sysdeps/htl/sem-close.c
@@ -0,0 +1,31 @@
+/* Close a named semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <errno.h>
+
+#include <pt-internal.h>
+
+int
+__sem_close (sem_t *sem)
+{
+  errno = EOPNOTSUPP;
+  return -1;
+}
+
+strong_alias (__sem_close, sem_close);
diff --git a/sysdeps/htl/sem-destroy.c b/sysdeps/htl/sem-destroy.c
new file mode 100644
index 0000000000..c1c5bcb423
--- /dev/null
+++ b/sysdeps/htl/sem-destroy.c
@@ -0,0 +1,37 @@
+/* Destroy a semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <errno.h>
+
+#include <pt-internal.h>
+
+int
+__sem_destroy (sem_t *sem)
+{
+  if (sem->__queue)
+    /* There are threads waiting on *SEM.  */
+    {
+      errno = EBUSY;
+      return -1;
+    }
+
+  return 0;
+}
+
+strong_alias (__sem_destroy, sem_destroy);
diff --git a/sysdeps/htl/sem-getvalue.c b/sysdeps/htl/sem-getvalue.c
new file mode 100644
index 0000000000..2065458527
--- /dev/null
+++ b/sysdeps/htl/sem-getvalue.c
@@ -0,0 +1,32 @@
+/* Get the value of a semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <pt-internal.h>
+
+int
+__sem_getvalue (sem_t *restrict sem, int *restrict value)
+{
+  __pthread_spin_lock (&sem->__lock);
+  *value = sem->__value;
+  __pthread_spin_unlock (&sem->__lock);
+
+  return 0;
+}
+
+strong_alias (__sem_getvalue, sem_getvalue);
diff --git a/sysdeps/htl/sem-init.c b/sysdeps/htl/sem-init.c
new file mode 100644
index 0000000000..5faa8ef1a1
--- /dev/null
+++ b/sysdeps/htl/sem-init.c
@@ -0,0 +1,45 @@
+/* Initialize a semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <errno.h>
+
+#include <pt-internal.h>
+
+int
+__sem_init (sem_t *sem, int pshared, unsigned value)
+{
+  if (pshared != 0)
+    {
+      errno = EOPNOTSUPP;
+      return -1;
+    }
+
+#ifdef SEM_VALUE_MAX
+  if (value > SEM_VALUE_MAX)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+#endif
+
+  *sem = (sem_t) __SEMAPHORE_INITIALIZER (pshared, value);
+  return 0;
+}
+
+strong_alias (__sem_init, sem_init);
diff --git a/sysdeps/htl/sem-open.c b/sysdeps/htl/sem-open.c
new file mode 100644
index 0000000000..2d708f03fd
--- /dev/null
+++ b/sysdeps/htl/sem-open.c
@@ -0,0 +1,31 @@
+/* Open a named semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <errno.h>
+
+#include <pt-internal.h>
+
+sem_t *
+__sem_open (const char *name, int open_flags, ...)
+{
+  errno = EOPNOTSUPP;
+  return SEM_FAILED;
+}
+
+strong_alias (__sem_open, sem_open);
diff --git a/sysdeps/htl/sem-post.c b/sysdeps/htl/sem-post.c
new file mode 100644
index 0000000000..12cb36c85a
--- /dev/null
+++ b/sysdeps/htl/sem-post.c
@@ -0,0 +1,61 @@
+/* Post a semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+__sem_post (sem_t *sem)
+{
+  struct __pthread *wakeup;
+
+  __pthread_spin_lock (&sem->__lock);
+  if (sem->__value > 0)
+    /* Do a quick up.  */
+    {
+      assert (sem->__queue == NULL);
+      sem->__value++;
+      __pthread_spin_unlock (&sem->__lock);
+      return 0;
+    }
+
+  if (sem->__queue == NULL)
+    /* No one waiting.  */
+    {
+      sem->__value = 1;
+      __pthread_spin_unlock (&sem->__lock);
+      return 0;
+    }
+
+  /* Wake someone up.  */
+
+  /* First dequeue someone.  */
+  wakeup = sem->__queue;
+  __pthread_dequeue (wakeup);
+
+  /* Then drop the lock and transfer control.  */
+  __pthread_spin_unlock (&sem->__lock);
+
+  __pthread_wakeup (wakeup);
+
+  return 0;
+}
+
+strong_alias (__sem_post, sem_post);
diff --git a/sysdeps/htl/sem-timedwait.c b/sysdeps/htl/sem-timedwait.c
new file mode 100644
index 0000000000..54a4ea44a8
--- /dev/null
+++ b/sysdeps/htl/sem-timedwait.c
@@ -0,0 +1,98 @@
+/* Wait on a semaphore with a timeout.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <pt-internal.h>
+
+int
+__sem_timedwait_internal (sem_t *restrict sem,
+			  const struct timespec *restrict timeout)
+{
+  error_t err;
+  int drain;
+  struct __pthread *self;
+
+  __pthread_spin_lock (&sem->__lock);
+  if (sem->__value > 0)
+    /* Successful down.  */
+    {
+      sem->__value--;
+      __pthread_spin_unlock (&sem->__lock);
+      return 0;
+    }
+
+  if (timeout != NULL && (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  /* Add ourselves to the queue.  */
+  self = _pthread_self ();
+
+  __pthread_enqueue (&sem->__queue, self);
+  __pthread_spin_unlock (&sem->__lock);
+
+  /* Block the thread.  */
+  if (timeout != NULL)
+    err = __pthread_timedblock (self, timeout, CLOCK_REALTIME);
+  else
+    {
+      err = 0;
+      __pthread_block (self);
+    }
+
+  __pthread_spin_lock (&sem->__lock);
+  if (self->prevp == NULL)
+    /* Another thread removed us from the queue, which means a wakeup message
+       has been sent.  It was either consumed while we were blocking, or
+       queued after we timed out and before we acquired the semaphore lock, in
+       which case the message queue must be drained.  */
+    drain = err ? 1 : 0;
+  else
+    {
+      /* We're still in the queue.  Noone attempted to wake us up, i.e. we
+         timed out.  */
+      __pthread_dequeue (self);
+      drain = 0;
+    }
+  __pthread_spin_unlock (&sem->__lock);
+
+  if (drain)
+    __pthread_block (self);
+
+  if (err)
+    {
+      assert (err == ETIMEDOUT);
+      errno = err;
+      return -1;
+    }
+
+  return 0;
+}
+
+int
+__sem_timedwait (sem_t *restrict sem, const struct timespec *restrict timeout)
+{
+  return __sem_timedwait_internal (sem, timeout);
+}
+
+weak_alias (__sem_timedwait, sem_timedwait);
diff --git a/sysdeps/htl/sem-trywait.c b/sysdeps/htl/sem-trywait.c
new file mode 100644
index 0000000000..e84b08d414
--- /dev/null
+++ b/sysdeps/htl/sem-trywait.c
@@ -0,0 +1,41 @@
+/* Lock a semaphore if it does not require blocking.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <errno.h>
+
+#include <pt-internal.h>
+
+int
+__sem_trywait (sem_t *sem)
+{
+  __pthread_spin_lock (&sem->__lock);
+  if (sem->__value > 0)
+    /* Successful down.  */
+    {
+      sem->__value--;
+      __pthread_spin_unlock (&sem->__lock);
+      return 0;
+    }
+  __pthread_spin_unlock (&sem->__lock);
+
+  errno = EAGAIN;
+  return -1;
+}
+
+strong_alias (__sem_trywait, sem_trywait);
diff --git a/sysdeps/htl/sem-unlink.c b/sysdeps/htl/sem-unlink.c
new file mode 100644
index 0000000000..a5f6390124
--- /dev/null
+++ b/sysdeps/htl/sem-unlink.c
@@ -0,0 +1,31 @@
+/* Unlink a named semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <errno.h>
+
+#include <pt-internal.h>
+
+int
+__sem_unlink (const char *name)
+{
+  errno = EOPNOTSUPP;
+  return -1;
+}
+
+strong_alias (__sem_unlink, sem_unlink);
diff --git a/sysdeps/htl/sem-wait.c b/sysdeps/htl/sem-wait.c
new file mode 100644
index 0000000000..e45b0b1b89
--- /dev/null
+++ b/sysdeps/htl/sem-wait.c
@@ -0,0 +1,31 @@
+/* Wait on a semaphore.  Generic version.
+   Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <semaphore.h>
+#include <pt-internal.h>
+
+extern int __sem_timedwait_internal (sem_t *restrict sem,
+				     const struct timespec *restrict timeout);
+
+int
+__sem_wait (sem_t *sem)
+{
+  return __sem_timedwait_internal (sem, 0);
+}
+
+strong_alias (__sem_wait, sem_wait);
diff --git a/sysdeps/htl/shm-directory.h b/sysdeps/htl/shm-directory.h
new file mode 100644
index 0000000000..cddd5e5144
--- /dev/null
+++ b/sysdeps/htl/shm-directory.h
@@ -0,0 +1,30 @@
+/* Header for directory for shm/sem files.  libpthread version.
+   Copyright (C) 2014-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SHM_DIRECTORY_H
+
+#include <sysdeps/posix/shm-directory.h>
+
+/* For libpthread the __shm_directory function lives in libpthread.
+   We don't want PLT calls from there.  But it's also used from
+   librt, so it cannot just be declared hidden.  */
+
+#if IS_IN (libpthread)
+hidden_proto (__shm_directory)
+#endif
+#endif /* shm-directory.h */
diff --git a/sysdeps/htl/timer_routines.h b/sysdeps/htl/timer_routines.h
new file mode 100644
index 0000000000..a8134f510f
--- /dev/null
+++ b/sysdeps/htl/timer_routines.h
@@ -0,0 +1,46 @@
+/* Helper code for POSIX timer implementation on Hurd.
+   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TIMER_ROUTINES_H
+#define _TIMER_ROUTINES_H	1
+
+#include <bits/pthreadtypes.h>
+
+/* Compare two pthread_attr_t thread attributes for exact equality.
+   Returns 1 if they are equal, otherwise zero if they are not equal
+   or contain illegal values.  This version is Hurd-specific for
+   performance reason.  One could use the access functions to get the
+   values of all the fields of the attribute structure.  */
+static inline int
+thread_attr_compare (const pthread_attr_t * left, const pthread_attr_t * right)
+{
+  struct __pthread_attr *ileft = (struct __pthread_attr *) left;
+  struct __pthread_attr *iright = (struct __pthread_attr *) right;
+
+  return ileft->__schedparam.sched_priority
+	   == iright->__schedparam.sched_priority
+	 && ileft->__stackaddr == iright->__stackaddr
+	 && ileft->__stacksize == iright->__stacksize
+	 && ileft->__guardsize == iright->__guardsize
+	 && ileft->__detachstate == iright->__detachstate
+	 && ileft->__inheritsched == iright->__inheritsched
+	 && ileft->__contentionscope == iright->__contentionscope
+	 && ileft->__schedpolicy == iright->__schedpolicy;
+}
+
+#endif /* timer_routines.h */
diff --git a/sysdeps/hurd/htl/pt-kill.c b/sysdeps/hurd/htl/pt-kill.c
new file mode 100644
index 0000000000..5b72701426
--- /dev/null
+++ b/sysdeps/hurd/htl/pt-kill.c
@@ -0,0 +1,51 @@
+/* pthread_kill.  Hurd version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+#include <signal.h>
+#include <hurd/signal.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_kill (pthread_t thread, int sig)
+{
+  struct __pthread *pthread;
+  struct hurd_signal_detail detail;
+  struct hurd_sigstate *ss;
+
+  /* Lookup the thread structure for THREAD.  */
+  pthread = __pthread_getid (thread);
+  if (pthread == NULL)
+    return ESRCH;
+
+  ss = _hurd_thread_sigstate (pthread->kernel_thread);
+  assert (ss);
+
+  if (sig == 0)
+    return 0;
+
+  detail.exc = 0;
+  detail.code = sig;
+  detail.error = 0;
+
+  __spin_lock (&ss->lock);
+  return _hurd_raise_signal (ss, sig, &detail);
+}
+strong_alias (__pthread_kill, pthread_kill)
diff --git a/sysdeps/i386/htl/bits/pthreadtypes-arch.h b/sysdeps/i386/htl/bits/pthreadtypes-arch.h
new file mode 100644
index 0000000000..75ba63223f
--- /dev/null
+++ b/sysdeps/i386/htl/bits/pthreadtypes-arch.h
@@ -0,0 +1,22 @@
+/* Machine-specific pthread type layouts.  Hurd i386 version.
+   Copyright (C) 2002-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_PTHREADTYPES_ARCH_H
+#define _BITS_PTHREADTYPES_ARCH_H	1
+
+#endif /* bits/pthreadtypes.h */
diff --git a/sysdeps/i386/htl/machine-sp.h b/sysdeps/i386/htl/machine-sp.h
new file mode 100644
index 0000000000..8470f2fa97
--- /dev/null
+++ b/sysdeps/i386/htl/machine-sp.h
@@ -0,0 +1,29 @@
+/* Machine-specific function to return the stack pointer.  i386 version.
+   Copyright (C) 1994-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MACHINE_SP_H
+#define _MACHINE_SP_H
+
+/* Return the current stack pointer.  */
+
+#define __thread_stack_pointer() ({					      \
+  register void *__sp__ asm("esp");					      \
+  __sp__;								      \
+})
+
+#endif /* machine-sp.h */
diff --git a/sysdeps/i386/htl/pt-machdep.h b/sysdeps/i386/htl/pt-machdep.h
new file mode 100644
index 0000000000..bfb50aff15
--- /dev/null
+++ b/sysdeps/i386/htl/pt-machdep.h
@@ -0,0 +1,28 @@
+/* Machine dependent pthreads internal defenitions.  i386 version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PT_MACHDEP_H
+#define _PT_MACHDEP_H	1
+
+struct pthread_mcontext
+{
+  void *pc;
+  void *sp;
+};
+
+#endif /* pt-machdep.h */
diff --git a/sysdeps/mach/htl/Implies b/sysdeps/mach/htl/Implies
new file mode 100644
index 0000000000..5215f33d98
--- /dev/null
+++ b/sysdeps/mach/htl/Implies
@@ -0,0 +1 @@
+htl
diff --git a/sysdeps/mach/htl/bits/spin-lock-inline.h b/sysdeps/mach/htl/bits/spin-lock-inline.h
new file mode 100644
index 0000000000..695c6dccde
--- /dev/null
+++ b/sysdeps/mach/htl/bits/spin-lock-inline.h
@@ -0,0 +1,87 @@
+/* Definitions of user-visible names for spin locks.
+   Copyright (C) 1994-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_SPIN_LOCK_INLINE_H
+#define _BITS_SPIN_LOCK_INLINE_H	1
+
+#include <features.h>
+#include <bits/types/__pthread_spinlock_t.h>
+#include <lock-intern.h>   /* This does all the work.  */
+
+__BEGIN_DECLS
+
+#if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES
+
+# ifndef __EBUSY
+#  include <errno.h>
+#  define __EBUSY EBUSY
+# endif
+
+# ifndef __PT_SPIN_INLINE
+#  define __PT_SPIN_INLINE __extern_inline
+# endif
+
+__PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_destroy (__pthread_spinlock_t *__lock)
+{
+  return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock,
+					  int __pshared);
+
+__PT_SPIN_INLINE int
+__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared)
+{
+  *__lock = __PTHREAD_SPIN_LOCK_INITIALIZER;
+  return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_trylock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_trylock (__pthread_spinlock_t *__lock)
+{
+  return __spin_try_lock ((__spin_lock_t *) __lock) ? 0 : __EBUSY;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_lock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_lock (__pthread_spinlock_t *__lock)
+{
+  __spin_lock ((__spin_lock_t *) __lock);
+  return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_unlock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_unlock (__pthread_spinlock_t *__lock)
+{
+  __spin_unlock ((__spin_lock_t *) __lock);
+  return 0;
+}
+
+#endif /* Use extern inlines or force inlines.  */
+
+__END_DECLS
+
+#endif /* bits/types/__pthread_spinlock_t.h */
diff --git a/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h b/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h
new file mode 100644
index 0000000000..038e2b429c
--- /dev/null
+++ b/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h
@@ -0,0 +1,34 @@
+/* Definitions of user-visible names for spin locks.
+   Copyright (C) 1994-2018 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES___PTHREAD_SPINLOCK_T_H
+#define _BITS_TYPES___PTHREAD_SPINLOCK_T_H	1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* The type of a spin lock object.  */
+typedef volatile int __pthread_spinlock_t;
+
+/* Initializer for a spin lock object.  */
+#define __PTHREAD_SPIN_LOCK_INITIALIZER 0
+
+__END_DECLS
+
+#endif /* bits/types/__pthread_spinlock_t.h */
diff --git a/sysdeps/mach/htl/pt-block.c b/sysdeps/mach/htl/pt-block.c
new file mode 100644
index 0000000000..1ffda81f1f
--- /dev/null
+++ b/sysdeps/mach/htl/pt-block.c
@@ -0,0 +1,38 @@
+/* Block a thread.  Mach version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/message.h>
+
+#include <pt-internal.h>
+
+/* Block THREAD.  */
+void
+__pthread_block (struct __pthread *thread)
+{
+  mach_msg_header_t msg;
+  error_t err;
+
+  err = __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof msg,
+		    thread->wakeupmsg.msgh_remote_port,
+		    MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+  assert_perror (err);
+}
diff --git a/sysdeps/mach/htl/pt-spin.c b/sysdeps/mach/htl/pt-spin.c
new file mode 100644
index 0000000000..b2e00eab81
--- /dev/null
+++ b/sysdeps/mach/htl/pt-spin.c
@@ -0,0 +1,31 @@
+/* Spin locks.  Mach version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <machine-lock.h>
+
+/* In glibc.  */
+extern void __spin_lock_solid (__spin_lock_t *lock);
+
+/* Lock the spin lock object LOCK.  If the lock is held by another
+   thread spin until it becomes available.  */
+int
+_pthread_spin_lock (__spin_lock_t *lock)
+{
+  __spin_lock_solid (lock);
+  return 0;
+}
diff --git a/sysdeps/mach/htl/pt-stack-alloc.c b/sysdeps/mach/htl/pt-stack-alloc.c
new file mode 100644
index 0000000000..6c38c92f64
--- /dev/null
+++ b/sysdeps/mach/htl/pt-stack-alloc.c
@@ -0,0 +1,67 @@
+/* Allocate a new stack.  Mach version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/machine/vm_param.h>
+
+#include <pt-internal.h>
+
+/* The next address to use for stack allocation.  */
+static vm_address_t next_stack_base = VM_MIN_ADDRESS;
+
+
+/* Allocate a new stack of size STACKSIZE.  If successful, store the
+   address of the newly allocated stack in *STACKADDR and return 0.
+   Otherwise return an error code (EINVAL for an invalid stack size,
+   EAGAIN if the system lacked the necessary resources to allocate a
+   new stack).  */
+int
+__pthread_stack_alloc (void **stackaddr, size_t stacksize)
+{
+  vm_offset_t base;
+  int i = 0;
+
+get_stack:
+  i++;
+  for (base = next_stack_base;
+       base < VM_MAX_ADDRESS
+       && __vm_allocate (__mach_task_self (), &base,
+			 stacksize, FALSE) != KERN_SUCCESS; base += stacksize)
+    ;
+
+  if (base >= VM_MAX_ADDRESS)
+    {
+      if (i == 1)
+	{
+	  next_stack_base = VM_MIN_ADDRESS;
+	  goto get_stack;
+	}
+      else
+	return EAGAIN;
+    }
+
+  if (base >= VM_MAX_ADDRESS)
+    return EAGAIN;
+
+  next_stack_base = base + stacksize;
+
+  (*stackaddr) = (void *) base;
+  return 0;
+}
diff --git a/sysdeps/mach/htl/pt-thread-alloc.c b/sysdeps/mach/htl/pt-thread-alloc.c
new file mode 100644
index 0000000000..3c763ef7cb
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-alloc.c
@@ -0,0 +1,94 @@
+/* Start thread.  Mach version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <mach.h>
+
+#include <pt-internal.h>
+
+/* Prepare a wakeup message.  */
+static error_t
+create_wakeupmsg (struct __pthread *thread)
+{
+  kern_return_t err;
+
+  /* Build wakeup message.  */
+  thread->wakeupmsg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
+  thread->wakeupmsg.msgh_size = 0;
+
+  err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+			      &thread->wakeupmsg.msgh_remote_port);
+  if (err)
+    return EAGAIN;
+
+  thread->wakeupmsg.msgh_local_port = MACH_PORT_NULL;
+  thread->wakeupmsg.msgh_seqno = 0;
+  thread->wakeupmsg.msgh_id = 0;
+
+  err = __mach_port_insert_right (__mach_task_self (),
+				  thread->wakeupmsg.msgh_remote_port,
+				  thread->wakeupmsg.msgh_remote_port,
+				  MACH_MSG_TYPE_MAKE_SEND);
+  if (err)
+    {
+      __mach_port_destroy (__mach_task_self (),
+			   thread->wakeupmsg.msgh_remote_port);
+      return EAGAIN;
+    }
+
+  /* No need to queue more than one wakeup message on this port.  */
+  __mach_port_set_qlimit (__mach_task_self (),
+			  thread->wakeupmsg.msgh_remote_port, 1);
+
+  return 0;
+}
+
+/* Allocate any resouces for THREAD.  The new kernel thread should not
+   be eligible to be scheduled.  */
+int
+__pthread_thread_alloc (struct __pthread *thread)
+{
+  static int do_create;
+  error_t err;
+
+  err = create_wakeupmsg (thread);
+  if (err)
+    return err;
+
+  if (!do_create)
+    {
+      assert (__pthread_total == 0);
+      thread->kernel_thread = __mach_thread_self ();
+      do_create = 1;
+    }
+  else
+    {
+      err = __thread_create (__mach_task_self (), &thread->kernel_thread);
+      if (err)
+	{
+	  __mach_port_destroy (__mach_task_self (),
+			       thread->wakeupmsg.msgh_remote_port);
+	  return EAGAIN;
+	}
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/htl/pt-thread-start.c b/sysdeps/mach/htl/pt-thread-start.c
new file mode 100644
index 0000000000..571c1f2a62
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-start.c
@@ -0,0 +1,53 @@
+/* Start thread.  Mach version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <mach.h>
+
+#include <pt-internal.h>
+
+/* Start THREAD.  Get the kernel thread scheduled and running.  */
+int
+__pthread_thread_start (struct __pthread *thread)
+{
+  static int do_start;
+  error_t err;
+
+  if (!do_start)
+    {
+      /* The main thread is already running: do nothing.  */
+      assert (__pthread_total == 1);
+      assert ((
+		{
+		  mach_port_t ktid = __mach_thread_self ();
+		  int ok = thread->kernel_thread == ktid;
+		  __mach_port_deallocate (__mach_task_self (),
+					  thread->kernel_thread);
+		  ok;
+		}));
+      do_start = 1;
+    }
+  else
+    {
+      err = __thread_resume (thread->kernel_thread);
+      assert_perror (err);
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/htl/pt-thread-terminate.c b/sysdeps/mach/htl/pt-thread-terminate.c
new file mode 100644
index 0000000000..418fb400f5
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-terminate.c
@@ -0,0 +1,82 @@
+/* Deallocate the kernel thread resources.  Mach version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <mach.h>
+
+#include <mach/mig_support.h>
+
+#include <pt-internal.h>
+
+/* Terminate the kernel thread associated with THREAD, and deallocate its
+   right reference and its stack.  The function also drops a reference
+   on THREAD.  */
+void
+__pthread_thread_terminate (struct __pthread *thread)
+{
+  thread_t kernel_thread, self_ktid;
+  mach_port_t wakeup_port, reply_port;
+  void *stackaddr;
+  size_t stacksize;
+  error_t err;
+
+  kernel_thread = thread->kernel_thread;
+
+  if (thread->stack)
+    {
+      stackaddr = thread->stackaddr;
+      stacksize = ((thread->guardsize + __vm_page_size - 1)
+		   / __vm_page_size) * __vm_page_size + thread->stacksize;
+    }
+  else
+    {
+      stackaddr = NULL;
+      stacksize = 0;
+    }
+
+  wakeup_port = thread->wakeupmsg.msgh_remote_port;
+
+  /* Each thread has its own reply port, allocated from MiG stub code calling
+     __mig_get_reply_port.  Destroying it is a bit tricky because the calls
+     involved are also RPCs, causing the creation of a new reply port if
+     currently null. The __thread_terminate_release call is actually a one way
+     simple routine designed not to require a reply port.  */
+  self_ktid = __mach_thread_self ();
+  reply_port = (self_ktid == kernel_thread)
+      ? __mig_get_reply_port () : MACH_PORT_NULL;
+  __mach_port_deallocate (__mach_task_self (), self_ktid);
+
+  /* Finally done with the thread structure.  */
+  __pthread_dealloc (thread);
+
+  /* The wake up port is now no longer needed.  */
+  __mach_port_destroy (__mach_task_self (), wakeup_port);
+
+  /* Terminate and release all that's left.  */
+  err = __thread_terminate_release (kernel_thread, mach_task_self (),
+				    kernel_thread, reply_port,
+				    (vm_address_t) stackaddr, stacksize);
+
+  /* The kernel does not support it yet.  Leak but at least terminate
+     correctly.  */
+  err = __thread_terminate (kernel_thread);
+
+  /* We are out of luck.  */
+  assert_perror (err);
+}
diff --git a/sysdeps/mach/htl/pt-timedblock.c b/sysdeps/mach/htl/pt-timedblock.c
new file mode 100644
index 0000000000..4255f77397
--- /dev/null
+++ b/sysdeps/mach/htl/pt-timedblock.c
@@ -0,0 +1,65 @@
+/* Block a thread with a timeout.  Mach version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <mach.h>
+#include <mach/message.h>
+
+#include <pt-internal.h>
+
+/* Block THREAD.  */
+error_t
+__pthread_timedblock (struct __pthread *thread,
+		      const struct timespec *abstime, clockid_t clock_id)
+{
+  error_t err;
+  mach_msg_header_t msg;
+  mach_msg_timeout_t timeout;
+  struct timespec now;
+
+  /* We have an absolute time and now we have to convert it to a
+     relative time.  Arg.  */
+
+  err = clock_gettime (clock_id, &now);
+  assert (!err);
+
+  if (now.tv_sec > abstime->tv_sec
+      || (now.tv_sec == abstime->tv_sec && now.tv_nsec > abstime->tv_nsec))
+    return ETIMEDOUT;
+
+  timeout = (abstime->tv_sec - now.tv_sec) * 1000;
+
+  if (abstime->tv_nsec >= now.tv_nsec)
+    timeout += (abstime->tv_nsec - now.tv_nsec + 999999) / 1000000;
+  else
+    /* Need to do a carry.  */
+    timeout -= (now.tv_nsec - abstime->tv_nsec + 999999) / 1000000;
+
+  err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
+		    sizeof msg, thread->wakeupmsg.msgh_remote_port,
+		    timeout, MACH_PORT_NULL);
+  if (err == EMACH_RCV_TIMED_OUT)
+    return ETIMEDOUT;
+
+  assert_perror (err);
+  return 0;
+}
diff --git a/sysdeps/mach/htl/pt-wakeup.c b/sysdeps/mach/htl/pt-wakeup.c
new file mode 100644
index 0000000000..1e5488f14b
--- /dev/null
+++ b/sysdeps/mach/htl/pt-wakeup.c
@@ -0,0 +1,37 @@
+/* Wakeup a thread.  Mach version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/message.h>
+
+#include <pt-internal.h>
+
+/* Wakeup THREAD.  */
+void
+__pthread_wakeup (struct __pthread *thread)
+{
+  error_t err;
+
+  err = __mach_msg (&thread->wakeupmsg, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
+		    sizeof (thread->wakeupmsg), 0, MACH_PORT_NULL,
+		    0, MACH_PORT_NULL);
+  assert_perror (err);
+}
diff --git a/sysdeps/mach/hurd/htl/Implies b/sysdeps/mach/hurd/htl/Implies
new file mode 100644
index 0000000000..64daad184a
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/Implies
@@ -0,0 +1,2 @@
+hurd/htl
+mach/htl
diff --git a/sysdeps/mach/hurd/htl/bits/pthread-np.h b/sysdeps/mach/hurd/htl/bits/pthread-np.h
new file mode 100644
index 0000000000..0acee62186
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/bits/pthread-np.h
@@ -0,0 +1,37 @@
+/* Non-portable functions. Hurd on Mach version.
+   Copyright (C) 2008-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+/*
+ * Never include this file directly; use <pthread.h> or <cthreads.h> instead.
+ */
+
+#ifndef _BITS_PTHREAD_NP_H
+#define _BITS_PTHREAD_NP_H	1
+
+/* Same as pthread_cond_wait, but for Hurd-specific cancellation.
+   See hurd_thread_cancel.  */
+extern int pthread_hurd_cond_wait_np (pthread_cond_t *__restrict __cond,
+				      pthread_mutex_t *__restrict __mutex);
+
+/* Same as pthread_cond_timedwait, but for Hurd-specific cancellation.
+   See hurd_thread_cancel.  */
+extern int pthread_hurd_cond_timedwait_np (pthread_cond_t *__restrict __cond,
+					   pthread_mutex_t *__restrict __mutex,
+					   const struct timespec *__abstime);
+
+#endif /* bits/pthread-np.h */
diff --git a/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h b/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h
new file mode 100644
index 0000000000..4fe87cc5f5
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h
@@ -0,0 +1,49 @@
+/* Mutex type.  Generic version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H
+#define _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H	1
+
+#include <bits/types/struct___pthread_mutexattr.h>
+
+/* User visible part of a mutex.  */
+struct __pthread_mutex
+{
+  unsigned int __lock;
+  unsigned int __owner_id;
+  unsigned int __cnt;
+  int __shpid;
+  int __type;
+  int __flags;
+  unsigned int __reserved1;
+  unsigned int __reserved2;
+};
+
+/* Static mutex initializers. */
+#define __PTHREAD_MUTEX_INITIALIZER   \
+  { 0, 0, 0, 0, __PTHREAD_MUTEX_TIMED, 0, 0, 0 }
+
+/* The +1 is to mantain binary compatibility with the old
+ * libpthread implementation. */
+#define __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER   \
+  { 0, 0, 0, 0, __PTHREAD_MUTEX_ERRORCHECK + 1, 0, 0, 0 }
+
+#define __PTHREAD_RECURSIVE_MUTEX_INITIALIZER   \
+  { 0, 0, 0, 0, __PTHREAD_MUTEX_RECURSIVE + 1, 0, 0, 0 }
+
+#endif /* bits/types/struct___pthread_mutex.h */
diff --git a/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c b/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c
new file mode 100644
index 0000000000..711ae67043
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c
@@ -0,0 +1,27 @@
+/* pthread_attr_setstackaddr.  Hurd on Mach version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr)
+{
+  attr->__stackaddr = stackaddr;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c b/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c
new file mode 100644
index 0000000000..6a96370ebe
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c
@@ -0,0 +1,27 @@
+/* pthread_attr_setstacksize.  Hurd on Mach version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize)
+{
+  attr->__stacksize = stacksize;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-docancel.c b/sysdeps/mach/hurd/htl/pt-docancel.c
new file mode 100644
index 0000000000..a8bcb24cdb
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-docancel.c
@@ -0,0 +1,65 @@
+/* Cancel a thread.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+static void
+call_exit (void)
+{
+  pthread_exit (0);
+}
+
+int
+__pthread_do_cancel (struct __pthread *p)
+{
+  mach_port_t ktid;
+  int me;
+
+  assert (p->cancel_pending == 1);
+  assert (p->cancel_state == PTHREAD_CANCEL_ENABLE);
+
+  __pthread_mutex_unlock (&p->cancel_lock);
+
+  ktid = __mach_thread_self ();
+  me = p->kernel_thread == ktid;
+  __mach_port_deallocate (__mach_task_self (), ktid);
+
+  if (me)
+    call_exit ();
+  else
+    {
+      error_t err;
+
+      err = __thread_suspend (p->kernel_thread);
+      assert_perror (err);
+
+      err = __thread_abort (p->kernel_thread);
+      assert_perror (err);
+
+      err = __thread_set_pcsptp (p->kernel_thread,
+				 1, (void *) call_exit, 0, 0, 0, 0);
+      assert_perror (err);
+
+      err = __thread_resume (p->kernel_thread);
+      assert_perror (err);
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
new file mode 100644
index 0000000000..41792e3711
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
@@ -0,0 +1,169 @@
+/* pthread_hurd_cond_timedwait_np.  Hurd-specific wait on a condition.
+   Copyright (C) 2012-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+#include <hurd/signal.h>
+
+#include <pt-internal.h>
+
+extern int __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
+						   pthread_mutex_t *mutex,
+						   const struct timespec
+						   *abstime);
+
+int
+__pthread_hurd_cond_timedwait_np (pthread_cond_t *cond,
+				  pthread_mutex_t *mutex,
+				  const struct timespec *abstime)
+{
+  return __pthread_hurd_cond_timedwait_internal (cond, mutex, abstime);
+}
+
+strong_alias (__pthread_hurd_cond_timedwait_np, pthread_hurd_cond_timedwait_np);
+
+int
+__pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
+					pthread_mutex_t *mutex,
+					const struct timespec *abstime)
+{
+  struct hurd_sigstate *ss = _hurd_self_sigstate ();
+  struct __pthread *self = _pthread_self ();
+  error_t err = 0;
+  int cancel, drain;
+  clockid_t clock_id = __pthread_default_condattr.__clock;
+
+  /* This function will be called by hurd_thread_cancel while we are blocked
+     We wake up our thread if it's still blocking or about to block, so it will
+     progress and notice the cancellation flag.  */
+  void cancel_me (void)
+  {
+    int unblock;
+
+    __pthread_spin_lock (&cond->__lock);
+    /* The thread only needs to be awaken if it's blocking or about to block.
+       If it was already unblocked, it's not queued any more.  */
+    unblock = self->prevp != NULL;
+    if (unblock)
+      __pthread_dequeue (self);
+    __pthread_spin_unlock (&cond->__lock);
+
+    if (unblock)
+      __pthread_wakeup (self);
+  }
+
+  assert (ss->intr_port == MACH_PORT_NULL);	/* Sanity check for signal bugs. */
+
+  if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+    return EINVAL;
+
+  /* Atomically enqueue our thread on the condition variable's queue of
+     waiters, and mark our sigstate to indicate that `cancel_me' must be
+     called to wake us up.  We must hold the sigstate lock while acquiring
+     the condition variable's lock and tweaking it, so that
+     hurd_thread_cancel can never suspend us and then deadlock waiting for
+     the condition variable's lock.  */
+
+  __spin_lock (&ss->lock);
+  __pthread_spin_lock (&cond->__lock);
+  cancel = ss->cancel;
+  if (cancel)
+    /* We were cancelled before doing anything.  Don't block at all.  */
+    ss->cancel = 0;
+  else
+    {
+      /* Put us on the queue so that pthread_cond_broadcast will know to wake
+         us up.  */
+      __pthread_enqueue (&cond->__queue, self);
+      if (cond->__attr)
+	clock_id = cond->__attr->__clock;
+      /* Tell hurd_thread_cancel how to unblock us.  */
+      ss->cancel_hook = &cancel_me;
+    }
+  __pthread_spin_unlock (&cond->__lock);
+  __spin_unlock (&ss->lock);
+
+  if (cancel)
+    {
+      /* Cancelled on entry.  Just leave the mutex locked.  */
+      mutex = NULL;
+
+      __spin_lock (&ss->lock);
+    }
+  else
+    {
+      /* Release MUTEX before blocking.  */
+      __pthread_mutex_unlock (mutex);
+
+      /* Block the thread.  */
+      if (abstime != NULL)
+	err = __pthread_timedblock (self, abstime, clock_id);
+      else
+	{
+	  err = 0;
+	  __pthread_block (self);
+	}
+
+      /* As it was done when enqueueing, prevent hurd_thread_cancel from
+         suspending us while the condition lock is held.  */
+      __spin_lock (&ss->lock);
+      __pthread_spin_lock (&cond->__lock);
+      if (self->prevp == NULL)
+	/* Another thread removed us from the list of waiters, which means
+	   a wakeup message has been sent.  It was either consumed while
+	   we were blocking, or queued after we timed out and before we
+	   acquired the condition lock, in which case the message queue
+	   must be drained.  */
+	drain = err ? 1 : 0;
+      else
+	{
+	  /* We're still in the list of waiters.  Noone attempted to wake us
+	     up, i.e. we timed out.  */
+	  __pthread_dequeue (self);
+	  drain = 0;
+	}
+      __pthread_spin_unlock (&cond->__lock);
+
+      if (drain)
+	__pthread_block (self);
+    }
+
+  /* Clear the hook, now that we are done blocking.  */
+  ss->cancel_hook = NULL;
+  /* Check the cancellation flag; we might have unblocked due to
+     cancellation rather than a normal pthread_cond_signal or
+     pthread_cond_broadcast (or we might have just happened to get cancelled
+     right after waking up).  */
+  cancel |= ss->cancel;
+  ss->cancel = 0;
+  __spin_unlock (&ss->lock);
+
+  if (mutex != NULL)
+    /* Reacquire the mutex and return.  */
+    __pthread_mutex_lock (mutex);
+
+  if (cancel)
+    return EINTR;
+  else if (err)
+    {
+      assert (err == ETIMEDOUT);
+      return err;
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c
new file mode 100644
index 0000000000..2f2b6c293f
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c
@@ -0,0 +1,40 @@
+/* pthread_hurd_cond_wait.  Hurd-specific wait on a condition.
+   Copyright (C) 2012-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+#include <hurd/signal.h>
+
+#include <pt-internal.h>
+
+/* Implemented in pt-hurd-cond-timedwait.c.  */
+extern int __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
+						   pthread_mutex_t *mutex,
+						   const struct timespec
+						   *abstime);
+
+int
+__pthread_hurd_cond_wait_np (pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+  error_t err;
+
+  err = __pthread_hurd_cond_timedwait_internal (cond, mutex, NULL);
+  return err == EINTR;
+}
+
+strong_alias (__pthread_hurd_cond_wait_np, pthread_hurd_cond_wait_np);
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-consistent.c b/sysdeps/mach/hurd/htl/pt-mutex-consistent.c
new file mode 100644
index 0000000000..9fd6342be4
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-consistent.c
@@ -0,0 +1,48 @@
+/* pthread_mutex_consistent.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_consistent (pthread_mutex_t *mtxp)
+{
+  int ret = EINVAL;
+  unsigned int val = mtxp->__lock;
+
+  if ((mtxp->__flags & PTHREAD_MUTEX_ROBUST) != 0 &&
+      (val & LLL_DEAD_OWNER) != 0 &&
+      atomic_compare_and_exchange_bool_acq (&mtxp->__lock,
+					    __getpid () | LLL_WAITERS,
+					    val) == 0)
+    {
+      /* The mutex is now ours, and it's consistent. */
+      mtxp->__owner_id = _pthread_self ()->thread;
+      mtxp->__cnt = 1;
+      ret = 0;
+    }
+
+  return ret;
+}
+
+weak_alias (pthread_mutex_consistent, pthread_mutex_consistent_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-destroy.c b/sysdeps/mach/hurd/htl/pt-mutex-destroy.c
new file mode 100644
index 0000000000..89b4916eb6
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-destroy.c
@@ -0,0 +1,38 @@
+/* pthread_mutex_destroy.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+_pthread_mutex_destroy (pthread_mutex_t *mtxp)
+{
+  atomic_read_barrier ();
+  if (*(volatile unsigned int *) &mtxp->__lock != 0)
+    return EBUSY;
+
+  mtxp->__type = -1;
+  return 0;
+}
+
+strong_alias (_pthread_mutex_destroy, pthread_mutex_destroy)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c
new file mode 100644
index 0000000000..fa6b82b667
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c
@@ -0,0 +1,35 @@
+/* pthread_mutex_getprioceiling.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_getprioceiling (const pthread_mutex_t *mtxp, int *clp)
+{
+  (void) mtxp;
+  (void) clp;
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutex_getprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-init.c b/sysdeps/mach/hurd/htl/pt-mutex-init.c
new file mode 100644
index 0000000000..8218eb150e
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-init.c
@@ -0,0 +1,56 @@
+/* pthread_mutex_init.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+static const pthread_mutexattr_t dfl_attr = {
+  .__prioceiling = 0,
+  .__protocol = PTHREAD_PRIO_NONE,
+  .__pshared = PTHREAD_PROCESS_PRIVATE,
+  .__mutex_type = __PTHREAD_MUTEX_TIMED
+};
+
+int
+_pthread_mutex_init (pthread_mutex_t *mtxp, const pthread_mutexattr_t *attrp)
+{
+  if (attrp == NULL)
+    attrp = &dfl_attr;
+
+  mtxp->__flags = (attrp->__pshared == PTHREAD_PROCESS_SHARED ?
+		   GSYNC_SHARED : 0) | ((attrp->
+					 __prioceiling & PTHREAD_MUTEX_ROBUST) ?
+					PTHREAD_MUTEX_ROBUST : 0);
+
+  mtxp->__type = attrp->__mutex_type +
+      (attrp->__mutex_type != __PTHREAD_MUTEX_TIMED);
+
+  mtxp->__owner_id = 0;
+  mtxp->__shpid = 0;
+  mtxp->__cnt = 0;
+  mtxp->__lock = 0;
+
+  return 0;
+}
+
+strong_alias (_pthread_mutex_init, pthread_mutex_init)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-lock.c b/sysdeps/mach/hurd/htl/pt-mutex-lock.c
new file mode 100644
index 0000000000..e4a86f0e49
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-lock.c
@@ -0,0 +1,81 @@
+/* pthread_mutex_lock.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_lock (pthread_mutex_t *mtxp)
+{
+  struct __pthread *self;
+  int flags = mtxp->__flags & GSYNC_SHARED;
+  int ret = 0;
+
+  switch (MTX_TYPE (mtxp))
+    {
+    case PT_MTX_NORMAL:
+      lll_lock (&mtxp->__lock, flags);
+      break;
+
+    case PT_MTX_RECURSIVE:
+      self = _pthread_self ();
+      if (mtx_owned_p (mtxp, self, flags))
+	{
+	  if (__glibc_unlikely (mtxp->__cnt + 1 == 0))
+	    return EAGAIN;
+
+	  ++mtxp->__cnt;
+	  return ret;
+	}
+
+      lll_lock (&mtxp->__lock, flags);
+      mtx_set_owner (mtxp, self, flags);
+      mtxp->__cnt = 1;
+      break;
+
+    case PT_MTX_ERRORCHECK:
+      self = _pthread_self ();
+      if (mtx_owned_p (mtxp, self, flags))
+	return EDEADLK;
+
+      lll_lock (&mtxp->__lock, flags);
+      mtx_set_owner (mtxp, self, flags);
+      break;
+
+    case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+      self = _pthread_self ();
+      ROBUST_LOCK (self, mtxp, __lll_robust_lock, flags);
+      break;
+
+    default:
+      ret = EINVAL;
+      break;
+    }
+
+  return ret;
+}
+
+strong_alias (__pthread_mutex_lock, _pthread_mutex_lock)
+strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c
new file mode 100644
index 0000000000..5f39ebb959
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c
@@ -0,0 +1,36 @@
+/* pthread_mutex_setprioceiling.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_setprioceiling (pthread_mutex_t *mtxp, int cl, int *prp)
+{
+  (void) mtxp;
+  (void) cl;
+  (void) prp;
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutex_setprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c b/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c
new file mode 100644
index 0000000000..0457445c86
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c
@@ -0,0 +1,79 @@
+/* pthread_mutex_timedlock.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp)
+{
+  struct __pthread *self;
+  int ret, flags = mtxp->__flags & GSYNC_SHARED;
+
+  switch (MTX_TYPE (mtxp))
+    {
+    case PT_MTX_NORMAL:
+      ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags);
+      break;
+
+    case PT_MTX_RECURSIVE:
+      self = _pthread_self ();
+      if (mtx_owned_p (mtxp, self, flags))
+	{
+	  if (__glibc_unlikely (mtxp->__cnt + 1 == 0))
+	    return EAGAIN;
+
+	  ++mtxp->__cnt;
+	  ret = 0;
+	}
+      else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0)
+	{
+	  mtx_set_owner (mtxp, self, flags);
+	  mtxp->__cnt = 1;
+	}
+
+      break;
+
+    case PT_MTX_ERRORCHECK:
+      self = _pthread_self ();
+      if (mtx_owned_p (mtxp, self, flags))
+	ret = EDEADLK;
+      else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0)
+	mtx_set_owner (mtxp, self, flags);
+
+      break;
+
+    case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+      self = _pthread_self ();
+      ROBUST_LOCK (self, mtxp, lll_robust_abstimed_lock, tsp, flags);
+      break;
+
+    default:
+      ret = EINVAL;
+      break;
+    }
+
+  return ret;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c b/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c
new file mode 100644
index 0000000000..e89c8dcac7
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c
@@ -0,0 +1,77 @@
+/* pthread_mutex_transfer_np.  Transfer mutex ownership to another thread.
+   Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_transfer_np (pthread_mutex_t *mtxp, pthread_t th)
+{
+  struct __pthread *self = _pthread_self ();
+  struct __pthread *pt = __pthread_getid (th);
+
+  if (pt == NULL)
+    return ESRCH;
+  else if (pt == self)
+    return 0;
+
+  int ret = 0;
+  int flags = mtxp->__flags & GSYNC_SHARED;
+
+  switch (MTX_TYPE (mtxp))
+    {
+    case PT_MTX_NORMAL:
+      break;
+
+    case PT_MTX_RECURSIVE:
+    case PT_MTX_ERRORCHECK:
+      if (!mtx_owned_p (mtxp, self, flags))
+	ret = EPERM;
+      else
+	mtx_set_owner (mtxp, pt, flags);
+
+      break;
+
+    case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+      /* Note that this can be used to transfer an inconsistent
+       * mutex as well. The new owner will still have the same
+       * flags as the original. */
+      if (mtxp->__owner_id != self->thread ||
+	  (int) (mtxp->__lock & LLL_OWNER_MASK) != __getpid ())
+	ret = EPERM;
+      else
+	mtxp->__owner_id = pt->thread;
+
+      break;
+
+    default:
+      ret = EINVAL;
+    }
+
+  return ret;
+}
+
+weak_alias (__pthread_mutex_transfer_np, pthread_mutex_transfer_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-trylock.c b/sysdeps/mach/hurd/htl/pt-mutex-trylock.c
new file mode 100644
index 0000000000..36d4f5921c
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-trylock.c
@@ -0,0 +1,85 @@
+/* pthread_mutex_trylock.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_trylock (pthread_mutex_t *mtxp)
+{
+  struct __pthread *self;
+  int ret;
+
+  switch (MTX_TYPE (mtxp))
+    {
+    case PT_MTX_NORMAL:
+      ret = lll_trylock (&mtxp->__lock);
+      if (ret)
+	ret = EBUSY;
+      break;
+
+    case PT_MTX_RECURSIVE:
+      self = _pthread_self ();
+      if (mtx_owned_p (mtxp, self, mtxp->__flags))
+	{
+	  if (__glibc_unlikely (mtxp->__cnt + 1 == 0))
+	    return EAGAIN;
+
+	  ++mtxp->__cnt;
+	  ret = 0;
+	}
+      else if ((ret = lll_trylock (&mtxp->__lock)) == 0)
+	{
+	  mtx_set_owner (mtxp, self, mtxp->__flags);
+	  mtxp->__cnt = 1;
+	}
+      else
+	ret = EBUSY;
+
+      break;
+
+    case PT_MTX_ERRORCHECK:
+      self = _pthread_self ();
+      if ((ret = lll_trylock (&mtxp->__lock)) == 0)
+	mtx_set_owner (mtxp, self, mtxp->__flags);
+      else
+	ret = EBUSY;
+      break;
+
+    case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+      self = _pthread_self ();
+      ROBUST_LOCK (self, mtxp, __lll_robust_trylock);
+      break;
+
+    default:
+      ret = EINVAL;
+      break;
+    }
+
+  return ret;
+}
+
+strong_alias (__pthread_mutex_trylock, _pthread_mutex_trylock)
+strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-unlock.c b/sysdeps/mach/hurd/htl/pt-mutex-unlock.c
new file mode 100644
index 0000000000..30c62fcb24
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-unlock.c
@@ -0,0 +1,92 @@
+/* pthread_mutex_unlock.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_unlock (pthread_mutex_t *mtxp)
+{
+  struct __pthread *self;
+  int ret = 0, flags = mtxp->__flags & GSYNC_SHARED;
+
+  switch (MTX_TYPE (mtxp))
+    {
+    case PT_MTX_NORMAL:
+      lll_unlock (&mtxp->__lock, flags);
+      break;
+
+    case PT_MTX_RECURSIVE:
+      self = _pthread_self ();
+      if (!mtx_owned_p (mtxp, self, flags))
+	ret = EPERM;
+      else if (--mtxp->__cnt == 0)
+	{
+	  mtxp->__owner_id = mtxp->__shpid = 0;
+	  lll_unlock (&mtxp->__lock, flags);
+	}
+
+      break;
+
+    case PT_MTX_ERRORCHECK:
+      self = _pthread_self ();
+      if (!mtx_owned_p (mtxp, self, flags))
+	ret = EPERM;
+      else
+	{
+	  mtxp->__owner_id = mtxp->__shpid = 0;
+	  lll_unlock (&mtxp->__lock, flags);
+	}
+
+      break;
+
+    case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+    case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+      self = _pthread_self ();
+      if (mtxp->__owner_id == NOTRECOVERABLE_ID)
+	;			/* Nothing to do. */
+      else if (mtxp->__owner_id != self->thread ||
+	       (int) (mtxp->__lock & LLL_OWNER_MASK) != __getpid ())
+	ret = EPERM;
+      else if (--mtxp->__cnt == 0)
+	{
+	  /* Release the lock. If it's in an inconsistent
+	   * state, mark it as irrecoverable. */
+	  mtxp->__owner_id = (mtxp->__lock & LLL_DEAD_OWNER) ?
+	      NOTRECOVERABLE_ID : 0;
+	  __lll_robust_unlock (&mtxp->__lock, flags);
+	}
+
+      break;
+
+    default:
+      ret = EINVAL;
+      break;
+    }
+
+  return ret;
+}
+
+strong_alias (__pthread_mutex_unlock, _pthread_mutex_unlock)
+strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex.h b/sysdeps/mach/hurd/htl/pt-mutex.h
new file mode 100644
index 0000000000..2daf63e986
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex.h
@@ -0,0 +1,90 @@
+/* Internal definitions for pthreads library.
+   Copyright (C) 2016-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PT_MUTEX_H
+#define _PT_MUTEX_H	1
+
+/* Special ID used to signal an unrecoverable robust mutex. */
+#define NOTRECOVERABLE_ID   (1U << 31)
+
+/* Common path for robust mutexes. Assumes the variable 'ret'
+ * is bound in the function this is called from. */
+#define ROBUST_LOCK(self, mtxp, cb, ...)   \
+  if (mtxp->__owner_id == NOTRECOVERABLE_ID)   \
+    return ENOTRECOVERABLE;   \
+  else if (mtxp->__owner_id == self->thread &&   \
+      __getpid () == (int)(mtxp->__lock & LLL_OWNER_MASK))   \
+    {   \
+      if (mtxp->__type == PT_MTX_RECURSIVE)   \
+        {   \
+          if (__glibc_unlikely (mtxp->__cnt + 1 == 0))   \
+            return EAGAIN;   \
+          \
+          ++mtxp->__cnt;   \
+          return 0;   \
+        }   \
+      else if (mtxp->__type == PT_MTX_ERRORCHECK)   \
+        return EDEADLK;   \
+    }   \
+  \
+  ret = cb (&mtxp->__lock, ##__VA_ARGS__);   \
+  if (ret == 0 || ret == EOWNERDEAD)   \
+    {   \
+      if (mtxp->__owner_id == ENOTRECOVERABLE)   \
+        ret = ENOTRECOVERABLE;   \
+      else   \
+        {   \
+          mtxp->__owner_id = self->thread;   \
+          mtxp->__cnt = 1;   \
+          if (ret == EOWNERDEAD)   \
+            {   \
+              mtxp->__lock = mtxp->__lock | LLL_DEAD_OWNER;   \
+              atomic_write_barrier ();   \
+            }   \
+        }   \
+    }   \
+  (void)0
+
+/* Check that a thread owns the mutex. For non-robust, task-shared
+ * objects, we have to check the thread *and* process-id. */
+#define mtx_owned_p(mtx, pt, flags)   \
+  ((mtx)->__owner_id == (pt)->thread &&   \
+    (((flags) & GSYNC_SHARED) == 0 ||   \
+      (mtx)->__shpid == __getpid ()))
+
+/* Record a thread as the owner of the mutex. */
+#define mtx_set_owner(mtx, pt, flags)   \
+  (void)   \
+    ({   \
+       (mtx)->__owner_id = (pt)->thread;   \
+       if ((flags) & GSYNC_SHARED)   \
+         (mtx)->__shpid = __getpid ();   \
+     })
+
+/* Redefined mutex types. The +1 is for binary compatibility. */
+#define PT_MTX_NORMAL       __PTHREAD_MUTEX_TIMED
+#define PT_MTX_RECURSIVE    (__PTHREAD_MUTEX_RECURSIVE + 1)
+#define PT_MTX_ERRORCHECK   (__PTHREAD_MUTEX_ERRORCHECK + 1)
+
+/* Mutex type, including robustness. */
+#define MTX_TYPE(mtxp)   \
+  ((mtxp)->__type | ((mtxp)->__flags & PTHREAD_MUTEX_ROBUST))
+
+extern int __getpid (void) __attribute__ ((const));
+
+#endif /* pt-mutex.h */
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c b/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c
new file mode 100644
index 0000000000..9c6cffc5bd
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c
@@ -0,0 +1,34 @@
+/* pthread_mutexattr_destroy.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutexattr_destroy (pthread_mutexattr_t *attrp)
+{
+  (void) attrp;
+  return 0;
+}
+
+weak_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c
new file mode 100644
index 0000000000..4532eca989
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_getprioceiling.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *ap, int *clp)
+{
+  (void) ap;
+  (void) clp;
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutexattr_getprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c
new file mode 100644
index 0000000000..33cdc158b2
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c
@@ -0,0 +1,32 @@
+/* pthread_mutexattr_getprotocol.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attrp, int *ptp)
+{
+  *ptp = attrp->__protocol;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c
new file mode 100644
index 0000000000..d393b4bb7f
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c
@@ -0,0 +1,32 @@
+/* pthread_mutexattr_getpshared.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getpshared (const pthread_mutexattr_t *attrp, int *outp)
+{
+  *outp = attrp->__pshared;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c
new file mode 100644
index 0000000000..0999db02d7
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_getrobust.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getrobust (const pthread_mutexattr_t *attrp, int *outp)
+{
+  *outp = (attrp->__prioceiling & PTHREAD_MUTEX_ROBUST) ?
+      PTHREAD_MUTEX_ROBUST : PTHREAD_MUTEX_STALLED;
+  return 0;
+}
+
+weak_alias (pthread_mutexattr_getrobust, pthread_mutexattr_getrobust_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c b/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c
new file mode 100644
index 0000000000..6881a5b816
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c
@@ -0,0 +1,32 @@
+/* pthread_mutexattr_gettype.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_gettype (const pthread_mutexattr_t *attrp, int *outp)
+{
+  *outp = attrp->__mutex_type;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-init.c b/sysdeps/mach/hurd/htl/pt-mutexattr-init.c
new file mode 100644
index 0000000000..b135126553
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-init.c
@@ -0,0 +1,40 @@
+/* pthread_mutexattr_init.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+static const pthread_mutexattr_t dfl_attr = {
+  .__prioceiling = 0,
+  .__protocol = PTHREAD_PRIO_NONE,
+  .__pshared = PTHREAD_PROCESS_PRIVATE,
+  .__mutex_type = __PTHREAD_MUTEX_TIMED
+};
+
+int
+__pthread_mutexattr_init (pthread_mutexattr_t *attrp)
+{
+  *attrp = dfl_attr;
+  return 0;
+}
+weak_alias (__pthread_mutexattr_init, pthread_mutexattr_init)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c
new file mode 100644
index 0000000000..6011ffb94e
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_setprioceiling.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attrp, int cl)
+{
+  (void) attrp;
+  (void) cl;
+  return ENOSYS;
+}
+
+stub_warning (pthread_mutexattr_setprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c
new file mode 100644
index 0000000000..5173a487c4
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c
@@ -0,0 +1,34 @@
+/* pthread_mutexattr_setprotocol.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setprotocol (pthread_mutexattr_t *attrp, int proto)
+{
+  (void) attrp;
+  return proto == PTHREAD_PRIO_NONE ? 0 :
+	 proto != PTHREAD_PRIO_INHERIT &&
+	 proto != PTHREAD_PRIO_PROTECT ? EINVAL : ENOTSUP;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c
new file mode 100644
index 0000000000..7e0e607151
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_setpshared.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setpshared (pthread_mutexattr_t *attrp, int pshared)
+{
+  if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED)
+    return EINVAL;
+
+  attrp->__pshared = pshared;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c
new file mode 100644
index 0000000000..f38c7a747e
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c
@@ -0,0 +1,37 @@
+/* pthread_mutexattr_setrobust.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setrobust (pthread_mutexattr_t *attrp, int robust)
+{
+  if (robust != PTHREAD_MUTEX_ROBUST && robust != PTHREAD_MUTEX_STALLED)
+    return EINVAL;
+
+  attrp->__prioceiling |= robust;
+  return 0;
+}
+
+weak_alias (pthread_mutexattr_setrobust, pthread_mutexattr_setrobust_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c b/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c
new file mode 100644
index 0000000000..c856fd7859
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c
@@ -0,0 +1,36 @@
+/* pthread_mutexattr_settype.  Hurd version.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program 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.
+
+   This program is distributed in the hope that 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 this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutexattr_settype (pthread_mutexattr_t *attrp, int type)
+{
+  if (type < 0 || type > __PTHREAD_MUTEX_RECURSIVE)
+    return EINVAL;
+
+  attrp->__mutex_type = type;
+  return 0;
+}
+weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr.c b/sysdeps/mach/hurd/htl/pt-mutexattr.c
new file mode 100644
index 0000000000..40a8c178f1
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr.c
@@ -0,0 +1 @@
+/* empty */
diff --git a/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c b/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c
new file mode 100644
index 0000000000..69de5cad01
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c
@@ -0,0 +1,26 @@
+/* Destroy the signal state.  Hurd on Mach version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+void
+__pthread_sigstate_destroy (struct __pthread *thread)
+{
+}
diff --git a/sysdeps/mach/hurd/htl/pt-sigstate-init.c b/sysdeps/mach/hurd/htl/pt-sigstate-init.c
new file mode 100644
index 0000000000..a6b4f76b25
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sigstate-init.c
@@ -0,0 +1,44 @@
+/* Initialize the signal state.  Hurd on Mach version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <pt-internal.h>
+#include <hurd/signal.h>
+
+error_t
+__pthread_sigstate_init (struct __pthread *thread)
+{
+  static int do_init_global;
+
+  /* Mark the thread as a global signal receiver so as to conform with
+     the pthread semantics.  However, we must be careful.  The first
+     pthread created is the main thread, during libpthread initialization.
+     We must not mark it, otherwise the sigprocmask call in
+     __pthread_create would try to access _hurd_global_sigstate,
+     which is not initialized yet.  When glibc runs _hurdsig_init later
+     on, the message thread is created, which must not be marked either.  */
+  if (do_init_global)
+    {
+      struct hurd_sigstate *ss = _hurd_thread_sigstate (thread->kernel_thread);
+      (void) ss;
+    }
+  else if (__pthread_num_threads >= 2)
+    do_init_global = 1;
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-sigstate.c b/sysdeps/mach/hurd/htl/pt-sigstate.c
new file mode 100644
index 0000000000..5f0a1b4f9a
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sigstate.c
@@ -0,0 +1,70 @@
+/* Set a thread's signal state.  Hurd on Mach version.
+   Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <assert.h>
+#include <signal.h>
+#include <hurd/signal.h>
+
+#include <pt-internal.h>
+
+error_t
+__pthread_sigstate (struct __pthread *thread, int how,
+		    const sigset_t *set, sigset_t *oset, int clear_pending)
+{
+  error_t err = 0;
+  struct hurd_sigstate *ss;
+
+  ss = _hurd_thread_sigstate (thread->kernel_thread);
+  assert (ss);
+
+  __spin_lock (&ss->lock);
+
+  if (oset != NULL)
+    *oset = ss->blocked;
+
+  if (set != NULL)
+    {
+      switch (how)
+	{
+	case SIG_BLOCK:
+	  ss->blocked |= *set;
+	  break;
+
+	case SIG_SETMASK:
+	  ss->blocked = *set;
+	  break;
+
+	case SIG_UNBLOCK:
+	  ss->blocked &= ~*set;
+	  break;
+
+	default:
+	  err = EINVAL;
+	  break;
+	}
+      ss->blocked &= ~_SIG_CANT_MASK;
+    }
+
+  if (!err && clear_pending)
+    __sigemptyset (&ss->pending);
+
+  __spin_unlock (&ss->lock);
+
+  return err;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.c b/sysdeps/mach/hurd/htl/pt-sysdep.c
new file mode 100644
index 0000000000..40ebc8e6d6
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.c
@@ -0,0 +1,99 @@
+/* System dependent pthreads code.  Hurd version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <mach.h>
+#include <mach/mig_support.h>
+
+#include <pt-internal.h>
+
+__thread struct __pthread *___pthread_self;
+
+/* Forward.  */
+static void *init_routine (void);
+
+/* OK, the name of this variable isn't really appropriate, but I don't
+   want to change it yet.  */
+void *(*_cthread_init_routine) (void) = &init_routine;
+
+/* This function is called from the Hurd-specific startup code.  It
+   should return a new stack pointer for the main thread.  The caller
+   will switch to this new stack before doing anything serious.  */
+static void *
+_init_routine (void *stack)
+{
+  struct __pthread *thread;
+  int err;
+  pthread_attr_t attr, *attrp = 0;
+
+  if (__pthread_threads != NULL)
+    /* Already initialized */
+    return 0;
+
+  /* Initialize the library.  */
+  ___pthread_init ();
+
+  if (stack != NULL)
+    {
+      /* We are getting initialized due to dlopening a library using libpthread
+         while the main program was not linked against libpthread.  */
+      /* Avoid allocating another stack */
+      attrp = &attr;
+      pthread_attr_init (attrp);
+      pthread_attr_setstack (attrp, stack, __vm_page_size);
+    }
+
+  /* Create the pthread structure for the main thread (i.e. us).  */
+  err = __pthread_create_internal (&thread, attrp, 0, 0);
+  assert_perror (err);
+
+  /* XXX The caller copies the command line arguments and the environment
+     to the new stack.  Pretend it wasn't allocated so that it remains
+     valid if the main thread terminates.  */
+  thread->stack = 0;
+
+  ___pthread_self = thread;
+
+  /* Decrease the number of threads, to take into account that the
+     signal thread (which will be created by the glibc startup code
+     when we return from here) shouldn't be seen as a user thread.  */
+  __pthread_total--;
+
+  /* Make MiG code thread aware.  */
+  __mig_init (thread->stackaddr);
+
+  return thread->mcontext.sp;
+}
+
+static void *
+init_routine (void)
+{
+  return _init_routine (0);
+}
+
+#ifdef SHARED
+__attribute__ ((constructor))
+static void
+dynamic_init_routine (void)
+{
+  _init_routine (__libc_stack_end);
+}
+#endif
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.h b/sysdeps/mach/hurd/htl/pt-sysdep.h
new file mode 100644
index 0000000000..09778068b7
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.h
@@ -0,0 +1,65 @@
+/* Internal definitions for pthreads library.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PT_SYSDEP_H
+#define _PT_SYSDEP_H	1
+
+#include <mach.h>
+
+/* XXX */
+#define _POSIX_THREAD_THREADS_MAX	64
+
+/* The default stack size.  */
+#define PTHREAD_STACK_DEFAULT	(8 * 1024 * 1024)
+
+#define PTHREAD_SYSDEP_MEMBERS \
+  thread_t kernel_thread;      \
+  mach_msg_header_t wakeupmsg;
+
+extern __thread struct __pthread *___pthread_self;
+#define _pthread_self()                                            \
+	({                                                         \
+	  struct __pthread *thread;                                \
+	                                                           \
+	  assert (__pthread_threads);                              \
+	  thread = ___pthread_self;                                \
+	                                                           \
+	  assert (thread);                                         \
+	  assert (({ mach_port_t ktid = __mach_thread_self ();     \
+                     int ok = thread->kernel_thread == ktid;       \
+                     __mach_port_deallocate (__mach_task_self (), ktid);\
+                     ok; }));                                      \
+          thread;                                                  \
+         })
+
+extern inline void
+__attribute__ ((__always_inline__))
+__pthread_stack_dealloc (void *stackaddr, size_t stacksize)
+{
+  __vm_deallocate (__mach_task_self (), (vm_offset_t) stackaddr, stacksize);
+}
+
+/* Change thread THREAD's program counter to PC if SET_PC is true,
+   its stack pointer to SP if SET_IP is true, and its thread pointer
+   to TP if SET_TP is true.  */
+extern int __thread_set_pcsptp (thread_t thread,
+				int set_pc, void *pc,
+				int set_sp, void *sp, int set_tp, void *tp);
+
+
+#endif /* pt-sysdep.h */
diff --git a/sysdeps/mach/hurd/i386/Implies b/sysdeps/mach/hurd/i386/Implies
index 94db5e92ef..eedc9eada9 100644
--- a/sysdeps/mach/hurd/i386/Implies
+++ b/sysdeps/mach/hurd/i386/Implies
@@ -1 +1,2 @@
 mach/hurd/x86
+mach/hurd/i386/htl
diff --git a/sysdeps/mach/hurd/i386/htl/Implies b/sysdeps/mach/hurd/i386/htl/Implies
new file mode 100644
index 0000000000..7a0f99d772
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/htl/Implies
@@ -0,0 +1,2 @@
+mach/hurd/htl
+i386/htl
diff --git a/sysdeps/mach/hurd/i386/htl/pt-machdep.c b/sysdeps/mach/hurd/i386/htl/pt-machdep.c
new file mode 100644
index 0000000000..9b2083d2da
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/htl/pt-machdep.c
@@ -0,0 +1,82 @@
+/* Machine dependent pthreads code.  Hurd/i386 version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/i386/thread_status.h>
+#include <mach/i386/mach_i386.h>
+#include <mach/mig_errors.h>
+#include <mach/thread_status.h>
+
+#define HURD_TLS_DESC_DECL(desc, tcb)					      \
+  struct descriptor desc =						      \
+    {				/* low word: */				      \
+      0xffff			/* limit 0..15 */			      \
+      | (((unsigned int) (tcb)) << 16) /* base 0..15 */			      \
+      ,				/* high word: */			      \
+      ((((unsigned int) (tcb)) >> 16) & 0xff) /* base 16..23 */		      \
+      | ((0x12 | 0x60 | 0x80) << 8) /* access = ACC_DATA_W|ACC_PL_U|ACC_P */  \
+      | (0xf << 16)		/* limit 16..19 */			      \
+      | ((4 | 8) << 20)		/* granularity = SZ_32|SZ_G */		      \
+      | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */		      \
+    }
+
+int
+__thread_set_pcsptp (thread_t thread,
+		     int set_ip, void *ip,
+		     int set_sp, void *sp,
+		     int set_tp, void *tp)
+{
+  error_t err;
+  struct i386_thread_state state;
+  mach_msg_type_number_t state_count;
+
+  state_count = i386_THREAD_STATE_COUNT;
+
+  err = __thread_get_state (thread, i386_REGS_SEGS_STATE,
+			    (thread_state_t) &state, &state_count);
+  if (err)
+    return err;
+
+  if (set_sp)
+    state.uesp = (unsigned int) sp;
+  if (set_ip)
+    state.eip = (unsigned int) ip;
+  if (set_tp)
+    {
+      HURD_TLS_DESC_DECL (desc, tp);
+      int sel;
+
+    asm ("mov %%gs, %w0": "=q" (sel):"0" (0));
+      if (__builtin_expect (sel, 0x48) & 4)	/* LDT selector */
+	err = __i386_set_ldt (thread, sel, &desc, 1);
+      else
+	err = __i386_set_gdt (thread, &sel, desc);
+      if (err)
+	return err;
+      state.gs = sel;
+    }
+
+  err = __thread_set_state (thread, i386_REGS_SEGS_STATE,
+			    (thread_state_t) &state, i386_THREAD_STATE_COUNT);
+  if (err)
+    return err;
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/i386/htl/pt-setup.c b/sysdeps/mach/hurd/i386/htl/pt-setup.c
new file mode 100644
index 0000000000..a59f71b7be
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/htl/pt-setup.c
@@ -0,0 +1,110 @@
+/* Setup thread stack.  Hurd/i386 version.
+   Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include <assert.h>
+#include <mach.h>
+
+#include <pt-internal.h>
+
+/* The stack layout used on the i386 is:
+
+    -----------------
+   |  ARG            |
+    -----------------
+   |  START_ROUTINE  |
+    -----------------
+   |  0              |
+    -----------------
+ */
+
+/* Set up the stack for THREAD, such that it appears as if
+   START_ROUTINE and ARG were passed to the new thread's entry-point.
+   Return the stack pointer for the new thread.  */
+static void *
+stack_setup (struct __pthread *thread,
+	     void *(*start_routine) (void *), void *arg)
+{
+  error_t err;
+  uintptr_t *bottom, *top;
+
+  /* Calculate the top of the new stack.  */
+  bottom = thread->stackaddr;
+  top = (uintptr_t *) ((uintptr_t) bottom + thread->stacksize
+		       + ((thread->guardsize + __vm_page_size - 1)
+			  / __vm_page_size) * __vm_page_size);
+
+  if (start_routine != NULL)
+    {
+      /* And then the call frame.  */
+      top -= 3;
+      top = (uintptr_t *) ((uintptr_t) top & ~0xf);
+      top[2] = (uintptr_t) arg;	/* Argument to START_ROUTINE.  */
+      top[1] = (uintptr_t) start_routine;
+      top[0] = (uintptr_t) thread;
+      *--top = 0;		/* Fake return address.  */
+    }
+
+  if (thread->guardsize)
+    {
+      err = __vm_protect (__mach_task_self (), (vm_address_t) bottom,
+			  thread->guardsize, 0, 0);
+      assert_perror (err);
+    }
+
+  return top;
+}
+
+int
+__pthread_setup (struct __pthread *thread,
+		 void (*entry_point) (struct __pthread *, void *(*)(void *),
+				      void *), void *(*start_routine) (void *),
+		 void *arg)
+{
+  tcbhead_t *tcb;
+  error_t err;
+  mach_port_t ktid;
+
+  thread->mcontext.pc = entry_point;
+  thread->mcontext.sp = stack_setup (thread, start_routine, arg);
+
+  ktid = __mach_thread_self ();
+  if (thread->kernel_thread == ktid)
+    /* Fix up the TCB for the main thread.  The C library has already
+       installed a TCB, which we want to keep using.  This TCB must not
+       be freed so don't register it in the thread structure.  On the
+       other hand, it's not yet possible to reliably release a TCB.
+       Leave the unused one registered so that it doesn't leak.  The
+       only thing left to do is to correctly set the `self' member in
+       the already existing TCB.  */
+    tcb = THREAD_SELF;
+  else
+    {
+      err = __thread_set_pcsptp (thread->kernel_thread,
+				 1, thread->mcontext.pc,
+				 1, thread->mcontext.sp,
+				 1, thread->tcb);
+      assert_perror (err);
+      tcb = thread->tcb;
+    }
+  __mach_port_deallocate (__mach_task_self (), ktid);
+
+  tcb->self = thread->kernel_thread;
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist
new file mode 100644
index 0000000000..e11569f176
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/libpthread.abilist
@@ -0,0 +1,151 @@
+GLIBC_2.12 GLIBC_2.12 A
+GLIBC_2.12 __mutex_lock_solid F
+GLIBC_2.12 __mutex_unlock_solid F
+GLIBC_2.12 __pthread_get_cleanup_stack F
+GLIBC_2.12 __pthread_key_create F
+GLIBC_2.12 __pthread_kill F
+GLIBC_2.12 __pthread_mutex_transfer_np F
+GLIBC_2.12 __pthread_spin_destroy F
+GLIBC_2.12 __pthread_spin_init F
+GLIBC_2.12 __pthread_spin_lock F
+GLIBC_2.12 __pthread_spin_trylock F
+GLIBC_2.12 __pthread_spin_unlock F
+GLIBC_2.12 _cthread_init_routine D 0x4
+GLIBC_2.12 _cthreads_flockfile F
+GLIBC_2.12 _cthreads_ftrylockfile F
+GLIBC_2.12 _cthreads_funlockfile F
+GLIBC_2.12 _pthread_mutex_destroy F
+GLIBC_2.12 _pthread_mutex_init F
+GLIBC_2.12 _pthread_mutex_lock F
+GLIBC_2.12 _pthread_mutex_trylock F
+GLIBC_2.12 _pthread_mutex_unlock F
+GLIBC_2.12 _pthread_rwlock_destroy F
+GLIBC_2.12 _pthread_rwlock_init F
+GLIBC_2.12 _pthread_spin_lock F
+GLIBC_2.12 cthread_detach F
+GLIBC_2.12 cthread_fork F
+GLIBC_2.12 cthread_getspecific F
+GLIBC_2.12 cthread_keycreate F
+GLIBC_2.12 cthread_setspecific F
+GLIBC_2.12 flockfile F
+GLIBC_2.12 ftrylockfile F
+GLIBC_2.12 funlockfile F
+GLIBC_2.12 pthread_atfork F
+GLIBC_2.12 pthread_attr_destroy F
+GLIBC_2.12 pthread_attr_getdetachstate F
+GLIBC_2.12 pthread_attr_getguardsize F
+GLIBC_2.12 pthread_attr_getinheritsched F
+GLIBC_2.12 pthread_attr_getschedparam F
+GLIBC_2.12 pthread_attr_getschedpolicy F
+GLIBC_2.12 pthread_attr_getscope F
+GLIBC_2.12 pthread_attr_getstack F
+GLIBC_2.12 pthread_attr_getstackaddr F
+GLIBC_2.12 pthread_attr_getstacksize F
+GLIBC_2.12 pthread_attr_init F
+GLIBC_2.12 pthread_attr_setdetachstate F
+GLIBC_2.12 pthread_attr_setguardsize F
+GLIBC_2.12 pthread_attr_setinheritsched F
+GLIBC_2.12 pthread_attr_setschedparam F
+GLIBC_2.12 pthread_attr_setschedpolicy F
+GLIBC_2.12 pthread_attr_setscope F
+GLIBC_2.12 pthread_attr_setstack F
+GLIBC_2.12 pthread_attr_setstackaddr F
+GLIBC_2.12 pthread_attr_setstacksize F
+GLIBC_2.12 pthread_barrier_destroy F
+GLIBC_2.12 pthread_barrier_init F
+GLIBC_2.12 pthread_barrier_wait F
+GLIBC_2.12 pthread_barrierattr_destroy F
+GLIBC_2.12 pthread_barrierattr_getpshared F
+GLIBC_2.12 pthread_barrierattr_init F
+GLIBC_2.12 pthread_barrierattr_setpshared F
+GLIBC_2.12 pthread_cancel F
+GLIBC_2.12 pthread_cond_broadcast F
+GLIBC_2.12 pthread_cond_destroy F
+GLIBC_2.12 pthread_cond_init F
+GLIBC_2.12 pthread_cond_signal F
+GLIBC_2.12 pthread_cond_timedwait F
+GLIBC_2.12 pthread_cond_wait F
+GLIBC_2.12 pthread_condattr_destroy F
+GLIBC_2.12 pthread_condattr_getclock F
+GLIBC_2.12 pthread_condattr_getpshared F
+GLIBC_2.12 pthread_condattr_init F
+GLIBC_2.12 pthread_condattr_setclock F
+GLIBC_2.12 pthread_condattr_setpshared F
+GLIBC_2.12 pthread_create F
+GLIBC_2.12 pthread_detach F
+GLIBC_2.12 pthread_equal F
+GLIBC_2.12 pthread_exit F
+GLIBC_2.12 pthread_getattr_np F
+GLIBC_2.12 pthread_getconcurrency F
+GLIBC_2.12 pthread_getcpuclockid F
+GLIBC_2.12 pthread_getschedparam F
+GLIBC_2.12 pthread_getspecific F
+GLIBC_2.12 pthread_join F
+GLIBC_2.12 pthread_key_create F
+GLIBC_2.12 pthread_key_delete F
+GLIBC_2.12 pthread_kill F
+GLIBC_2.12 pthread_mutex_destroy F
+GLIBC_2.12 pthread_mutex_getprioceiling F
+GLIBC_2.12 pthread_mutex_init F
+GLIBC_2.12 pthread_mutex_lock F
+GLIBC_2.12 pthread_mutex_setprioceiling F
+GLIBC_2.12 pthread_mutex_timedlock F
+GLIBC_2.12 pthread_mutex_transfer_np F
+GLIBC_2.12 pthread_mutex_trylock F
+GLIBC_2.12 pthread_mutex_unlock F
+GLIBC_2.12 pthread_mutexattr_destroy F
+GLIBC_2.12 pthread_mutexattr_getprioceiling F
+GLIBC_2.12 pthread_mutexattr_getprotocol F
+GLIBC_2.12 pthread_mutexattr_getpshared F
+GLIBC_2.12 pthread_mutexattr_gettype F
+GLIBC_2.12 pthread_mutexattr_init F
+GLIBC_2.12 pthread_mutexattr_setprioceiling F
+GLIBC_2.12 pthread_mutexattr_setprotocol F
+GLIBC_2.12 pthread_mutexattr_setpshared F
+GLIBC_2.12 pthread_mutexattr_settype F
+GLIBC_2.12 pthread_once F
+GLIBC_2.12 pthread_rwlock_destroy F
+GLIBC_2.12 pthread_rwlock_init F
+GLIBC_2.12 pthread_rwlock_rdlock F
+GLIBC_2.12 pthread_rwlock_timedrdlock F
+GLIBC_2.12 pthread_rwlock_timedwrlock F
+GLIBC_2.12 pthread_rwlock_tryrdlock F
+GLIBC_2.12 pthread_rwlock_trywrlock F
+GLIBC_2.12 pthread_rwlock_unlock F
+GLIBC_2.12 pthread_rwlock_wrlock F
+GLIBC_2.12 pthread_rwlockattr_destroy F
+GLIBC_2.12 pthread_rwlockattr_getpshared F
+GLIBC_2.12 pthread_rwlockattr_init F
+GLIBC_2.12 pthread_rwlockattr_setpshared F
+GLIBC_2.12 pthread_self F
+GLIBC_2.12 pthread_setcancelstate F
+GLIBC_2.12 pthread_setcanceltype F
+GLIBC_2.12 pthread_setconcurrency F
+GLIBC_2.12 pthread_setschedparam F
+GLIBC_2.12 pthread_setschedprio F
+GLIBC_2.12 pthread_setspecific F
+GLIBC_2.12 pthread_sigmask F
+GLIBC_2.12 pthread_spin_destroy F
+GLIBC_2.12 pthread_spin_init F
+GLIBC_2.12 pthread_spin_lock F
+GLIBC_2.12 pthread_spin_trylock F
+GLIBC_2.12 pthread_spin_unlock F
+GLIBC_2.12 pthread_testcancel F
+GLIBC_2.12 pthread_yield F
+GLIBC_2.12 sem_close F
+GLIBC_2.12 sem_destroy F
+GLIBC_2.12 sem_getvalue F
+GLIBC_2.12 sem_init F
+GLIBC_2.12 sem_open F
+GLIBC_2.12 sem_post F
+GLIBC_2.12 sem_timedwait F
+GLIBC_2.12 sem_trywait F
+GLIBC_2.12 sem_unlink F
+GLIBC_2.12 sem_wait F
+GLIBC_2.2.6 GLIBC_2.2.6 A
+GLIBC_2.2.6 _IO_flockfile F
+GLIBC_2.2.6 _IO_ftrylockfile F
+GLIBC_2.2.6 _IO_funlockfile F
+GLIBC_2.21 GLIBC_2.21 A
+GLIBC_2.21 pthread_hurd_cond_timedwait_np F
+GLIBC_2.21 pthread_hurd_cond_wait_np F