This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.27.9000-251-g33574c1


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  33574c17eefcf326c1cd30eb9f915ad26d3d9ef2 (commit)
      from  03e2aa50fd512449025bba8c244d16338d8526a4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=33574c17eefcf326c1cd30eb9f915ad26d3d9ef2

commit 33574c17eefcf326c1cd30eb9f915ad26d3d9ef2
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Mon Apr 2 01:43:22 2018 +0200

    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.

diff --git a/ChangeLog b/ChangeLog
index 55eec1b..2d813a8 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 0000000..3bde5f0
--- /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 0000000..6a63a1b
--- /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 0000000..4c183bd
--- /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 0000000..5983490
--- /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 0000000..4e140b1
--- /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 0000000..042ed64
--- /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 0000000..cb36ae2
--- /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 0000000..b6e9682
--- /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 0000000..e5bd2cc
--- /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 0000000..33346b4
--- /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 0000000..9069496
--- /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 0000000..adab790
--- /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 0000000..9f87724
--- /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 0000000..74c86b2
--- /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 0000000..f5c06ff
--- /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 0000000..15e251e
--- /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 0000000..773ed10
--- /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 0000000..8f3d755
--- /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 0000000..b1ec5e0
--- /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 0000000..201810f
--- /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 0000000..22afc1f
--- /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 0000000..329163d
--- /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 0000000..0f932ac
--- /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 0000000..de5c688
--- /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 0000000..0f29a43
--- /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 0000000..f55c508
--- /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 0000000..3797235
--- /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 0000000..783a6a6
--- /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 0000000..0dee959
--- /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 0000000..98e07a6
--- /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 0000000..7177ad1
--- /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 0000000..230f1b2
--- /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 0000000..25263ee
--- /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 0000000..31d3449
--- /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 0000000..f8c7a42
--- /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 0000000..9676446
--- /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 0000000..d142149
--- /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 0000000..6e7cef1
--- /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 0000000..baf866a
--- /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 0000000..519aa84
--- /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 0000000..ffc90b5
--- /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 0000000..1194a34
--- /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 0000000..beed473
--- /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 0000000..b8c24b7
--- /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 0000000..ef9691c
--- /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 0000000..e25d419
--- /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 0000000..4823de2
--- /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 0000000..9cf74a7
--- /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 0000000..ad6bc36
--- /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 0000000..c54ccad
--- /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 6c1aa44..ba64a2d 100644
--- a/nscd/Depend
+++ b/nscd/Depend
@@ -1 +1,2 @@
 nptl
+htl
diff --git a/resolv/Depend b/resolv/Depend
index 6c1aa44..ba64a2d 100644
--- a/resolv/Depend
+++ b/resolv/Depend
@@ -1 +1,2 @@
 nptl
+htl
diff --git a/rt/Depend b/rt/Depend
index 6c1aa44..ba64a2d 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 0000000..f1b3e89
--- /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 0000000..3af4c1d
--- /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 0000000..12bb54e
--- /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 0000000..5215f33
--- /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 0000000..3a3b1e8
--- /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 0000000..56cf1af
--- /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 0000000..b9587ef
--- /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 0000000..593ab06
--- /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 0000000..95ccf51
--- /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 0000000..b1789be
--- /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 0000000..054cbf2
--- /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 0000000..c558f47
--- /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 0000000..44f9543
--- /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 0000000..27a6b84
--- /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 0000000..5ac2c34
--- /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 0000000..d84cde0
--- /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 0000000..4d54501
--- /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 0000000..0a89ded
--- /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 0000000..c77458a
--- /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 0000000..5b99658
--- /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 0000000..cf47671
--- /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 0000000..7df532e
--- /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 0000000..f9df093
--- /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 0000000..f944a74
--- /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 0000000..7de42c7
--- /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 0000000..bc7da12
--- /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 0000000..944c0e5
--- /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 0000000..dfb7e98
--- /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 0000000..036427d
--- /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 0000000..a538201
--- /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 0000000..5520305
--- /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 0000000..38c4f78
--- /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 0000000..1187dfa
--- /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 0000000..cd86d61
--- /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 0000000..49e1fed
--- /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 0000000..a48ec6d
--- /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 0000000..4367c2f
--- /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 0000000..a043d78
--- /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 0000000..59c9c64
--- /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 0000000..e6ccc82
--- /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 0000000..4907f4b
--- /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 0000000..97f9d3b
--- /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 0000000..abbb9cb
--- /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 0000000..c382f55
--- /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 0000000..411fc0b
--- /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 0000000..4e20d24
--- /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 0000000..e538283
--- /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 0000000..e3ca583
--- /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 0000000..547bf67
--- /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 0000000..f1877fd
--- /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 0000000..7d4f03e
--- /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 0000000..8f652d7
--- /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 0000000..faac1f9
--- /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 0000000..0990ce9
--- /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 0000000..c99227b
--- /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 0000000..3015f1c
--- /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 0000000..b523628
--- /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 0000000..52a5040
--- /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 0000000..fc1d653
--- /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 0000000..81c4ccf
--- /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 0000000..4c128ac
--- /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 0000000..a1c0c2a
--- /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 0000000..525e63d
--- /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 0000000..8ea7c8e
--- /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 0000000..2dc6c51
--- /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 0000000..7399858
--- /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 0000000..6c603e1
--- /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 0000000..4f51f7e
--- /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 0000000..ec392e1
--- /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 0000000..fa3e14a
--- /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 0000000..9283a68
--- /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 0000000..523a620
--- /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 0000000..11ded7a
--- /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 0000000..4b95901
--- /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 0000000..e4c7e87
--- /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 0000000..2d83287
--- /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 0000000..70e1f6c
--- /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 0000000..841ba27
--- /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 0000000..194acc3
--- /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 0000000..e9b5665
--- /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 0000000..d1d4b76
--- /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 0000000..7f7a39e
--- /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 0000000..17b3083
--- /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 0000000..66833b8
--- /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 0000000..ee3ca9a
--- /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 0000000..6a82627
--- /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 0000000..ea02188
--- /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 0000000..2a64c53
--- /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 0000000..e208ac1
--- /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 0000000..b19611b
--- /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 0000000..e46a913
--- /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 0000000..a43cf7d
--- /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 0000000..9e13910
--- /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 0000000..cef51d2
--- /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 0000000..3afcb50
--- /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 0000000..aa5639c
--- /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 0000000..bb90ce7
--- /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 0000000..8a0f86f
--- /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 0000000..ffd21c2
--- /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 0000000..759def0
--- /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 0000000..9dc5ba0
--- /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 0000000..ba55ebd
--- /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 0000000..a3a139a
--- /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 0000000..a4814fc
--- /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 0000000..8261a18
--- /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 0000000..0ef8432
--- /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 0000000..4592e1a
--- /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 0000000..60dd97f
--- /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 0000000..b30c250
--- /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 0000000..39a368c
--- /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 0000000..2f6f7b9
--- /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 0000000..9fd1aa8
--- /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 0000000..ed129a8
--- /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 0000000..218fe88
--- /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 0000000..09f57c6
--- /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 0000000..6ba3a3d
--- /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 0000000..acb5ea4
--- /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 0000000..3f05005
--- /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 0000000..f8bce35
--- /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 0000000..1d13cbd
--- /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 0000000..8492b5d
--- /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 0000000..0840bab
--- /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 0000000..dc3bc59
--- /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 0000000..a0d06cc
--- /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 0000000..91ab9b3
--- /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 0000000..c379749
--- /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 0000000..d2f21c8
--- /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 0000000..10a96ca
--- /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 0000000..c1c5bcb
--- /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 0000000..2065458
--- /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 0000000..5faa8ef
--- /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 0000000..2d708f0
--- /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 0000000..12cb36c
--- /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 0000000..54a4ea4
--- /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 0000000..e84b08d
--- /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 0000000..a5f6390
--- /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 0000000..e45b0b1
--- /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 0000000..cddd5e5
--- /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 0000000..a8134f5
--- /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 0000000..5b72701
--- /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 0000000..75ba632
--- /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 0000000..8470f2f
--- /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 0000000..bfb50af
--- /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 0000000..5215f33
--- /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 0000000..695c6dc
--- /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 0000000..038e2b4
--- /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 0000000..1ffda81
--- /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 0000000..b2e00ea
--- /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 0000000..6c38c92
--- /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 0000000..3c763ef
--- /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 0000000..571c1f2
--- /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 0000000..418fb40
--- /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 0000000..4255f77
--- /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 0000000..1e5488f
--- /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 0000000..64daad1
--- /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 0000000..0acee62
--- /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 0000000..4fe87cc
--- /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 0000000..711ae67
--- /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 0000000..6a96370
--- /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 0000000..a8bcb24
--- /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 0000000..41792e3
--- /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 0000000..2f2b6c2
--- /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 0000000..9fd6342
--- /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 0000000..89b4916
--- /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 0000000..fa6b82b
--- /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 0000000..8218eb1
--- /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 0000000..e4a86f0
--- /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 0000000..5f39ebb
--- /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 0000000..0457445
--- /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 0000000..e89c8dc
--- /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 0000000..36d4f59
--- /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 0000000..30c62fc
--- /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 0000000..2daf63e
--- /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 0000000..9c6cffc
--- /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 0000000..4532eca
--- /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 0000000..33cdc15
--- /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 0000000..d393b4b
--- /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 0000000..0999db0
--- /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 0000000..6881a5b
--- /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 0000000..b135126
--- /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 0000000..6011ffb
--- /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 0000000..5173a48
--- /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 0000000..7e0e607
--- /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 0000000..f38c7a7
--- /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 0000000..c856fd7
--- /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 0000000..40a8c17
--- /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 0000000..69de5ca
--- /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 0000000..a6b4f76
--- /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 0000000..5f0a1b4
--- /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 0000000..40ebc8e
--- /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 0000000..0977806
--- /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 94db5e9..eedc9ea 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 0000000..7a0f99d
--- /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 0000000..9b2083d
--- /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 0000000..a59f71b
--- /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 0000000..e11569f
--- /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

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |   24 +
 htl/Makefile                                       |  237 ++++++
 htl/Versions                                       |  156 ++++
 htl/alloca_cutoff.c                                |   26 +
 htl/configure                                      |    2 +
 htl/configure.in                                   |    4 +
 htl/cthreads-compat.c                              |  101 +++
 htl/forward.c                                      |  283 +++++++
 htl/libc_pthread_init.c                            |   33 +
 htl/libpthread.a                                   |   22 +
 htl/libpthread_pic.a                               |   22 +
 htl/lockfile.c                                     |   60 ++
 htl/pt-alloc.c                                     |  214 +++++
 htl/pt-cancel.c                                    |   62 ++
 htl/pt-cleanup.c                                   |   27 +
 htl/pt-create.c                                    |  246 ++++++
 htl/pt-dealloc.c                                   |   68 ++
 htl/pt-detach.c                                    |   79 ++
 htl/pt-exit.c                                      |  111 +++
 htl/pt-getattr.c                                   |   51 ++
 htl/pt-initialize.c                                |   83 ++
 htl/pt-internal.h                                  |  324 +++++++
 htl/pt-join.c                                      |   75 ++
 htl/pt-self.c                                      |   33 +
 htl/pt-setcancelstate.c                            |   46 +
 htl/pt-setcanceltype.c                             |   46 +
 htl/pt-sigmask.c                                   |   31 +
 htl/pt-spin-inlines.c                              |   33 +
 htl/pt-testcancel.c                                |   35 +
 htl/pt-yield.c                                     |   26 +
 htl/shlib-versions                                 |    1 +
 htl/tests/Makefile                                 |   40 +
 htl/tests/README                                   |    6 +
 htl/tests/test-1.c                                 |   68 ++
 htl/tests/test-10.c                                |   62 ++
 htl/tests/test-11.c                                |  159 ++++
 htl/tests/test-12.c                                |   45 +
 htl/tests/test-13.c                                |   82 ++
 htl/tests/test-14.c                                |   60 ++
 htl/tests/test-15.c                                |  102 +++
 htl/tests/test-16.c                                |   87 ++
 htl/tests/test-17.c                                |   73 ++
 htl/tests/test-2.c                                 |   56 ++
 htl/tests/test-3.c                                 |   71 ++
 htl/tests/test-4.c                                 |  102 +++
 htl/tests/test-5.c                                 |   91 ++
 htl/tests/test-6.c                                 |  114 +++
 htl/tests/test-7.c                                 |   89 ++
 htl/tests/test-8.c                                 |   78 ++
 htl/tests/test-9.c                                 |  104 +++
 htl/tests/test-__pthread_destroy_specific-skip.c   |  100 +++
 nscd/Depend                                        |    1 +
 resolv/Depend                                      |    1 +
 rt/Depend                                          |    1 +
 sysdeps/{nptl => htl}/Implies                      |    0
 sysdeps/htl/Makeconfig                             |   11 +
 sysdeps/htl/Makefile                               |    7 +
 sysdeps/htl/Subdirs                                |    1 +
 sysdeps/htl/Versions                               |   15 +
 sysdeps/htl/bits/cancelation.h                     |   50 ++
 sysdeps/htl/bits/pthread-np.h                      |   26 +
 sysdeps/htl/bits/pthread.h                         |   36 +
 sysdeps/htl/bits/pthreadtypes.h                    |  131 +++
 sysdeps/htl/bits/semaphore.h                       |   47 +
 sysdeps/htl/bits/thread-shared-types.h             |   24 +
 sysdeps/htl/bits/types/__pthread_key.h             |   24 +
 sysdeps/htl/bits/types/struct___pthread_attr.h     |   45 +
 sysdeps/htl/bits/types/struct___pthread_barrier.h  |   38 +
 .../htl/bits/types/struct___pthread_barrierattr.h  |   31 +
 sysdeps/htl/bits/types/struct___pthread_cond.h     |   38 +
 sysdeps/htl/bits/types/struct___pthread_condattr.h |   33 +
 sysdeps/htl/bits/types/struct___pthread_mutex.h    |   62 ++
 .../htl/bits/types/struct___pthread_mutexattr.h    |   40 +
 sysdeps/htl/bits/types/struct___pthread_once.h     |   33 +
 sysdeps/htl/bits/types/struct___pthread_rwlock.h   |   45 +
 .../htl/bits/types/struct___pthread_rwlockattr.h   |   31 +
 sysdeps/htl/flockfile.c                            |   31 +
 sysdeps/htl/fork.h                                 |   29 +
 sysdeps/htl/ftrylockfile.c                         |   35 +
 sysdeps/htl/funlockfile.c                          |   32 +
 sysdeps/htl/libc-lockP.h                           |  180 ++++
 sysdeps/htl/old_pt-atfork.c                        |   26 +
 sysdeps/htl/pt-atfork.c                            |   33 +
 sysdeps/htl/pt-attr-destroy.c                      |   27 +
 sysdeps/htl/pt-attr-getdetachstate.c               |   29 +
 sysdeps/htl/pt-attr-getguardsize.c                 |   27 +
 sysdeps/htl/pt-attr-getinheritsched.c              |   29 +
 sysdeps/htl/pt-attr-getschedparam.c                |   33 +
 sysdeps/htl/pt-attr-getschedpolicy.c               |   29 +
 sysdeps/htl/pt-attr-getscope.c                     |   29 +
 sysdeps/htl/pt-attr-getstack.c                     |   30 +
 sysdeps/htl/pt-attr-getstackaddr.c                 |   27 +
 sysdeps/htl/pt-attr-getstacksize.c                 |   27 +
 sysdeps/htl/pt-attr-init.c                         |   28 +
 sysdeps/htl/pt-attr-setdetachstate.c               |   38 +
 sysdeps/htl/pt-attr-setguardsize.c                 |   27 +
 sysdeps/htl/pt-attr-setinheritsched.c              |   38 +
 sysdeps/htl/pt-attr-setschedparam.c                |   38 +
 sysdeps/htl/pt-attr-setschedpolicy.c               |   42 +
 sysdeps/htl/pt-attr-setscope.c                     |   41 +
 sysdeps/htl/pt-attr-setstack.c                     |   48 ++
 sysdeps/htl/pt-attr-setstackaddr.c                 |   27 +
 sysdeps/htl/pt-attr-setstacksize.c                 |   28 +
 sysdeps/htl/pt-attr.c                              |   39 +
 sysdeps/htl/pt-barrier-destroy.c                   |   26 +
 sysdeps/htl/pt-barrier-init.c                      |   51 ++
 sysdeps/htl/pt-barrier-wait.c                      |   68 ++
 sysdeps/htl/pt-barrier.c                           |   24 +
 sysdeps/htl/pt-barrierattr-destroy.c               |   26 +
 sysdeps/htl/pt-barrierattr-getpshared.c            |   28 +
 sysdeps/htl/pt-barrierattr-init.c                  |   27 +
 sysdeps/htl/pt-barrierattr-setpshared.c            |   37 +
 sysdeps/htl/pt-cond-brdcast.c                      |   44 +
 sysdeps/htl/pt-cond-destroy.c                      |   28 +
 sysdeps/htl/pt-cond-init.c                         |   45 +
 sysdeps/htl/pt-cond-signal.c                       |   42 +
 sysdeps/htl/pt-cond-timedwait.c                    |  177 ++++
 sysdeps/htl/pt-cond-wait.c                         |   38 +
 sysdeps/htl/pt-cond.c                              |   27 +
 sysdeps/htl/pt-condattr-destroy.c                  |   28 +
 sysdeps/htl/pt-condattr-getclock.c                 |   29 +
 sysdeps/htl/pt-condattr-getpshared.c               |   27 +
 sysdeps/htl/pt-condattr-init.c                     |   29 +
 sysdeps/htl/pt-condattr-setclock.c                 |   51 ++
 sysdeps/htl/pt-condattr-setpshared.c               |   37 +
 sysdeps/htl/pt-destroy-specific.c                  |   77 ++
 sysdeps/htl/pt-equal.c                             |   30 +
 sysdeps/htl/pt-getconcurrency.c                    |   26 +
 sysdeps/htl/pt-getcpuclockid.c                     |   35 +
 sysdeps/htl/pt-getschedparam.c                     |   31 +
 sysdeps/htl/pt-getspecific.c                       |   38 +
 sysdeps/htl/pt-init-specific.c                     |   30 +
 sysdeps/htl/pt-key-create.c                        |  108 +++
 sysdeps/htl/pt-key-delete.c                        |   63 ++
 sysdeps/htl/pt-key.h                               |   76 ++
 sysdeps/htl/pt-kill.c                              |   33 +
 sysdeps/htl/pt-mutex-destroy.c                     |   38 +
 sysdeps/htl/pt-mutex-getprioceiling.c              |   28 +
 sysdeps/htl/pt-mutex-init.c                        |   48 ++
 sysdeps/htl/pt-mutex-lock.c                        |   36 +
 sysdeps/htl/pt-mutex-setprioceiling.c              |   28 +
 sysdeps/htl/pt-mutex-timedlock.c                   |  195 +++++
 sysdeps/htl/pt-mutex-transfer-np.c                 |   66 ++
 sysdeps/htl/pt-mutex-trylock.c                     |  111 +++
 sysdeps/htl/pt-mutex-unlock.c                      |  107 +++
 sysdeps/htl/pt-mutexattr-destroy.c                 |   27 +
 sysdeps/htl/pt-mutexattr-getprioceiling.c          |   29 +
 sysdeps/htl/pt-mutexattr-getprotocol.c             |   27 +
 sysdeps/htl/pt-mutexattr-getpshared.c              |   27 +
 sysdeps/htl/pt-mutexattr-gettype.c                 |   27 +
 sysdeps/htl/pt-mutexattr-init.c                    |   28 +
 sysdeps/htl/pt-mutexattr-setprioceiling.c          |   28 +
 sysdeps/htl/pt-mutexattr-setprotocol.c             |   40 +
 sysdeps/htl/pt-mutexattr-setpshared.c              |   37 +
 sysdeps/htl/pt-mutexattr-settype.c                 |   37 +
 sysdeps/htl/pt-mutexattr.c                         |   41 +
 sysdeps/htl/pt-once.c                              |   44 +
 sysdeps/htl/pt-rwlock-attr.c                       |   24 +
 sysdeps/htl/pt-rwlock-destroy.c                    |   28 +
 sysdeps/htl/pt-rwlock-init.c                       |   44 +
 sysdeps/htl/pt-rwlock-rdlock.c                     |   34 +
 sysdeps/htl/pt-rwlock-timedrdlock.c                |  120 +++
 sysdeps/htl/pt-rwlock-timedwrlock.c                |  103 +++
 sysdeps/htl/pt-rwlock-tryrdlock.c                  |   55 ++
 sysdeps/htl/pt-rwlock-trywrlock.c                  |   45 +
 sysdeps/htl/pt-rwlock-unlock.c                     |   98 +++
 sysdeps/htl/pt-rwlock-wrlock.c                     |   36 +
 sysdeps/htl/pt-rwlockattr-destroy.c                |   26 +
 sysdeps/htl/pt-rwlockattr-getpshared.c             |   27 +
 sysdeps/htl/pt-rwlockattr-init.c                   |   27 +
 sysdeps/htl/pt-rwlockattr-setpshared.c             |   37 +
 sysdeps/htl/pt-setconcurrency.c                    |   33 +
 sysdeps/htl/pt-setschedparam.c                     |   30 +
 sysdeps/htl/pt-setschedprio.c                      |   28 +
 sysdeps/htl/pt-setspecific.c                       |   50 ++
 sysdeps/htl/pt-spin.c                              |   50 ++
 sysdeps/htl/pt-startup.c                           |   24 +
 sysdeps/htl/pthread-functions.h                    |  140 +++
 sysdeps/htl/pthread.h                              |  883 ++++++++++++++++++++
 sysdeps/htl/pthreadP.h                             |   46 +
 sysdeps/htl/raise.c                                |   51 ++
 sysdeps/htl/sem-close.c                            |   31 +
 sysdeps/htl/sem-destroy.c                          |   37 +
 sysdeps/htl/sem-getvalue.c                         |   32 +
 sysdeps/htl/sem-init.c                             |   45 +
 sysdeps/htl/sem-open.c                             |   31 +
 sysdeps/htl/sem-post.c                             |   61 ++
 sysdeps/htl/sem-timedwait.c                        |   98 +++
 sysdeps/htl/sem-trywait.c                          |   41 +
 sysdeps/htl/sem-unlink.c                           |   31 +
 sysdeps/htl/sem-wait.c                             |   31 +
 sysdeps/htl/shm-directory.h                        |   30 +
 sysdeps/htl/timer_routines.h                       |   46 +
 sysdeps/hurd/htl/pt-kill.c                         |   51 ++
 sysdeps/i386/htl/bits/pthreadtypes-arch.h          |   22 +
 sysdeps/i386/htl/machine-sp.h                      |   29 +
 sysdeps/i386/htl/pt-machdep.h                      |   28 +
 sysdeps/mach/htl/Implies                           |    1 +
 sysdeps/mach/htl/bits/spin-lock-inline.h           |   87 ++
 sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h |   34 +
 sysdeps/mach/htl/pt-block.c                        |   38 +
 sysdeps/mach/htl/pt-spin.c                         |   31 +
 sysdeps/mach/htl/pt-stack-alloc.c                  |   67 ++
 sysdeps/mach/htl/pt-thread-alloc.c                 |   94 +++
 sysdeps/mach/htl/pt-thread-start.c                 |   53 ++
 sysdeps/mach/htl/pt-thread-terminate.c             |   82 ++
 sysdeps/mach/htl/pt-timedblock.c                   |   65 ++
 sysdeps/mach/htl/pt-wakeup.c                       |   37 +
 sysdeps/mach/hurd/htl/Implies                      |    2 +
 sysdeps/mach/hurd/htl/bits/pthread-np.h            |   37 +
 .../hurd/htl/bits/types/struct___pthread_mutex.h   |   49 ++
 sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c       |   27 +
 sysdeps/mach/hurd/htl/pt-attr-setstacksize.c       |   27 +
 sysdeps/mach/hurd/htl/pt-docancel.c                |   65 ++
 sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c     |  169 ++++
 sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c          |   40 +
 sysdeps/mach/hurd/htl/pt-mutex-consistent.c        |   48 ++
 sysdeps/mach/hurd/htl/pt-mutex-destroy.c           |   38 +
 sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c    |   35 +
 sysdeps/mach/hurd/htl/pt-mutex-init.c              |   56 ++
 sysdeps/mach/hurd/htl/pt-mutex-lock.c              |   81 ++
 sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c    |   36 +
 sysdeps/mach/hurd/htl/pt-mutex-timedlock.c         |   79 ++
 sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c       |   77 ++
 sysdeps/mach/hurd/htl/pt-mutex-trylock.c           |   85 ++
 sysdeps/mach/hurd/htl/pt-mutex-unlock.c            |   92 ++
 sysdeps/mach/hurd/htl/pt-mutex.h                   |   90 ++
 sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c       |   34 +
 .../mach/hurd/htl/pt-mutexattr-getprioceiling.c    |   35 +
 sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c   |   32 +
 sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c    |   32 +
 sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c     |   35 +
 sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c       |   32 +
 sysdeps/mach/hurd/htl/pt-mutexattr-init.c          |   40 +
 .../mach/hurd/htl/pt-mutexattr-setprioceiling.c    |   35 +
 sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c   |   34 +
 sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c    |   35 +
 sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c     |   37 +
 sysdeps/mach/hurd/htl/pt-mutexattr-settype.c       |   36 +
 .../mach/hurd/htl/pt-mutexattr.c                   |    0
 sysdeps/mach/hurd/htl/pt-sigstate-destroy.c        |   26 +
 sysdeps/mach/hurd/htl/pt-sigstate-init.c           |   44 +
 sysdeps/mach/hurd/htl/pt-sigstate.c                |   70 ++
 sysdeps/mach/hurd/htl/pt-sysdep.c                  |   99 +++
 sysdeps/mach/hurd/htl/pt-sysdep.h                  |   65 ++
 sysdeps/mach/hurd/i386/Implies                     |    1 +
 sysdeps/mach/hurd/i386/htl/Implies                 |    2 +
 sysdeps/mach/hurd/i386/htl/pt-machdep.c            |   82 ++
 sysdeps/mach/hurd/i386/htl/pt-setup.c              |  110 +++
 sysdeps/mach/hurd/i386/libpthread.abilist          |  151 ++++
 250 files changed, 13925 insertions(+), 0 deletions(-)
 create mode 100644 htl/Makefile
 create mode 100644 htl/Versions
 create mode 100644 htl/alloca_cutoff.c
 create mode 100644 htl/configure
 create mode 100644 htl/configure.in
 create mode 100644 htl/cthreads-compat.c
 create mode 100644 htl/forward.c
 create mode 100644 htl/libc_pthread_init.c
 create mode 100644 htl/libpthread.a
 create mode 100644 htl/libpthread_pic.a
 create mode 100644 htl/lockfile.c
 create mode 100644 htl/pt-alloc.c
 create mode 100644 htl/pt-cancel.c
 create mode 100644 htl/pt-cleanup.c
 create mode 100644 htl/pt-create.c
 create mode 100644 htl/pt-dealloc.c
 create mode 100644 htl/pt-detach.c
 create mode 100644 htl/pt-exit.c
 create mode 100644 htl/pt-getattr.c
 create mode 100644 htl/pt-initialize.c
 create mode 100644 htl/pt-internal.h
 create mode 100644 htl/pt-join.c
 create mode 100644 htl/pt-self.c
 create mode 100644 htl/pt-setcancelstate.c
 create mode 100644 htl/pt-setcanceltype.c
 create mode 100644 htl/pt-sigmask.c
 create mode 100644 htl/pt-spin-inlines.c
 create mode 100644 htl/pt-testcancel.c
 create mode 100644 htl/pt-yield.c
 create mode 100644 htl/shlib-versions
 create mode 100644 htl/tests/Makefile
 create mode 100644 htl/tests/README
 create mode 100644 htl/tests/test-1.c
 create mode 100644 htl/tests/test-10.c
 create mode 100644 htl/tests/test-11.c
 create mode 100644 htl/tests/test-12.c
 create mode 100644 htl/tests/test-13.c
 create mode 100644 htl/tests/test-14.c
 create mode 100644 htl/tests/test-15.c
 create mode 100644 htl/tests/test-16.c
 create mode 100644 htl/tests/test-17.c
 create mode 100644 htl/tests/test-2.c
 create mode 100644 htl/tests/test-3.c
 create mode 100644 htl/tests/test-4.c
 create mode 100644 htl/tests/test-5.c
 create mode 100644 htl/tests/test-6.c
 create mode 100644 htl/tests/test-7.c
 create mode 100644 htl/tests/test-8.c
 create mode 100644 htl/tests/test-9.c
 create mode 100644 htl/tests/test-__pthread_destroy_specific-skip.c
 copy sysdeps/{nptl => htl}/Implies (100%)
 create mode 100644 sysdeps/htl/Makeconfig
 create mode 100644 sysdeps/htl/Makefile
 create mode 100644 sysdeps/htl/Subdirs
 create mode 100644 sysdeps/htl/Versions
 create mode 100644 sysdeps/htl/bits/cancelation.h
 create mode 100644 sysdeps/htl/bits/pthread-np.h
 create mode 100644 sysdeps/htl/bits/pthread.h
 create mode 100644 sysdeps/htl/bits/pthreadtypes.h
 create mode 100644 sysdeps/htl/bits/semaphore.h
 create mode 100644 sysdeps/htl/bits/thread-shared-types.h
 create mode 100644 sysdeps/htl/bits/types/__pthread_key.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_attr.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_barrier.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_barrierattr.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_cond.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_condattr.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_mutex.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_mutexattr.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_once.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_rwlock.h
 create mode 100644 sysdeps/htl/bits/types/struct___pthread_rwlockattr.h
 create mode 100644 sysdeps/htl/flockfile.c
 create mode 100644 sysdeps/htl/fork.h
 create mode 100644 sysdeps/htl/ftrylockfile.c
 create mode 100644 sysdeps/htl/funlockfile.c
 create mode 100644 sysdeps/htl/libc-lockP.h
 create mode 100644 sysdeps/htl/old_pt-atfork.c
 create mode 100644 sysdeps/htl/pt-atfork.c
 create mode 100644 sysdeps/htl/pt-attr-destroy.c
 create mode 100644 sysdeps/htl/pt-attr-getdetachstate.c
 create mode 100644 sysdeps/htl/pt-attr-getguardsize.c
 create mode 100644 sysdeps/htl/pt-attr-getinheritsched.c
 create mode 100644 sysdeps/htl/pt-attr-getschedparam.c
 create mode 100644 sysdeps/htl/pt-attr-getschedpolicy.c
 create mode 100644 sysdeps/htl/pt-attr-getscope.c
 create mode 100644 sysdeps/htl/pt-attr-getstack.c
 create mode 100644 sysdeps/htl/pt-attr-getstackaddr.c
 create mode 100644 sysdeps/htl/pt-attr-getstacksize.c
 create mode 100644 sysdeps/htl/pt-attr-init.c
 create mode 100644 sysdeps/htl/pt-attr-setdetachstate.c
 create mode 100644 sysdeps/htl/pt-attr-setguardsize.c
 create mode 100644 sysdeps/htl/pt-attr-setinheritsched.c
 create mode 100644 sysdeps/htl/pt-attr-setschedparam.c
 create mode 100644 sysdeps/htl/pt-attr-setschedpolicy.c
 create mode 100644 sysdeps/htl/pt-attr-setscope.c
 create mode 100644 sysdeps/htl/pt-attr-setstack.c
 create mode 100644 sysdeps/htl/pt-attr-setstackaddr.c
 create mode 100644 sysdeps/htl/pt-attr-setstacksize.c
 create mode 100644 sysdeps/htl/pt-attr.c
 create mode 100644 sysdeps/htl/pt-barrier-destroy.c
 create mode 100644 sysdeps/htl/pt-barrier-init.c
 create mode 100644 sysdeps/htl/pt-barrier-wait.c
 create mode 100644 sysdeps/htl/pt-barrier.c
 create mode 100644 sysdeps/htl/pt-barrierattr-destroy.c
 create mode 100644 sysdeps/htl/pt-barrierattr-getpshared.c
 create mode 100644 sysdeps/htl/pt-barrierattr-init.c
 create mode 100644 sysdeps/htl/pt-barrierattr-setpshared.c
 create mode 100644 sysdeps/htl/pt-cond-brdcast.c
 create mode 100644 sysdeps/htl/pt-cond-destroy.c
 create mode 100644 sysdeps/htl/pt-cond-init.c
 create mode 100644 sysdeps/htl/pt-cond-signal.c
 create mode 100644 sysdeps/htl/pt-cond-timedwait.c
 create mode 100644 sysdeps/htl/pt-cond-wait.c
 create mode 100644 sysdeps/htl/pt-cond.c
 create mode 100644 sysdeps/htl/pt-condattr-destroy.c
 create mode 100644 sysdeps/htl/pt-condattr-getclock.c
 create mode 100644 sysdeps/htl/pt-condattr-getpshared.c
 create mode 100644 sysdeps/htl/pt-condattr-init.c
 create mode 100644 sysdeps/htl/pt-condattr-setclock.c
 create mode 100644 sysdeps/htl/pt-condattr-setpshared.c
 create mode 100644 sysdeps/htl/pt-destroy-specific.c
 create mode 100644 sysdeps/htl/pt-equal.c
 create mode 100644 sysdeps/htl/pt-getconcurrency.c
 create mode 100644 sysdeps/htl/pt-getcpuclockid.c
 create mode 100644 sysdeps/htl/pt-getschedparam.c
 create mode 100644 sysdeps/htl/pt-getspecific.c
 create mode 100644 sysdeps/htl/pt-init-specific.c
 create mode 100644 sysdeps/htl/pt-key-create.c
 create mode 100644 sysdeps/htl/pt-key-delete.c
 create mode 100644 sysdeps/htl/pt-key.h
 create mode 100644 sysdeps/htl/pt-kill.c
 create mode 100644 sysdeps/htl/pt-mutex-destroy.c
 create mode 100644 sysdeps/htl/pt-mutex-getprioceiling.c
 create mode 100644 sysdeps/htl/pt-mutex-init.c
 create mode 100644 sysdeps/htl/pt-mutex-lock.c
 create mode 100644 sysdeps/htl/pt-mutex-setprioceiling.c
 create mode 100644 sysdeps/htl/pt-mutex-timedlock.c
 create mode 100644 sysdeps/htl/pt-mutex-transfer-np.c
 create mode 100644 sysdeps/htl/pt-mutex-trylock.c
 create mode 100644 sysdeps/htl/pt-mutex-unlock.c
 create mode 100644 sysdeps/htl/pt-mutexattr-destroy.c
 create mode 100644 sysdeps/htl/pt-mutexattr-getprioceiling.c
 create mode 100644 sysdeps/htl/pt-mutexattr-getprotocol.c
 create mode 100644 sysdeps/htl/pt-mutexattr-getpshared.c
 create mode 100644 sysdeps/htl/pt-mutexattr-gettype.c
 create mode 100644 sysdeps/htl/pt-mutexattr-init.c
 create mode 100644 sysdeps/htl/pt-mutexattr-setprioceiling.c
 create mode 100644 sysdeps/htl/pt-mutexattr-setprotocol.c
 create mode 100644 sysdeps/htl/pt-mutexattr-setpshared.c
 create mode 100644 sysdeps/htl/pt-mutexattr-settype.c
 create mode 100644 sysdeps/htl/pt-mutexattr.c
 create mode 100644 sysdeps/htl/pt-once.c
 create mode 100644 sysdeps/htl/pt-rwlock-attr.c
 create mode 100644 sysdeps/htl/pt-rwlock-destroy.c
 create mode 100644 sysdeps/htl/pt-rwlock-init.c
 create mode 100644 sysdeps/htl/pt-rwlock-rdlock.c
 create mode 100644 sysdeps/htl/pt-rwlock-timedrdlock.c
 create mode 100644 sysdeps/htl/pt-rwlock-timedwrlock.c
 create mode 100644 sysdeps/htl/pt-rwlock-tryrdlock.c
 create mode 100644 sysdeps/htl/pt-rwlock-trywrlock.c
 create mode 100644 sysdeps/htl/pt-rwlock-unlock.c
 create mode 100644 sysdeps/htl/pt-rwlock-wrlock.c
 create mode 100644 sysdeps/htl/pt-rwlockattr-destroy.c
 create mode 100644 sysdeps/htl/pt-rwlockattr-getpshared.c
 create mode 100644 sysdeps/htl/pt-rwlockattr-init.c
 create mode 100644 sysdeps/htl/pt-rwlockattr-setpshared.c
 create mode 100644 sysdeps/htl/pt-setconcurrency.c
 create mode 100644 sysdeps/htl/pt-setschedparam.c
 create mode 100644 sysdeps/htl/pt-setschedprio.c
 create mode 100644 sysdeps/htl/pt-setspecific.c
 create mode 100644 sysdeps/htl/pt-spin.c
 create mode 100644 sysdeps/htl/pt-startup.c
 create mode 100644 sysdeps/htl/pthread-functions.h
 create mode 100644 sysdeps/htl/pthread.h
 create mode 100644 sysdeps/htl/pthreadP.h
 create mode 100644 sysdeps/htl/raise.c
 create mode 100644 sysdeps/htl/sem-close.c
 create mode 100644 sysdeps/htl/sem-destroy.c
 create mode 100644 sysdeps/htl/sem-getvalue.c
 create mode 100644 sysdeps/htl/sem-init.c
 create mode 100644 sysdeps/htl/sem-open.c
 create mode 100644 sysdeps/htl/sem-post.c
 create mode 100644 sysdeps/htl/sem-timedwait.c
 create mode 100644 sysdeps/htl/sem-trywait.c
 create mode 100644 sysdeps/htl/sem-unlink.c
 create mode 100644 sysdeps/htl/sem-wait.c
 create mode 100644 sysdeps/htl/shm-directory.h
 create mode 100644 sysdeps/htl/timer_routines.h
 create mode 100644 sysdeps/hurd/htl/pt-kill.c
 create mode 100644 sysdeps/i386/htl/bits/pthreadtypes-arch.h
 create mode 100644 sysdeps/i386/htl/machine-sp.h
 create mode 100644 sysdeps/i386/htl/pt-machdep.h
 create mode 100644 sysdeps/mach/htl/Implies
 create mode 100644 sysdeps/mach/htl/bits/spin-lock-inline.h
 create mode 100644 sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h
 create mode 100644 sysdeps/mach/htl/pt-block.c
 create mode 100644 sysdeps/mach/htl/pt-spin.c
 create mode 100644 sysdeps/mach/htl/pt-stack-alloc.c
 create mode 100644 sysdeps/mach/htl/pt-thread-alloc.c
 create mode 100644 sysdeps/mach/htl/pt-thread-start.c
 create mode 100644 sysdeps/mach/htl/pt-thread-terminate.c
 create mode 100644 sysdeps/mach/htl/pt-timedblock.c
 create mode 100644 sysdeps/mach/htl/pt-wakeup.c
 create mode 100644 sysdeps/mach/hurd/htl/Implies
 create mode 100644 sysdeps/mach/hurd/htl/bits/pthread-np.h
 create mode 100644 sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h
 create mode 100644 sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-attr-setstacksize.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-docancel.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-consistent.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-destroy.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-init.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-lock.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-timedlock.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-trylock.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex-unlock.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutex.h
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-init.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-mutexattr-settype.c
 copy nptl/elision-conf.h => sysdeps/mach/hurd/htl/pt-mutexattr.c (100%)
 create mode 100644 sysdeps/mach/hurd/htl/pt-sigstate-destroy.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-sigstate-init.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-sigstate.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-sysdep.c
 create mode 100644 sysdeps/mach/hurd/htl/pt-sysdep.h
 create mode 100644 sysdeps/mach/hurd/i386/htl/Implies
 create mode 100644 sysdeps/mach/hurd/i386/htl/pt-machdep.c
 create mode 100644 sysdeps/mach/hurd/i386/htl/pt-setup.c
 create mode 100644 sysdeps/mach/hurd/i386/libpthread.abilist


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]