This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch sthibaul/hurd-builds created. glibc-2.27.9000-232-g77d43b1
- From: sthibaul at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 19 Mar 2018 01:51:05 -0000
- Subject: GNU C Library master sources branch sthibaul/hurd-builds created. glibc-2.27.9000-232-g77d43b1
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, sthibaul/hurd-builds has been created
at 77d43b1ef9f2d643ac0fd88fea523032c57c685a (commit)
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=77d43b1ef9f2d643ac0fd88fea523032c57c685a
commit 77d43b1ef9f2d643ac0fd88fea523032c57c685a
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Mon Mar 19 02:40:39 2018 +0100
Plug htl
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
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=554be7984b8e87f8037df0405097cc854edb4797
commit 554be7984b8e87f8037df0405097cc854edb4797
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Mon Mar 19 02:40:33 2018 +0100
Import Hurd libpthread git snapshot 3931478319b3
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..79bb564
--- /dev/null
+++ b/htl/Versions
@@ -0,0 +1,155 @@
+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_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..ecbba35
--- /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..4347e68
--- /dev/null
+++ b/htl/forward.c
@@ -0,0 +1,281 @@
+/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, 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)
+ 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)
+ {
+ 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)
+ {
+ 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)
+ 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)
+ fork_handlers->prev = new;
+ fork_handlers = new;
+ if (!fork_last_handler)
+ 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)
+ {
+ 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)
+ 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..2270844
--- /dev/null
+++ b/htl/libc_pthread_init.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, 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..76cb0eb
--- /dev/null
+++ b/htl/lockfile.c
@@ -0,0 +1,60 @@
+/* lockfile - Handle locking and unlocking of streams. Hurd cthreads 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..22a3000
--- /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..b7e9a93
--- /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)
+ 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..41e8507
--- /dev/null
+++ b/htl/pt-create.c
@@ -0,0 +1,247 @@
+/* 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)
+ {
+ struct rlimit rlim;
+ __getrlimit(RLIMIT_STACK, &rlim);
+ if (rlim.rlim_cur != RLIM_INFINITY)
+ stacksize = rlim.rlim_cur;
+ if (!stacksize)
+ 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)
+ {
+ 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..1807a1d
--- /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..f22c1a0
--- /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..14e560e
--- /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;
+ *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..f76ad57
--- /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..094c596
--- /dev/null
+++ b/htl/pt-initialize.c
@@ -0,0 +1,84 @@
+/* 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..1f17f25
--- /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..1150b33
--- /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)
+ *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..44e43dd
--- /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);
+
+ 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..b015f87
--- /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)
+ *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..f17a0f8
--- /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)
+ *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..7402d87
--- /dev/null
+++ b/htl/pt-sigmask.c
@@ -0,0 +1,32 @@
+/* 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..40a692b
--- /dev/null
+++ b/htl/pt-spin-inlines.c
@@ -0,0 +1,32 @@
+/* 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..5cf6c8b
--- /dev/null
+++ b/htl/pt-yield.c
@@ -0,0 +1,25 @@
+/* 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/tags b/htl/tags
new file mode 100644
index 0000000..8bb273a
--- /dev/null
+++ b/htl/tags
@@ -0,0 +1,739 @@
+!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME Exuberant Ctags //
+!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
+!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
+CFLAGS tests/Makefile /^CFLAGS=-Wall -g$/;" m
+CFLAGS-lockfile.c Makefile /^CFLAGS-lockfile.c = -D_IO_MTSAFE_IO$/;" m
+CHECK_OBJS tests/Makefile /^CHECK_OBJS := $(addsuffix .o,$(basename $(notdir $(CHECK_SRC))))$/;" m
+CHECK_PROGS tests/Makefile /^CHECK_PROGS := $(basename $(notdir $(CHECK_SRC))) \\$/;" m
+CHECK_SRC tests/Makefile /^CHECK_SRC := test-1.c test-2.c test-3.c test-6.c test-7.c test-8.c \\$/;" m
+CTHREAD_KEY_INVALID pthread/cthreads-compat.c 22;" d file:
+FORWARD forward.c 53;" d file:
+FORWARD2 forward.c 32;" d file:
+FORWARD_NORETURN forward.c 43;" d file:
+HURD_TLS_DESC_DECL sysdeps/mach/hurd/i386/pt-machdep.c 27;" d file:
+INSTALL_ROOT_CPPFLAGS tests/Makefile /^INSTALL_ROOT_CPPFLAGS = -isystem $(INSTALL_ROOT)\/include$/;" m
+INSTALL_ROOT_LDFLAGS tests/Makefile /^INSTALL_ROOT_LDFLAGS = -L$(INSTALL_ROOT)\/lib -Wl,-rpath,$(INSTALL_ROOT)\/lib$/;" m
+KEYS tests/test-7.c 10;" d file:
+LCLHDRS Makefile /^LCLHDRS :=$/;" m
+LDLIBS tests/Makefile /^LDLIBS = -lpthread$/;" m
+LOSE sysdeps/generic/pt-mutex-timedlock.c 24;" d file:
+LOSE sysdeps/generic/pt-mutex-trylock.c 23;" d file:
+LOSE sysdeps/generic/pt-mutex-unlock.c 23;" d file:
+MICROKERNEL Makefile /^MICROKERNEL := mach$/;" m
+MTX_TYPE sysdeps/mach/hurd/pt-mutex.h 86;" d
+NOTRECOVERABLE_ID sysdeps/mach/hurd/pt-mutex.h 24;" d
+N_k tests/test-__pthread_destroy_specific-skip.c 11;" d file:
+PTFAVAIL sysdeps/pthread/libc-lockP.h 44;" d
+PTFAVAIL sysdeps/pthread/libc-lockP.h 50;" d
+PTFAVAIL sysdeps/pthread/libc-lockP.h 56;" d
+PTHFCT_CALL sysdeps/pthread/pthread-functions.h 137;" d
+PTHREAD_BARRIER_SERIAL_THREAD sysdeps/generic/pthread/pthread.h 757;" d
+PTHREAD_CANCELED sysdeps/generic/pthread/pthread.h 713;" d
+PTHREAD_CANCEL_ASYNCHRONOUS sysdeps/generic/pthread/pthread.h 705;" d
+PTHREAD_CANCEL_DEFERRED sysdeps/generic/pthread/pthread.h 704;" d
+PTHREAD_CANCEL_DISABLE sysdeps/generic/pthread/pthread.h 697;" d
+PTHREAD_CANCEL_ENABLE sysdeps/generic/pthread/pthread.h 698;" d
+PTHREAD_COND_INITIALIZER sysdeps/generic/pthread/pthread.h 485;" d
+PTHREAD_CREATE_DETACHED sysdeps/generic/pthread/pthread.h 74;" d
+PTHREAD_CREATE_JOINABLE sysdeps/generic/pthread/pthread.h 73;" d
+PTHREAD_DETACHED pthread/pt-internal.h /^ PTHREAD_DETACHED,$/;" e enum:pthread_state
+PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP sysdeps/generic/pthread/pthread.h 372;" d
+PTHREAD_EXITED pthread/pt-internal.h /^ PTHREAD_EXITED,$/;" e enum:pthread_state
+PTHREAD_EXPLICIT_SCHED sysdeps/generic/pthread/pthread.h 65;" d
+PTHREAD_INHERIT_SCHED sysdeps/generic/pthread/pthread.h 66;" d
+PTHREAD_JOINABLE pthread/pt-internal.h /^ PTHREAD_JOINABLE = 0,$/;" e enum:pthread_state
+PTHREAD_KEY_INVALID sysdeps/generic/pt-key.h 26;" d
+PTHREAD_KEY_MEMBERS pthread/pt-internal.h 54;" d
+PTHREAD_KEY_MEMBERS sysdeps/generic/pt-key.h 22;" d
+PTHREAD_MUTEX_DEFAULT sysdeps/generic/pthread/pthread.h 265;" d
+PTHREAD_MUTEX_ERRORCHECK sysdeps/generic/pthread/pthread.h 263;" d
+PTHREAD_MUTEX_ERRORCHECK_NP sysdeps/generic/pthread/pthread.h 259;" d
+PTHREAD_MUTEX_FAST_NP sysdeps/generic/pthread/pthread.h 269;" d
+PTHREAD_MUTEX_INITIALIZER sysdeps/generic/pthread/pthread.h 368;" d
+PTHREAD_MUTEX_NORMAL sysdeps/generic/pthread/pthread.h 262;" d
+PTHREAD_MUTEX_RECURSIVE sysdeps/generic/pthread/pthread.h 264;" d
+PTHREAD_MUTEX_RECURSIVE_NP sysdeps/generic/pthread/pthread.h 260;" d
+PTHREAD_MUTEX_ROBUST sysdeps/generic/pthread/pthread.h 274;" d
+PTHREAD_MUTEX_STALLED sysdeps/generic/pthread/pthread.h 273;" d
+PTHREAD_MUTEX_TIMED_NP sysdeps/generic/pthread/pthread.h 258;" d
+PTHREAD_ONCE_INIT sysdeps/generic/pthread/pthread.h 804;" d
+PTHREAD_PRIO_INHERIT sysdeps/generic/pthread/pthread.h 254;" d
+PTHREAD_PRIO_INHERIT_NP sysdeps/generic/pthread/pthread.h 250;" d
+PTHREAD_PRIO_NONE sysdeps/generic/pthread/pthread.h 253;" d
+PTHREAD_PRIO_NONE_NP sysdeps/generic/pthread/pthread.h 249;" d
+PTHREAD_PRIO_PROTECT sysdeps/generic/pthread/pthread.h 255;" d
+PTHREAD_PRIO_PROTECT_NP sysdeps/generic/pthread/pthread.h 251;" d
+PTHREAD_PROCESS_PRIVATE sysdeps/generic/pthread/pthread.h 58;" d
+PTHREAD_PROCESS_SHARED sysdeps/generic/pthread/pthread.h 59;" d
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP sysdeps/generic/pthread/pthread.h 374;" d
+PTHREAD_RWLOCK_INITIALIZER sysdeps/generic/pthread/pthread.h 633;" d
+PTHREAD_SCOPE_PROCESS sysdeps/generic/pthread/pthread.h 70;" d
+PTHREAD_SCOPE_SYSTEM sysdeps/generic/pthread/pthread.h 69;" d
+PTHREAD_SPINLOCK_INITIALIZER sysdeps/generic/pthread/pthread.h 526;" d
+PTHREAD_STACK_DEFAULT sysdeps/mach/hurd/pt-sysdep.h 28;" d
+PTHREAD_SYSDEP_MEMBERS pthread/pt-internal.h 58;" d
+PTHREAD_SYSDEP_MEMBERS sysdeps/mach/hurd/pt-sysdep.h 30;" d
+PTHREAD_TERMINATED pthread/pt-internal.h /^ PTHREAD_TERMINATED$/;" e enum:pthread_state
+PT_MTX_ERRORCHECK sysdeps/mach/hurd/pt-mutex.h 83;" d
+PT_MTX_NORMAL sysdeps/mach/hurd/pt-mutex.h 81;" d
+PT_MTX_RECURSIVE sysdeps/mach/hurd/pt-mutex.h 82;" d
+ROBUST_LOCK sysdeps/mach/hurd/pt-mutex.h 28;" d
+SEM_FAILED sysdeps/pthread/semaphore.h 33;" d
+SYSDEPS Makefile /^SYSDEPS := lockfile$/;" m
+SYSDEP_PATH Makefile /^SYSDEP_PATH = $(srcdir)\/sysdeps\/$(MICROKERNEL)\/hurd\/i386 \\$/;" m
+TEST tests/test-3.c 37;" d file:
+TEST1 tests/test-3.c 30;" d file:
+THREADS tests/test-1.c 10;" d file:
+THREADS tests/test-11.c 10;" d file:
+THREADS tests/test-15.c 12;" d file:
+THREADS tests/test-6.c 9;" d file:
+THREADS tests/test-7.c 9;" d file:
+THREADS tests/test-8.c 8;" d file:
+THREADS tests/test-9.c 10;" d file:
+UNREGISTER_ATFORK sysdeps/generic/fork.h 21;" d
+WAITS tests/test-6.c 10;" d file:
+_BITS_ATOMIC_H sysdeps/i386/bits/pt-atomic.h 20;" d
+_BITS_BARRIER_ATTR_H sysdeps/pthread/bits/barrier-attr.h 20;" d
+_BITS_BARRIER_H sysdeps/pthread/bits/barrier.h 20;" d
+_BITS_CANCELATION_H sysdeps/pthread/bits/cancelation.h 20;" d
+_BITS_CONDITION_ATTR_H sysdeps/pthread/bits/condition-attr.h 20;" d
+_BITS_CONDITION_H sysdeps/pthread/bits/condition.h 20;" d
+_BITS_LIBC_LOCKP_H sysdeps/pthread/libc-lockP.h 20;" d
+_BITS_MUTEX_ATTR_H sysdeps/pthread/bits/mutex-attr.h 20;" d
+_BITS_MUTEX_H sysdeps/mach/hurd/bits/mutex.h 20;" d
+_BITS_MUTEX_H sysdeps/pthread/bits/mutex.h 22;" d
+_BITS_ONCE_H sysdeps/pthread/bits/once.h 20;" d
+_BITS_PTHREADTYPES_ARCH_H sysdeps/i386/bits/pthreadtypes-arch.h 19;" d
+_BITS_PTHREADTYPES_H sysdeps/pthread/bits/pthreadtypes.h 24;" d
+_BITS_PTHREAD_H sysdeps/pthread/bits/pthread.h 20;" d
+_BITS_PTHREAD_NP_H sysdeps/mach/hurd/bits/pthread-np.h 24;" d
+_BITS_PTHREAD_NP_H sysdeps/pthread/bits/pthread-np.h 24;" d
+_BITS_RWLOCK_ATTR_H sysdeps/pthread/bits/rwlock-attr.h 20;" d
+_BITS_RWLOCK_H sysdeps/pthread/bits/rwlock.h 20;" d
+_BITS_SEMAPHORE_H sysdeps/pthread/bits/semaphore.h 20;" d
+_BITS_SPIN_LOCK_H sysdeps/mach/bits/spin-lock.h 20;" d
+_BITS_SPIN_LOCK_INLINE_H sysdeps/mach/bits/spin-lock-inline.h 20;" d
+_BITS_THREAD_ATTR_H sysdeps/pthread/bits/thread-attr.h 20;" d
+_BITS_THREAD_SPECIFIC_H sysdeps/pthread/bits/thread-specific.h 20;" d
+_FORCE_INLINES pthread/pt-spin-inlines.c 22;" d file:
+_GNU_SOURCE tests/test-1.c 1;" d file:
+_GNU_SOURCE tests/test-10.c 3;" d file:
+_GNU_SOURCE tests/test-11.c 3;" d file:
+_GNU_SOURCE tests/test-12.c 3;" d file:
+_GNU_SOURCE tests/test-13.c 3;" d file:
+_GNU_SOURCE tests/test-14.c 3;" d file:
+_GNU_SOURCE tests/test-15.c 3;" d file:
+_GNU_SOURCE tests/test-16.c 3;" d file:
+_GNU_SOURCE tests/test-17.c 4;" d file:
+_GNU_SOURCE tests/test-2.c 2;" d file:
+_GNU_SOURCE tests/test-3.c 3;" d file:
+_GNU_SOURCE tests/test-4.c 3;" d file:
+_GNU_SOURCE tests/test-5.c 3;" d file:
+_GNU_SOURCE tests/test-6.c 1;" d file:
+_GNU_SOURCE tests/test-7.c 1;" d file:
+_GNU_SOURCE tests/test-8.c 1;" d file:
+_GNU_SOURCE tests/test-9.c 3;" d file:
+_GNU_SOURCE tests/test-__pthread_destroy_specific-skip.c 4;" d file:
+_IO_flockfile lockfile.c 41;" d file:
+_IO_ftrylockfile lockfile.c 43;" d file:
+_IO_funlockfile lockfile.c 42;" d file:
+_MACHINE_SP_H sysdeps/i386/machine-sp.h 20;" d
+_POSIX_THREAD_THREADS_MAX sysdeps/mach/hurd/pt-sysdep.h 25;" d
+_PTHREADP_H sysdeps/pthread/pthreadP.h 19;" d
+_PTHREADTYPES_H sysdeps/generic/pthread/pthreadtypes.h 23;" d
+_PTHREAD_FUNCTIONS_H sysdeps/pthread/pthread-functions.h 20;" d
+_PTHREAD_H sysdeps/generic/pthread/pthread.h 23;" d
+_PT_INTERNAL_H pthread/pt-internal.h 20;" d
+_PT_MACHDEP_H sysdeps/i386/pt-machdep.h 20;" d
+_PT_MUTEX_H sysdeps/mach/hurd/pt-mutex.h 21;" d
+_PT_SYSDEP_H sysdeps/mach/hurd/pt-sysdep.h 20;" d
+_SEMAPHORE_H sysdeps/pthread/semaphore.h 19;" d
+_THREAD_SHARED_TYPES_H sysdeps/pthread/bits/thread-shared-types.h 20;" d
+_TIMER_ROUTINES_H sysdeps/generic/timer_routines.h 21;" d
+__EBUSY sysdeps/mach/bits/spin-lock-inline.h 32;" d
+__PTHREAD_COND_INITIALIZER sysdeps/pthread/bits/condition.h 35;" d
+__PTHREAD_CREATE_DETACHED sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_CREATE_DETACHED$/;" e enum:__pthread_detachstate
+__PTHREAD_CREATE_JOINABLE sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_CREATE_JOINABLE = 0,$/;" e enum:__pthread_detachstate
+__PTHREAD_ERRORCHECK_MUTEXATTR sysdeps/pthread/bits/mutex.h 50;" d
+__PTHREAD_ERRORCHECK_MUTEX_INITIALIZER sysdeps/mach/hurd/bits/mutex.h 43;" d
+__PTHREAD_ERRORCHECK_MUTEX_INITIALIZER sysdeps/pthread/bits/mutex.h 52;" d
+__PTHREAD_EXPLICIT_SCHED sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_EXPLICIT_SCHED = 0,$/;" e enum:__pthread_inheritsched
+__PTHREAD_INHERIT_SCHED sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_INHERIT_SCHED$/;" e enum:__pthread_inheritsched
+__PTHREAD_MUTEX_ERRORCHECK sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_MUTEX_ERRORCHECK,$/;" e enum:__pthread_mutex_type
+__PTHREAD_MUTEX_INITIALIZER sysdeps/mach/hurd/bits/mutex.h 38;" d
+__PTHREAD_MUTEX_INITIALIZER sysdeps/pthread/bits/mutex.h 47;" d
+__PTHREAD_MUTEX_RECURSIVE sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_MUTEX_RECURSIVE$/;" e enum:__pthread_mutex_type
+__PTHREAD_MUTEX_ROBUST sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_MUTEX_ROBUST = 0x100$/;" e enum:__pthread_mutex_robustness
+__PTHREAD_MUTEX_STALLED sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_MUTEX_STALLED,$/;" e enum:__pthread_mutex_robustness
+__PTHREAD_MUTEX_TIMED sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_MUTEX_TIMED,$/;" e enum:__pthread_mutex_type
+__PTHREAD_ONCE_INIT sysdeps/pthread/bits/once.h 30;" d
+__PTHREAD_PRIO_INHERIT sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_PRIO_INHERIT,$/;" e enum:__pthread_mutex_protocol
+__PTHREAD_PRIO_NONE sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_PRIO_NONE= 0,$/;" e enum:__pthread_mutex_protocol
+__PTHREAD_PRIO_PROTECT sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_PRIO_PROTECT$/;" e enum:__pthread_mutex_protocol
+__PTHREAD_PROCESS_PRIVATE sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_PROCESS_PRIVATE = 0,$/;" e enum:__pthread_process_shared
+__PTHREAD_PROCESS_SHARED sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_PROCESS_SHARED$/;" e enum:__pthread_process_shared
+__PTHREAD_RECURSIVE_MUTEXATTR sysdeps/pthread/bits/mutex.h 56;" d
+__PTHREAD_RECURSIVE_MUTEX_INITIALIZER sysdeps/mach/hurd/bits/mutex.h 46;" d
+__PTHREAD_RECURSIVE_MUTEX_INITIALIZER sysdeps/pthread/bits/mutex.h 58;" d
+__PTHREAD_RWLOCK_INITIALIZER sysdeps/pthread/bits/rwlock.h 41;" d
+__PTHREAD_SCOPE_PROCESS sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_SCOPE_PROCESS$/;" e enum:__pthread_contentionscope
+__PTHREAD_SCOPE_SYSTEM sysdeps/generic/pthread/pthreadtypes.h /^ __PTHREAD_SCOPE_SYSTEM = 0,$/;" e enum:__pthread_contentionscope
+__PTHREAD_SPIN_COUNT sysdeps/posix/pt-spin.c 25;" d file:
+__PTHREAD_SPIN_LOCK_INITIALIZER sysdeps/mach/bits/spin-lock.h 30;" d
+__PT_SPIN_INLINE pthread/pt-spin-inlines.c 23;" d file:
+__PT_SPIN_INLINE sysdeps/mach/bits/spin-lock-inline.h 36;" d
+__SEMAPHORE_INITIALIZER sysdeps/pthread/bits/semaphore.h 40;" d
+___pthread_init pthread/pt-initialize.c /^___pthread_init (void)$/;" f
+___pthread_self sysdeps/mach/hurd/pt-sysdep.c /^__thread struct __pthread *___pthread_self;$/;" v typeref:struct:__pthread
+__arg sysdeps/pthread/bits/cancelation.h /^ void *__arg;$/;" m struct:__pthread_cancelation_handler
+__atomic_dec sysdeps/i386/bits/pt-atomic.h /^__atomic_dec (__atomic_t *__var)$/;" f
+__atomic_dec_and_test sysdeps/i386/bits/pt-atomic.h /^__atomic_dec_and_test (__atomic_t *__var)$/;" f
+__atomic_inc sysdeps/i386/bits/pt-atomic.h /^__atomic_inc (__atomic_t *__var)$/;" f
+__atomic_t sysdeps/i386/bits/pt-atomic.h /^typedef __volatile int __atomic_t;$/;" t
+__atomicptr_compare_and_swap sysdeps/i386/bits/pt-atomic.h /^__atomicptr_compare_and_swap (__atomicptr_t *__ptr, void *__oldval,$/;" f
+__atomicptr_t sysdeps/i386/bits/pt-atomic.h /^typedef __volatile int * __atomicptr_t;$/;" t
+__attr sysdeps/pthread/bits/barrier.h /^ struct __pthread_barrierattr *__attr;$/;" m struct:__pthread_barrier typeref:struct:__pthread_barrier::__pthread_barrierattr
+__attr sysdeps/pthread/bits/condition.h /^ struct __pthread_condattr *__attr;$/;" m struct:__pthread_cond typeref:struct:__pthread_cond::__pthread_condattr
+__attr sysdeps/pthread/bits/mutex.h /^ struct __pthread_mutexattr *__attr;$/;" m struct:__pthread_mutex typeref:struct:__pthread_mutex::__pthread_mutexattr
+__attr sysdeps/pthread/bits/rwlock.h /^ struct __pthread_rwlockattr *__attr;$/;" m struct:__pthread_rwlock typeref:struct:__pthread_rwlock::__pthread_rwlockattr
+__clock sysdeps/pthread/bits/condition-attr.h /^ __clockid_t __clock;$/;" m struct:__pthread_condattr
+__cnt sysdeps/mach/hurd/bits/mutex.h /^ unsigned int __cnt;$/;" m struct:__pthread_mutex
+__contentionscope sysdeps/pthread/bits/thread-attr.h /^ enum __pthread_contentionscope __contentionscope;$/;" m struct:__pthread_attr typeref:enum:__pthread_attr::__pthread_contentionscope
+__count sysdeps/pthread/bits/barrier.h /^ unsigned __count; \/* Number of threads that must wait before$/;" m struct:__pthread_barrier
+__cthread_detach pthread/cthreads-compat.c /^__cthread_detach (__cthread_t thread)$/;" f
+__cthread_fn_t sysdeps/pthread/pthread.h /^typedef void * (*__cthread_fn_t)(void *__arg);$/;" t
+__cthread_key_t sysdeps/pthread/pthread.h /^typedef int __cthread_key_t;$/;" t
+__cthread_t sysdeps/pthread/pthread.h /^typedef struct __cthread *__cthread_t;$/;" t typeref:struct:__cthread
+__cthreadscompat1 sysdeps/pthread/bits/mutex.h /^ char *__cthreadscompat1;$/;" m struct:__pthread_mutex
+__data sysdeps/pthread/bits/barrier.h /^ void *__data;$/;" m struct:__pthread_barrier
+__data sysdeps/pthread/bits/condition.h /^ void *__data;$/;" m struct:__pthread_cond
+__data sysdeps/pthread/bits/mutex.h /^ void *__data;$/;" m struct:__pthread_mutex
+__data sysdeps/pthread/bits/rwlock.h /^ void *__data;$/;" m struct:__pthread_rwlock
+__data sysdeps/pthread/bits/semaphore.h /^ void *__data;$/;" m struct:__semaphore
+__detachstate sysdeps/pthread/bits/thread-attr.h /^ enum __pthread_detachstate __detachstate;$/;" m struct:__pthread_attr typeref:enum:__pthread_attr::__pthread_detachstate
+__extern_always_inline sysdeps/generic/pthread/pthread.h 35;" d
+__extern_always_inline sysdeps/generic/pthread/pthread.h 38;" d
+__extern_always_inline sysdeps/generic/pthread/pthread.h 43;" d
+__extern_inline sysdeps/generic/pthread/pthread.h 33;" d
+__extern_inline sysdeps/generic/pthread/pthread.h 42;" d
+__flags sysdeps/mach/hurd/bits/mutex.h /^ int __flags;$/;" m struct:__pthread_mutex
+__flockfile sysdeps/pthread/flockfile.c /^__flockfile (FILE *stream)$/;" f
+__ftrylockfile sysdeps/pthread/ftrylockfile.c /^__ftrylockfile (FILE *stream)$/;" f
+__funlockfile sysdeps/pthread/funlockfile.c /^__funlockfile (FILE *stream)$/;" f
+__guardsize sysdeps/pthread/bits/thread-attr.h /^ size_t __guardsize;$/;" m struct:__pthread_attr
+__handler sysdeps/pthread/bits/cancelation.h /^ void (*__handler)(void *);$/;" m struct:__pthread_cancelation_handler
+__held sysdeps/pthread/bits/mutex.h /^ __pthread_spinlock_t __held;$/;" m struct:__pthread_mutex
+__held sysdeps/pthread/bits/rwlock.h /^ __pthread_spinlock_t __held;$/;" m struct:__pthread_rwlock
+__impl sysdeps/pthread/bits/condition.h /^ struct __pthread_condimpl *__impl;$/;" m struct:__pthread_cond typeref:struct:__pthread_cond::__pthread_condimpl
+__inheritsched sysdeps/pthread/bits/thread-attr.h /^ enum __pthread_inheritsched __inheritsched;$/;" m struct:__pthread_attr typeref:enum:__pthread_attr::__pthread_inheritsched
+__libc_alloca_cutoff pthread/alloca_cutoff.c /^__libc_alloca_cutoff (size_t size)$/;" f
+__libc_getspecific sysdeps/pthread/libc-lockP.h 68;" d
+__libc_key_create sysdeps/pthread/libc-lockP.h 64;" d
+__libc_key_t sysdeps/pthread/libc-lockP.h /^typedef pthread_key_t __libc_key_t;$/;" t
+__libc_maybe_call sysdeps/pthread/libc-lockP.h 34;" d
+__libc_maybe_call sysdeps/pthread/libc-lockP.h 38;" d
+__libc_ptf_call sysdeps/pthread/libc-lockP.h 45;" d
+__libc_ptf_call sysdeps/pthread/libc-lockP.h 51;" d
+__libc_ptf_call sysdeps/pthread/libc-lockP.h 57;" d
+__libc_ptf_call_always sysdeps/pthread/libc-lockP.h 47;" d
+__libc_ptf_call_always sysdeps/pthread/libc-lockP.h 53;" d
+__libc_ptf_call_always sysdeps/pthread/libc-lockP.h 59;" d
+__libc_pthread_init libc_pthread_init.c /^__libc_pthread_init (const struct pthread_functions *functions)$/;" f
+__libc_setspecific sysdeps/pthread/libc-lockP.h 72;" d
+__lock sysdeps/mach/hurd/bits/mutex.h /^ unsigned int __lock;$/;" m struct:__pthread_mutex
+__lock sysdeps/pthread/bits/barrier.h /^ __pthread_spinlock_t __lock;$/;" m struct:__pthread_barrier
+__lock sysdeps/pthread/bits/condition.h /^ __pthread_spinlock_t __lock;$/;" m struct:__pthread_cond
+__lock sysdeps/pthread/bits/mutex.h /^ __pthread_spinlock_t __lock;$/;" m struct:__pthread_mutex
+__lock sysdeps/pthread/bits/once.h /^ __pthread_spinlock_t __lock;$/;" m struct:__pthread_once
+__lock sysdeps/pthread/bits/rwlock.h /^ __pthread_spinlock_t __lock;$/;" m struct:__pthread_rwlock
+__lock sysdeps/pthread/bits/semaphore.h /^ __pthread_spinlock_t __lock;$/;" m struct:__semaphore
+__locks sysdeps/pthread/bits/mutex.h /^ unsigned __locks;$/;" m struct:__pthread_mutex
+__mutex_type sysdeps/pthread/bits/mutex-attr.h /^ enum __pthread_mutex_type __mutex_type;$/;" m struct:__pthread_mutexattr typeref:enum:__pthread_mutexattr::__pthread_mutex_type
+__mutex_unlock_solid pthread/cthreads-compat.c /^__mutex_unlock_solid (void *lock)$/;" f
+__need_size_t sysdeps/pthread/bits/thread-attr.h 24;" d
+__next sysdeps/pthread/bits/cancelation.h /^ struct __pthread_cancelation_handler *__next;$/;" m struct:__pthread_cancelation_handler typeref:struct:__pthread_cancelation_handler::__pthread_cancelation_handler
+__owner sysdeps/pthread/bits/mutex.h /^ void *__owner;$/;" m struct:__pthread_mutex
+__owner_id sysdeps/mach/hurd/bits/mutex.h /^ unsigned int __owner_id;$/;" m struct:__pthread_mutex
+__pending sysdeps/pthread/bits/barrier.h /^ unsigned __pending; \/* Number of that still need to wait on$/;" m struct:__pthread_barrier
+__prioceiling sysdeps/pthread/bits/mutex-attr.h /^ int __prioceiling;$/;" m struct:__pthread_mutexattr
+__protocol sysdeps/pthread/bits/mutex-attr.h /^ enum __pthread_mutex_protocol __protocol;$/;" m struct:__pthread_mutexattr typeref:enum:__pthread_mutexattr::__pthread_mutex_protocol
+__pshared sysdeps/pthread/bits/barrier-attr.h /^ enum __pthread_process_shared __pshared;$/;" m struct:__pthread_barrierattr typeref:enum:__pthread_barrierattr::__pthread_process_shared
+__pshared sysdeps/pthread/bits/condition-attr.h /^ enum __pthread_process_shared __pshared;$/;" m struct:__pthread_condattr typeref:enum:__pthread_condattr::__pthread_process_shared
+__pshared sysdeps/pthread/bits/mutex-attr.h /^ enum __pthread_process_shared __pshared;$/;" m struct:__pthread_mutexattr typeref:enum:__pthread_mutexattr::__pthread_process_shared
+__pshared sysdeps/pthread/bits/rwlock-attr.h /^ enum __pthread_process_shared __pshared;$/;" m struct:__pthread_rwlockattr typeref:enum:__pthread_rwlockattr::__pthread_process_shared
+__pshared sysdeps/pthread/bits/semaphore.h /^ int __pshared;$/;" m struct:__semaphore
+__pthread pthread/pt-internal.h /^struct __pthread$/;" s
+__pthread_alloc pthread/pt-alloc.c /^__pthread_alloc (struct __pthread **pthread)$/;" f
+__pthread_atfork sysdeps/pthread/libc-lockP.h 175;" d
+__pthread_attr sysdeps/pthread/bits/thread-attr.h /^struct __pthread_attr$/;" s
+__pthread_attr_destroy sysdeps/generic/pt-attr-destroy.c /^__pthread_attr_destroy (pthread_attr_t *attr)$/;" f
+__pthread_attr_getdetachstate sysdeps/generic/pt-attr-getdetachstate.c /^__pthread_attr_getdetachstate (const pthread_attr_t *attr,$/;" f
+__pthread_attr_getinheritsched sysdeps/generic/pt-attr-getinheritsched.c /^__pthread_attr_getinheritsched (const pthread_attr_t *attr,$/;" f
+__pthread_attr_getschedparam sysdeps/generic/pt-attr-getschedparam.c /^__pthread_attr_getschedparam (const pthread_attr_t *attr,$/;" f
+__pthread_attr_getschedpolicy sysdeps/generic/pt-attr-getschedpolicy.c /^__pthread_attr_getschedpolicy (const pthread_attr_t *attr,$/;" f
+__pthread_attr_getscope sysdeps/generic/pt-attr-getscope.c /^__pthread_attr_getscope (const pthread_attr_t *attr,$/;" f
+__pthread_attr_getstack sysdeps/generic/pt-attr-getstack.c /^__pthread_attr_getstack (const pthread_attr_t *attr,$/;" f
+__pthread_attr_init sysdeps/generic/pt-attr-init.c /^__pthread_attr_init (pthread_attr_t *attr)$/;" f
+__pthread_attr_setdetachstate sysdeps/generic/pt-attr-setdetachstate.c /^__pthread_attr_setdetachstate (pthread_attr_t *attr,$/;" f
+__pthread_attr_setinheritsched sysdeps/generic/pt-attr-setinheritsched.c /^__pthread_attr_setinheritsched (pthread_attr_t *attr,$/;" f
+__pthread_attr_setschedparam sysdeps/generic/pt-attr-setschedparam.c /^__pthread_attr_setschedparam (pthread_attr_t *attr,$/;" f
+__pthread_attr_setschedpolicy sysdeps/generic/pt-attr-setschedpolicy.c /^__pthread_attr_setschedpolicy (pthread_attr_t *attr,$/;" f
+__pthread_attr_setscope sysdeps/generic/pt-attr-setscope.c /^__pthread_attr_setscope (pthread_attr_t *attr,$/;" f
+__pthread_barrier sysdeps/pthread/bits/barrier.h /^struct __pthread_barrier$/;" s
+__pthread_barrierattr sysdeps/pthread/bits/barrier-attr.h /^struct __pthread_barrierattr$/;" s
+__pthread_block sysdeps/mach/pt-block.c /^__pthread_block (struct __pthread *thread)$/;" f
+__pthread_cancelation_handler sysdeps/pthread/bits/cancelation.h /^struct __pthread_cancelation_handler$/;" s
+__pthread_cleanup_pop sysdeps/pthread/bits/cancelation.h 44;" d
+__pthread_cleanup_push sysdeps/pthread/bits/cancelation.h 32;" d
+__pthread_concurrency sysdeps/generic/pt-setconcurrency.c /^int __pthread_concurrency;$/;" v
+__pthread_cond sysdeps/pthread/bits/condition.h /^struct __pthread_cond$/;" s
+__pthread_cond_broadcast sysdeps/generic/pt-cond-brdcast.c /^__pthread_cond_broadcast (pthread_cond_t *cond)$/;" f
+__pthread_cond_destroy sysdeps/generic/pt-cond-destroy.c /^__pthread_cond_destroy (pthread_cond_t *cond)$/;" f
+__pthread_cond_init sysdeps/generic/pt-cond-init.c /^__pthread_cond_init (pthread_cond_t *cond,$/;" f
+__pthread_cond_signal sysdeps/generic/pt-cond-signal.c /^__pthread_cond_signal (pthread_cond_t *cond)$/;" f
+__pthread_cond_timedwait sysdeps/generic/pt-cond-timedwait.c /^__pthread_cond_timedwait (pthread_cond_t *cond,$/;" f
+__pthread_cond_timedwait_internal sysdeps/generic/pt-cond-timedwait.c /^__pthread_cond_timedwait_internal (pthread_cond_t *cond,$/;" f
+__pthread_cond_wait sysdeps/generic/pt-cond-wait.c /^__pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)$/;" f
+__pthread_condattr sysdeps/pthread/bits/condition-attr.h /^struct __pthread_condattr$/;" s
+__pthread_condattr_destroy sysdeps/generic/pt-condattr-destroy.c /^__pthread_condattr_destroy (pthread_condattr_t *cond)$/;" f
+__pthread_condattr_init sysdeps/generic/pt-condattr-init.c /^__pthread_condattr_init (pthread_condattr_t *attr)$/;" f
+__pthread_contentionscope sysdeps/generic/pthread/pthreadtypes.h /^enum __pthread_contentionscope$/;" g
+__pthread_create_internal pthread/pt-create.c /^__pthread_create_internal (struct __pthread **thread,$/;" f
+__pthread_dealloc pthread/pt-dealloc.c /^__pthread_dealloc (struct __pthread *pthread)$/;" f
+__pthread_default_attr sysdeps/generic/pt-attr.c /^const struct __pthread_attr __pthread_default_attr =$/;" v typeref:struct:__pthread_attr
+__pthread_default_barrierattr sysdeps/generic/pt-barrier.c /^const struct __pthread_barrierattr __pthread_default_barrierattr =$/;" v typeref:struct:__pthread_barrierattr
+__pthread_default_condattr sysdeps/generic/pt-cond.c /^const struct __pthread_condattr __pthread_default_condattr =$/;" v typeref:struct:__pthread_condattr
+__pthread_default_mutexattr sysdeps/generic/pt-mutexattr.c /^const struct __pthread_mutexattr __pthread_default_mutexattr =$/;" v typeref:struct:__pthread_mutexattr
+__pthread_default_rwlockattr sysdeps/generic/pt-rwlock-attr.c /^const struct __pthread_rwlockattr __pthread_default_rwlockattr =$/;" v typeref:struct:__pthread_rwlockattr
+__pthread_dequeue pthread/pt-internal.h /^__pthread_dequeue (struct __pthread *thread)$/;" f
+__pthread_dequeuing_iterate pthread/pt-internal.h 165;" d
+__pthread_destroy_specific sysdeps/generic/pt-destroy-specific.c /^__pthread_destroy_specific (struct __pthread *thread)$/;" f
+__pthread_detachstate sysdeps/generic/pthread/pthreadtypes.h /^enum __pthread_detachstate$/;" g
+__pthread_do_cancel sysdeps/mach/hurd/pt-docancel.c /^__pthread_do_cancel (struct __pthread *p)$/;" f
+__pthread_enqueue pthread/pt-internal.h /^__pthread_enqueue (struct __pthread **head, struct __pthread *thread)$/;" f
+__pthread_equal sysdeps/generic/pt-equal.c /^__pthread_equal (pthread_t __t1, pthread_t __t2)$/;" f
+__pthread_equal sysdeps/pthread/bits/pthread.h /^__pthread_equal (__pthread_t __t1, __pthread_t __t2)$/;" f
+__pthread_errorcheck_mutexattr sysdeps/generic/pt-mutexattr.c /^const struct __pthread_mutexattr __pthread_errorcheck_mutexattr =$/;" v typeref:struct:__pthread_mutexattr
+__pthread_exit pthread/pt-exit.c /^__pthread_exit (void *status)$/;" f
+__pthread_free_threads pthread/pt-alloc.c /^struct __pthread *__pthread_free_threads;$/;" v typeref:struct:__pthread
+__pthread_free_threads_lock pthread/pt-alloc.c /^pthread_mutex_t __pthread_free_threads_lock;$/;" v
+__pthread_get_cleanup_stack pthread/pt-cleanup.c /^__pthread_get_cleanup_stack (void)$/;" f
+__pthread_getattr_np pthread/pt-getattr.c /^__pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)$/;" f
+__pthread_getid pthread/pt-internal.h 190;" d
+__pthread_getschedparam sysdeps/generic/pt-getschedparam.c /^__pthread_getschedparam (pthread_t thread, int *policy,$/;" f
+__pthread_getspecific sysdeps/generic/pt-getspecific.c /^__pthread_getspecific (pthread_key_t key)$/;" f
+__pthread_getspecific sysdeps/pthread/libc-lockP.h 172;" d
+__pthread_hurd_cond_timedwait_internal sysdeps/mach/hurd/pt-hurd-cond-timedwait.c /^__pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,$/;" f
+__pthread_hurd_cond_timedwait_np sysdeps/mach/hurd/pt-hurd-cond-timedwait.c /^__pthread_hurd_cond_timedwait_np (pthread_cond_t *cond,$/;" f
+__pthread_hurd_cond_wait_np sysdeps/mach/hurd/pt-hurd-cond-wait.c /^__pthread_hurd_cond_wait_np (pthread_cond_t *cond,$/;" f
+__pthread_inheritsched sysdeps/generic/pthread/pthreadtypes.h /^enum __pthread_inheritsched$/;" g
+__pthread_init_specific sysdeps/generic/pt-init-specific.c /^__pthread_init_specific (struct __pthread *thread)$/;" f
+__pthread_initialize sysdeps/pthread/libc-lockP.h 174;" d
+__pthread_key sysdeps/pthread/bits/thread-specific.h /^typedef int __pthread_key;$/;" t
+__pthread_key_count sysdeps/generic/pt-key-create.c /^int __pthread_key_count;$/;" v
+__pthread_key_create sysdeps/generic/pt-key-create.c /^__pthread_key_create (pthread_key_t *key, void (*destructor) (void *))$/;" f
+__pthread_key_create sysdeps/pthread/libc-lockP.h 170;" d
+__pthread_key_destructors sysdeps/generic/pt-key-create.c /^void (**__pthread_key_destructors) (void *arg);$/;" v
+__pthread_key_invalid_count sysdeps/generic/pt-key-create.c /^int __pthread_key_invalid_count;$/;" v
+__pthread_key_lock sysdeps/generic/pt-key-create.c /^pthread_mutex_t __pthread_key_lock;$/;" v
+__pthread_key_lock_ready sysdeps/generic/pt-key.h /^__pthread_key_lock_ready (void)$/;" f
+__pthread_key_size sysdeps/generic/pt-key-create.c /^int __pthread_key_size;$/;" v
+__pthread_kill sysdeps/generic/pt-kill.c /^__pthread_kill (pthread_t tid, int signo)$/;" f
+__pthread_kill sysdeps/generic/raise.c 25;" d file:
+__pthread_kill sysdeps/hurd/pt-kill.c /^__pthread_kill (pthread_t thread, int sig)$/;" f
+__pthread_max_threads pthread/pt-alloc.c /^int __pthread_max_threads;$/;" v
+__pthread_mutex sysdeps/mach/hurd/bits/mutex.h /^struct __pthread_mutex$/;" s
+__pthread_mutex sysdeps/pthread/bits/mutex.h /^struct __pthread_mutex$/;" s
+__pthread_mutex_destroy sysdeps/pthread/libc-lockP.h 157;" d
+__pthread_mutex_init sysdeps/pthread/libc-lockP.h 156;" d
+__pthread_mutex_lock sysdeps/generic/pt-mutex-lock.c /^__pthread_mutex_lock (struct __pthread_mutex *mutex)$/;" f
+__pthread_mutex_lock sysdeps/mach/hurd/pt-mutex-lock.c /^int __pthread_mutex_lock (pthread_mutex_t *mtxp)$/;" f
+__pthread_mutex_lock sysdeps/pthread/libc-lockP.h 158;" d
+__pthread_mutex_protocol sysdeps/generic/pthread/pthreadtypes.h /^enum __pthread_mutex_protocol$/;" g
+__pthread_mutex_robustness sysdeps/generic/pthread/pthreadtypes.h /^enum __pthread_mutex_robustness$/;" g
+__pthread_mutex_timedlock_internal sysdeps/generic/pt-mutex-timedlock.c /^__pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,$/;" f
+__pthread_mutex_transfer_np sysdeps/generic/pt-mutex-transfer-np.c /^__pthread_mutex_transfer_np (struct __pthread_mutex *mutex, pthread_t tid)$/;" f
+__pthread_mutex_transfer_np sysdeps/mach/hurd/pt-mutex-transfer-np.c /^int __pthread_mutex_transfer_np (pthread_mutex_t *mtxp, pthread_t th)$/;" f
+__pthread_mutex_trylock sysdeps/generic/pt-mutex-trylock.c /^__pthread_mutex_trylock (struct __pthread_mutex *mutex)$/;" f
+__pthread_mutex_trylock sysdeps/mach/hurd/pt-mutex-trylock.c /^int __pthread_mutex_trylock (pthread_mutex_t *mtxp)$/;" f
+__pthread_mutex_trylock sysdeps/pthread/libc-lockP.h 159;" d
+__pthread_mutex_type sysdeps/generic/pthread/pthreadtypes.h /^enum __pthread_mutex_type$/;" g
+__pthread_mutex_unlock sysdeps/generic/pt-mutex-unlock.c /^__pthread_mutex_unlock (pthread_mutex_t *mutex)$/;" f
+__pthread_mutex_unlock sysdeps/mach/hurd/pt-mutex-unlock.c /^int __pthread_mutex_unlock (pthread_mutex_t *mtxp)$/;" f
+__pthread_mutex_unlock sysdeps/pthread/libc-lockP.h 160;" d
+__pthread_mutexattr sysdeps/pthread/bits/mutex-attr.h /^struct __pthread_mutexattr$/;" s
+__pthread_mutexattr_destroy sysdeps/generic/pt-mutexattr-destroy.c /^__pthread_mutexattr_destroy (pthread_mutexattr_t *attr)$/;" f
+__pthread_mutexattr_destroy sysdeps/mach/hurd/pt-mutexattr-destroy.c /^int __pthread_mutexattr_destroy (pthread_mutexattr_t *attrp)$/;" f
+__pthread_mutexattr_destroy sysdeps/pthread/libc-lockP.h 162;" d
+__pthread_mutexattr_init sysdeps/generic/pt-mutexattr-init.c /^__pthread_mutexattr_init (pthread_mutexattr_t *attr)$/;" f
+__pthread_mutexattr_init sysdeps/mach/hurd/pt-mutexattr-init.c /^int __pthread_mutexattr_init (pthread_mutexattr_t *attrp)$/;" f
+__pthread_mutexattr_init sysdeps/pthread/libc-lockP.h 161;" d
+__pthread_mutexattr_settype sysdeps/generic/pt-mutexattr-settype.c /^__pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)$/;" f
+__pthread_mutexattr_settype sysdeps/mach/hurd/pt-mutexattr-settype.c /^int __pthread_mutexattr_settype (pthread_mutexattr_t *attrp, int type)$/;" f
+__pthread_mutexattr_settype sysdeps/pthread/libc-lockP.h 163;" d
+__pthread_num_threads pthread/pt-alloc.c /^int __pthread_num_threads;$/;" v
+__pthread_once sysdeps/generic/pt-once.c /^__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))$/;" f
+__pthread_once sysdeps/pthread/bits/once.h /^struct __pthread_once$/;" s
+__pthread_once sysdeps/pthread/libc-lockP.h 173;" d
+__pthread_process_shared sysdeps/generic/pthread/pthreadtypes.h /^enum __pthread_process_shared$/;" g
+__pthread_queue_iterate pthread/pt-internal.h 156;" d
+__pthread_recursive_mutexattr sysdeps/generic/pt-mutexattr.c /^const struct __pthread_mutexattr __pthread_recursive_mutexattr =$/;" v typeref:struct:__pthread_mutexattr
+__pthread_rwlock sysdeps/pthread/bits/rwlock.h /^struct __pthread_rwlock$/;" s
+__pthread_rwlock_destroy sysdeps/pthread/libc-lockP.h 164;" d
+__pthread_rwlock_rdlock sysdeps/generic/pt-rwlock-rdlock.c /^__pthread_rwlock_rdlock (struct __pthread_rwlock *rwlock)$/;" f
+__pthread_rwlock_rdlock sysdeps/pthread/libc-lockP.h 165;" d
+__pthread_rwlock_timedrdlock sysdeps/generic/pt-rwlock-timedrdlock.c /^__pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock,$/;" f
+__pthread_rwlock_timedrdlock_internal sysdeps/generic/pt-rwlock-timedrdlock.c /^__pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,$/;" f
+__pthread_rwlock_timedwrlock sysdeps/generic/pt-rwlock-timedwrlock.c /^__pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock,$/;" f
+__pthread_rwlock_timedwrlock_internal sysdeps/generic/pt-rwlock-timedwrlock.c /^__pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,$/;" f
+__pthread_rwlock_tryrdlock sysdeps/pthread/libc-lockP.h 166;" d
+__pthread_rwlock_trywrlock sysdeps/pthread/libc-lockP.h 168;" d
+__pthread_rwlock_unlock sysdeps/generic/pt-rwlock-unlock.c /^__pthread_rwlock_unlock (pthread_rwlock_t *rwlock)$/;" f
+__pthread_rwlock_unlock sysdeps/pthread/libc-lockP.h 169;" d
+__pthread_rwlock_wrlock sysdeps/generic/pt-rwlock-wrlock.c /^__pthread_rwlock_wrlock (struct __pthread_rwlock *rwlock)$/;" f
+__pthread_rwlock_wrlock sysdeps/pthread/libc-lockP.h 167;" d
+__pthread_rwlockattr sysdeps/pthread/bits/rwlock-attr.h /^struct __pthread_rwlockattr$/;" s
+__pthread_self pthread/pt-self.c /^__pthread_self (void)$/;" f
+__pthread_self sysdeps/generic/raise.c 26;" d file:
+__pthread_setcancelstate pthread/pt-setcancelstate.c /^__pthread_setcancelstate (int state, int *oldstate)$/;" f
+__pthread_setcancelstate sysdeps/pthread/libc-lockP.h 176;" d
+__pthread_setcanceltype pthread/pt-setcanceltype.c /^__pthread_setcanceltype (int type, int *oldtype)$/;" f
+__pthread_setid pthread/pt-internal.h 197;" d
+__pthread_setschedparam sysdeps/generic/pt-setschedparam.c /^__pthread_setschedparam (pthread_t thread, int policy,$/;" f
+__pthread_setspecific sysdeps/generic/pt-setspecific.c /^__pthread_setspecific (pthread_key_t key, const void *value)$/;" f
+__pthread_setspecific sysdeps/pthread/libc-lockP.h 171;" d
+__pthread_setup sysdeps/mach/hurd/i386/pt-setup.c /^__pthread_setup (struct __pthread *thread,$/;" f
+__pthread_sigstate sysdeps/mach/hurd/pt-sigstate.c /^__pthread_sigstate (struct __pthread *thread, int how,$/;" f
+__pthread_sigstate_destroy sysdeps/mach/hurd/pt-sigstate-destroy.c /^__pthread_sigstate_destroy (struct __pthread *thread)$/;" f
+__pthread_sigstate_init sysdeps/mach/hurd/pt-sigstate-init.c /^__pthread_sigstate_init (struct __pthread *thread)$/;" f
+__pthread_spin_count sysdeps/posix/pt-spin.c /^int __pthread_spin_count = __PTHREAD_SPIN_COUNT;$/;" v
+__pthread_spin_destroy sysdeps/mach/bits/spin-lock-inline.h /^__pthread_spin_destroy (__pthread_spinlock_t *__lock)$/;" f
+__pthread_spin_init sysdeps/mach/bits/spin-lock-inline.h /^__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared)$/;" f
+__pthread_spin_lock sysdeps/mach/bits/spin-lock-inline.h /^__pthread_spin_lock (__pthread_spinlock_t *__lock)$/;" f
+__pthread_spin_trylock sysdeps/mach/bits/spin-lock-inline.h /^__pthread_spin_trylock (__pthread_spinlock_t *__lock)$/;" f
+__pthread_spin_unlock sysdeps/mach/bits/spin-lock-inline.h /^__pthread_spin_unlock (__pthread_spinlock_t *__lock)$/;" f
+__pthread_spinlock_t sysdeps/mach/bits/spin-lock.h /^typedef volatile int __pthread_spinlock_t;$/;" t
+__pthread_stack_alloc sysdeps/mach/pt-stack-alloc.c /^__pthread_stack_alloc (void **stackaddr, size_t stacksize)$/;" f
+__pthread_stack_dealloc sysdeps/mach/hurd/pt-sysdep.h /^__pthread_stack_dealloc (void *stackaddr, size_t stacksize)$/;" f
+__pthread_startup sysdeps/generic/pt-startup.c /^__pthread_startup (void)$/;" f
+__pthread_t sysdeps/pthread/bits/pthread.h /^typedef int __pthread_t;$/;" t
+__pthread_thread_alloc sysdeps/mach/pt-thread-alloc.c /^__pthread_thread_alloc (struct __pthread *thread)$/;" f
+__pthread_thread_start sysdeps/mach/pt-thread-start.c /^__pthread_thread_start (struct __pthread *thread)$/;" f
+__pthread_thread_terminate sysdeps/mach/pt-thread-terminate.c /^__pthread_thread_terminate (struct __pthread *thread)$/;" f
+__pthread_threads pthread/pt-alloc.c /^struct __pthread **__pthread_threads;$/;" v typeref:struct:__pthread
+__pthread_threads sysdeps/generic/raise.c 27;" d file:
+__pthread_threads_lock pthread/pt-alloc.c /^pthread_rwlock_t __pthread_threads_lock;$/;" v
+__pthread_timedblock sysdeps/mach/pt-timedblock.c /^__pthread_timedblock (struct __pthread *thread,$/;" f
+__pthread_total pthread/pt-create.c /^unsigned int __pthread_total;$/;" v
+__pthread_wakeup sysdeps/mach/pt-wakeup.c /^__pthread_wakeup (struct __pthread *thread)$/;" f
+__queue sysdeps/pthread/bits/barrier.h /^ struct __pthread *__queue; \/* List of waiters. *\/$/;" m struct:__pthread_barrier typeref:struct:__pthread_barrier::__pthread
+__queue sysdeps/pthread/bits/condition.h /^ struct __pthread *__queue;$/;" m struct:__pthread_cond typeref:struct:__pthread_cond::__pthread
+__queue sysdeps/pthread/bits/mutex.h /^ struct __pthread *__queue;$/;" m struct:__pthread_mutex typeref:struct:__pthread_mutex::__pthread
+__queue sysdeps/pthread/bits/semaphore.h /^ struct __pthread *__queue;$/;" m struct:__semaphore typeref:struct:__semaphore::__pthread
+__readerqueue sysdeps/pthread/bits/rwlock.h /^ struct __pthread *__readerqueue;$/;" m struct:__pthread_rwlock typeref:struct:__pthread_rwlock::__pthread
+__readers sysdeps/pthread/bits/rwlock.h /^ int __readers;$/;" m struct:__pthread_rwlock
+__register_atfork forward.c /^__register_atfork ($/;" f
+__reserved1 sysdeps/mach/hurd/bits/mutex.h /^ unsigned int __reserved1;$/;" m struct:__pthread_mutex
+__reserved2 sysdeps/mach/hurd/bits/mutex.h /^ unsigned int __reserved2;$/;" m struct:__pthread_mutex
+__run sysdeps/pthread/bits/once.h /^ int __run;$/;" m struct:__pthread_once
+__schedparam sysdeps/pthread/bits/thread-attr.h /^ struct sched_param __schedparam;$/;" m struct:__pthread_attr typeref:struct:__pthread_attr::sched_param
+__schedpolicy sysdeps/pthread/bits/thread-attr.h /^ int __schedpolicy;$/;" m struct:__pthread_attr
+__sem_close sysdeps/generic/sem-close.c /^__sem_close (sem_t *sem)$/;" f
+__sem_destroy sysdeps/generic/sem-destroy.c /^__sem_destroy (sem_t *sem)$/;" f
+__sem_getvalue sysdeps/generic/sem-getvalue.c /^__sem_getvalue (sem_t *restrict sem, int *restrict value)$/;" f
+__sem_init sysdeps/generic/sem-init.c /^__sem_init (sem_t *sem, int pshared, unsigned value)$/;" f
+__sem_open sysdeps/generic/sem-open.c /^__sem_open (const char *name, int open_flags, ...)$/;" f
+__sem_post sysdeps/generic/sem-post.c /^__sem_post (sem_t *sem)$/;" f
+__sem_timedwait sysdeps/generic/sem-timedwait.c /^__sem_timedwait (sem_t *restrict sem,$/;" f
+__sem_timedwait_internal sysdeps/generic/sem-timedwait.c /^__sem_timedwait_internal (sem_t *restrict sem,$/;" f
+__sem_trywait sysdeps/generic/sem-trywait.c /^__sem_trywait (sem_t *sem)$/;" f
+__sem_unlink sysdeps/generic/sem-unlink.c /^__sem_unlink (const char *name)$/;" f
+__sem_wait sysdeps/generic/sem-wait.c /^__sem_wait (sem_t *sem)$/;" f
+__semaphore sysdeps/pthread/bits/semaphore.h /^struct __semaphore$/;" s
+__shpid sysdeps/mach/hurd/bits/mutex.h /^ int __shpid;$/;" m struct:__pthread_mutex
+__stackaddr sysdeps/pthread/bits/thread-attr.h /^ void *__stackaddr;$/;" m struct:__pthread_attr
+__stacksize sysdeps/pthread/bits/thread-attr.h /^ size_t __stacksize;$/;" m struct:__pthread_attr
+__thread_set_pcsptp sysdeps/mach/hurd/i386/pt-machdep.c /^__thread_set_pcsptp (thread_t thread,$/;" f
+__thread_stack_pointer sysdeps/i386/machine-sp.h 24;" d
+__type sysdeps/mach/hurd/bits/mutex.h /^ int __type;$/;" m struct:__pthread_mutex
+__value sysdeps/pthread/bits/semaphore.h /^ int __value;$/;" m struct:__semaphore
+__writerqueue sysdeps/pthread/bits/rwlock.h /^ struct __pthread *__writerqueue;$/;" m struct:__pthread_rwlock typeref:struct:__pthread_rwlock::__pthread
+_cthread_init_routine sysdeps/mach/hurd/pt-sysdep.c /^void *(*_cthread_init_routine)(void) = &init_routine;$/;" v
+_cthreads_flockfile lockfile.c /^_cthreads_flockfile (_IO_FILE *fp)$/;" f
+_cthreads_ftrylockfile lockfile.c /^_cthreads_ftrylockfile (_IO_FILE *fp)$/;" f
+_cthreads_funlockfile lockfile.c /^_cthreads_funlockfile (_IO_FILE *fp)$/;" f
+_init_routine sysdeps/mach/hurd/pt-sysdep.c /^_init_routine (void *stack)$/;" f file:
+_pthread_mutex_destroy sysdeps/generic/pt-mutex-destroy.c /^_pthread_mutex_destroy (pthread_mutex_t *mutex)$/;" f
+_pthread_mutex_destroy sysdeps/mach/hurd/pt-mutex-destroy.c /^int _pthread_mutex_destroy (pthread_mutex_t *mtxp)$/;" f
+_pthread_mutex_init sysdeps/generic/pt-mutex-init.c /^_pthread_mutex_init (pthread_mutex_t *mutex,$/;" f
+_pthread_mutex_init sysdeps/mach/hurd/pt-mutex-init.c /^int _pthread_mutex_init (pthread_mutex_t *mtxp,$/;" f
+_pthread_rwlock_destroy sysdeps/generic/pt-rwlock-destroy.c /^_pthread_rwlock_destroy (pthread_rwlock_t *rwlock)$/;" f
+_pthread_rwlock_init sysdeps/generic/pt-rwlock-init.c /^_pthread_rwlock_init (pthread_rwlock_t *rwlock,$/;" f
+_pthread_self sysdeps/mach/hurd/pt-sysdep.h 35;" d
+_pthread_spin_lock sysdeps/mach/pt-spin.c /^_pthread_spin_lock (__spin_lock_t *lock)$/;" f
+_pthread_spin_lock sysdeps/posix/pt-spin.c /^_pthread_spin_lock (__pthread_spinlock_t *lock)$/;" f
+a tests/test-11.c /^int a;$/;" v
+atfork forward.c /^struct atfork {$/;" s file:
+atfork_pthread_child forward.c /^atfork_pthread_child (void)$/;" f file:
+atfork_pthread_parent forward.c /^atfork_pthread_parent (void)$/;" f file:
+atfork_pthread_prepare forward.c /^atfork_pthread_prepare (void)$/;" f file:
+attribute_hidden forward.c /^int __libc_pthread_functions_init attribute_hidden;$/;" v
+attribute_hidden forward.c /^struct pthread_functions __libc_pthread_functions attribute_hidden;$/;" v typeref:struct:__libc_pthread_functions
+b tests/test-11.c /^int b;$/;" v
+call_exit sysdeps/mach/hurd/pt-docancel.c /^call_exit (void)$/;" f file:
+cancel_ctx sysdeps/generic/pt-cond-timedwait.c /^struct cancel_ctx$/;" s file:
+cancel_hook pthread/pt-internal.h /^ void (*cancel_hook)(void *); \/* Called to unblock a thread blocking$/;" m struct:__pthread
+cancel_hook sysdeps/generic/pt-cond-timedwait.c /^cancel_hook (void *arg)$/;" f file:
+cancel_hook_arg pthread/pt-internal.h /^ void *cancel_hook_arg;$/;" m struct:__pthread
+cancel_lock pthread/pt-internal.h /^ pthread_mutex_t cancel_lock; \/* Protect cancel_xxx members. *\/$/;" m struct:__pthread
+cancel_pending pthread/pt-internal.h /^ int cancel_pending;$/;" m struct:__pthread
+cancel_state pthread/pt-internal.h /^ int cancel_state;$/;" m struct:__pthread
+cancel_type pthread/pt-internal.h /^ int cancel_type;$/;" m struct:__pthread
+cancelation_handlers pthread/pt-internal.h /^ struct __pthread_cancelation_handler *cancelation_handlers;$/;" m struct:__pthread typeref:struct:__pthread::__pthread_cancelation_handler
+child forward.c /^ void (*child) (void);$/;" m struct:atfork file:
+cond sysdeps/generic/pt-cond-timedwait.c /^ pthread_cond_t *cond;$/;" m struct:cancel_ctx file:
+create_wakeupmsg sysdeps/mach/pt-thread-alloc.c /^create_wakeupmsg (struct __pthread *thread)$/;" f file:
+d tests/test-__pthread_destroy_specific-skip.c /^d (void *x)$/;" f file:
+dfl_attr sysdeps/mach/hurd/pt-mutex-init.c /^static const pthread_mutexattr_t dfl_attr =$/;" v file:
+dfl_attr sysdeps/mach/hurd/pt-mutexattr-init.c /^static const pthread_mutexattr_t dfl_attr =$/;" v file:
+distribute Makefile /^distribute :=$/;" m
+dowait tests/test-6.c /^dowait (void *arg)$/;" f
+dso_handle forward.c /^ void *dso_handle;$/;" m struct:atfork file:
+dtv pthread/pt-internal.h /^ void *dtv; \/* Vector of pointers to TLS data. *\/$/;" m struct:__anon1
+dummy_list forward.c /^struct __pthread_cancelation_handler *dummy_list;$/;" v typeref:struct:__pthread_cancelation_handler
+dynamic_init_routine sysdeps/mach/hurd/pt-sysdep.c /^__attribute__ ((constructor)) static void dynamic_init_routine(void)$/;" f file:
+entry_point pthread/pt-create.c /^entry_point (struct __pthread *self, void *(*start_routine)(void *), void *arg)$/;" f file:
+extra-B-pthread.so Makefile /^extra-B-pthread.so = -B$(common-objpfx)htl\/$/;" m
+extra-libs Makefile /^extra-libs := libpthread$/;" m
+extra-libs-others Makefile /^extra-libs-others := $(extra-libs)$/;" m
+flockfile lockfile.c 44;" d file:
+foo tests/test-1.c /^foo (void *arg)$/;" f
+foo tests/test-9.c /^int foo;$/;" v
+foobar tests/test-5.c /^int foobar;$/;" v
+fork_handlers forward.c /^static struct atfork *fork_handlers, *fork_last_handler;$/;" v typeref:struct:atfork file:
+fork_last_handler forward.c /^static struct atfork *fork_handlers, *fork_last_handler;$/;" v typeref:struct: file:
+ftrylockfile lockfile.c 46;" d file:
+funlockfile lockfile.c 45;" d file:
+guardsize pthread/pt-internal.h /^ size_t guardsize;$/;" m struct:__pthread
+handler tests/test-16.c /^handler (int sig)$/;" f file:
+headers Makefile /^headers := \\$/;" m
+i tests/test-16.c /^int i;$/;" v
+inc_var tests/test-8.c /^inc_var (void)$/;" f
+inc_var_once tests/test-8.c /^pthread_once_t inc_var_once = PTHREAD_ONCE_INIT;$/;" v
+init_routine sysdeps/mach/hurd/pt-sysdep.c /^init_routine (void)$/;" f file:
+initialize_pthread pthread/pt-alloc.c /^initialize_pthread (struct __pthread *new)$/;" f file:
+install-lib Makefile /^install-lib := libpthread.so$/;" m
+key tests/test-7.c /^pthread_key_t key[KEYS];$/;" v
+libc-link.so Makefile /^libc-link.so = $(common-objpfx)libc.so$/;" m
+libc_hidden_def forward.c /^libc_hidden_def (__register_atfork)$/;" f
+libpthread-routines Makefile /^libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate \\$/;" m
+libpthread-static-only-routines Makefile /^libpthread-static-only-routines = pt-atfork$/;" m
+main tests/test-1.c /^main (int argc, char **argv)$/;" f
+main tests/test-10.c /^main (int argc, char **argv)$/;" f
+main tests/test-11.c /^main (int argc, char **argv)$/;" f
+main tests/test-12.c /^main (int argc, char **argv)$/;" f
+main tests/test-13.c /^main (int argc, char **argv)$/;" f
+main tests/test-14.c /^main (int argc, char **argv)$/;" f
+main tests/test-15.c /^main (int argc, char **argv)$/;" f
+main tests/test-16.c /^main (int argc, char **argv)$/;" f
+main tests/test-17.c /^main (int argc, char *argv[])$/;" f
+main tests/test-2.c /^main (int argc, char **argv)$/;" f
+main tests/test-3.c /^main (int argc, char *argv[])$/;" f
+main tests/test-4.c /^main (int argc, char *argv[])$/;" f
+main tests/test-5.c /^main (int argc, char *argv[])$/;" f
+main tests/test-6.c /^main (int argc, char **argv)$/;" f
+main tests/test-7.c /^main (int argc, char **argv)$/;" f
+main tests/test-8.c /^main (int argc, char **argv)$/;" f
+main tests/test-9.c /^main (int argc, char **argv)$/;" f
+main tests/test-__pthread_destroy_specific-skip.c /^int main(void)$/;" f
+mcontext pthread/pt-internal.h /^ struct pthread_mcontext mcontext;$/;" m struct:__pthread typeref:struct:__pthread::pthread_mcontext
+mtx_owned_p sysdeps/mach/hurd/pt-mutex.h 66;" d
+mtx_set_owner sysdeps/mach/hurd/pt-mutex.h 72;" d
+next forward.c /^ struct atfork *next;$/;" m struct:atfork typeref:struct:atfork::atfork file:
+next pthread/pt-internal.h /^ struct __pthread *next, **prevp;$/;" m struct:__pthread typeref:struct:__pthread::__pthread
+next_stack_base sysdeps/mach/pt-stack-alloc.c /^static vm_address_t next_stack_base = VM_MIN_ADDRESS;$/;" v file:
+nr_refs pthread/pt-internal.h /^ __atomic_t nr_refs; \/* Detached threads have a self reference only,$/;" m struct:__pthread
+parent forward.c /^ void (*parent) (void);$/;" m struct:atfork file:
+pc sysdeps/i386/pt-machdep.h /^ void *pc;$/;" m struct:pthread_mcontext
+prepare forward.c /^ void (*prepare) (void);$/;" m struct:atfork file:
+prev forward.c /^ struct atfork *prev;$/;" m struct:atfork typeref:struct:atfork::atfork file:
+prevp pthread/pt-internal.h /^ struct __pthread *next, **prevp;$/;" m struct:__pthread typeref:struct:__pthread::
+pthread_atfork sysdeps/generic/old_pt-atfork.c 22;" d file:
+pthread_atfork sysdeps/generic/old_pt-atfork.c 24;" d file:
+pthread_atfork sysdeps/generic/pt-atfork.c /^pthread_atfork (void (*prepare) (void),$/;" f
+pthread_attr_getguardsize sysdeps/generic/pt-attr-getguardsize.c /^pthread_attr_getguardsize (const pthread_attr_t *attr,$/;" f
+pthread_attr_getstackaddr sysdeps/generic/pt-attr-getstackaddr.c /^pthread_attr_getstackaddr (const pthread_attr_t *attr,$/;" f
+pthread_attr_getstacksize sysdeps/generic/pt-attr-getstacksize.c /^pthread_attr_getstacksize (const pthread_attr_t *attr,$/;" f
+pthread_attr_setguardsize sysdeps/generic/pt-attr-setguardsize.c /^pthread_attr_setguardsize (pthread_attr_t *attr,$/;" f
+pthread_attr_setstack sysdeps/generic/pt-attr-setstack.c /^pthread_attr_setstack (pthread_attr_t *attr,$/;" f
+pthread_attr_setstackaddr sysdeps/generic/pt-attr-setstackaddr.c /^pthread_attr_setstackaddr (pthread_attr_t *attr,$/;" f
+pthread_attr_setstackaddr sysdeps/mach/hurd/pt-attr-setstackaddr.c /^pthread_attr_setstackaddr (pthread_attr_t *attr,$/;" f
+pthread_attr_setstacksize sysdeps/generic/pt-attr-setstacksize.c /^pthread_attr_setstacksize (pthread_attr_t *attr,$/;" f
+pthread_attr_setstacksize sysdeps/mach/hurd/pt-attr-setstacksize.c /^pthread_attr_setstacksize (pthread_attr_t *attr,$/;" f
+pthread_attr_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_attr pthread_attr_t;$/;" t typeref:struct:__pthread_attr
+pthread_barrier_destroy sysdeps/generic/pt-barrier-destroy.c /^pthread_barrier_destroy (pthread_barrier_t *barrier)$/;" f
+pthread_barrier_init sysdeps/generic/pt-barrier-init.c /^pthread_barrier_init (pthread_barrier_t *barrier,$/;" f
+pthread_barrier_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_barrier pthread_barrier_t;$/;" t typeref:struct:__pthread_barrier
+pthread_barrier_wait sysdeps/generic/pt-barrier-wait.c /^pthread_barrier_wait (pthread_barrier_t *barrier)$/;" f
+pthread_barrierattr_destroy sysdeps/generic/pt-barrierattr-destroy.c /^pthread_barrierattr_destroy (pthread_barrierattr_t *attr)$/;" f
+pthread_barrierattr_getpshared sysdeps/generic/pt-barrierattr-getpshared.c /^pthread_barrierattr_getpshared (const pthread_barrierattr_t *attr,$/;" f
+pthread_barrierattr_init sysdeps/generic/pt-barrierattr-init.c /^pthread_barrierattr_init (pthread_barrierattr_t *attr)$/;" f
+pthread_barrierattr_setpshared sysdeps/generic/pt-barrierattr-setpshared.c /^pthread_barrierattr_setpshared (pthread_barrierattr_t *attr,$/;" f
+pthread_barrierattr_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_barrierattr pthread_barrierattr_t;$/;" t typeref:struct:__pthread_barrierattr
+pthread_cancel pthread/pt-cancel.c /^pthread_cancel (pthread_t t)$/;" f
+pthread_cleanup_pop sysdeps/generic/pthread/pthread.h 695;" d
+pthread_cleanup_push sysdeps/generic/pthread/pthread.h 694;" d
+pthread_cond_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_cond pthread_cond_t;$/;" t typeref:struct:__pthread_cond
+pthread_condattr_getclock sysdeps/generic/pt-condattr-getclock.c /^pthread_condattr_getclock (const pthread_condattr_t *attr,$/;" f
+pthread_condattr_getpshared sysdeps/generic/pt-condattr-getpshared.c /^pthread_condattr_getpshared (const pthread_condattr_t *attr,$/;" f
+pthread_condattr_setclock sysdeps/generic/pt-condattr-setclock.c /^pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock)$/;" f
+pthread_condattr_setpshared sysdeps/generic/pt-condattr-setpshared.c /^pthread_condattr_setpshared (pthread_condattr_t *attr,$/;" f
+pthread_condattr_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_condattr pthread_condattr_t;$/;" t typeref:struct:__pthread_condattr
+pthread_create pthread/pt-create.c /^pthread_create (pthread_t *thread, const pthread_attr_t *attr,$/;" f
+pthread_detach pthread/pt-detach.c /^pthread_detach (pthread_t thread)$/;" f
+pthread_equal sysdeps/generic/pthread/pthread.h /^pthread_equal (pthread_t __t1, pthread_t __t2)$/;" f
+pthread_functions pthread/pt-initialize.c /^static const struct pthread_functions pthread_functions =$/;" v typeref:struct:pthread_functions file:
+pthread_functions sysdeps/pthread/pthread-functions.h /^struct pthread_functions$/;" s
+pthread_getconcurrency sysdeps/generic/pt-getconcurrency.c /^pthread_getconcurrency (void)$/;" f
+pthread_getcpuclockid sysdeps/generic/pt-getcpuclockid.c /^pthread_getcpuclockid (pthread_t thread, clockid_t *clock)$/;" f
+pthread_join pthread/pt-join.c /^pthread_join (pthread_t thread, void **status)$/;" f
+pthread_key_delete sysdeps/generic/pt-key-delete.c /^pthread_key_delete (pthread_key_t key)$/;" f
+pthread_key_t sysdeps/generic/pthread/pthreadtypes.h /^typedef __pthread_key pthread_key_t;$/;" t
+pthread_mcontext sysdeps/i386/pt-machdep.h /^struct pthread_mcontext$/;" s
+pthread_mutex_consistent sysdeps/mach/hurd/pt-mutex-consistent.c /^int pthread_mutex_consistent (pthread_mutex_t *mtxp)$/;" f
+pthread_mutex_getprioceiling sysdeps/generic/pt-mutex-getprioceiling.c /^pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,$/;" f
+pthread_mutex_getprioceiling sysdeps/mach/hurd/pt-mutex-getprioceiling.c /^int pthread_mutex_getprioceiling (const pthread_mutex_t *mtxp, int *clp)$/;" f
+pthread_mutex_setprioceiling sysdeps/generic/pt-mutex-setprioceiling.c /^pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prio,$/;" f
+pthread_mutex_setprioceiling sysdeps/mach/hurd/pt-mutex-setprioceiling.c /^int pthread_mutex_setprioceiling (pthread_mutex_t *mtxp, int cl, int *prp)$/;" f
+pthread_mutex_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_mutex pthread_mutex_t;$/;" t typeref:struct:__pthread_mutex
+pthread_mutex_timedlock sysdeps/generic/pt-mutex-timedlock.c /^pthread_mutex_timedlock (struct __pthread_mutex *mutex,$/;" f
+pthread_mutex_timedlock sysdeps/mach/hurd/pt-mutex-timedlock.c /^int pthread_mutex_timedlock (pthread_mutex_t *mtxp,$/;" f
+pthread_mutexattr_getprioceiling sysdeps/generic/pt-mutexattr-getprioceiling.c /^pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr,$/;" f
+pthread_mutexattr_getprioceiling sysdeps/mach/hurd/pt-mutexattr-getprioceiling.c /^int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *ap, int *clp)$/;" f
+pthread_mutexattr_getprotocol sysdeps/generic/pt-mutexattr-getprotocol.c /^pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr,$/;" f
+pthread_mutexattr_getprotocol sysdeps/mach/hurd/pt-mutexattr-getprotocol.c /^int pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attrp, int *ptp)$/;" f
+pthread_mutexattr_getpshared sysdeps/generic/pt-mutexattr-getpshared.c /^pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr,$/;" f
+pthread_mutexattr_getpshared sysdeps/mach/hurd/pt-mutexattr-getpshared.c /^int pthread_mutexattr_getpshared (const pthread_mutexattr_t *attrp, int *outp)$/;" f
+pthread_mutexattr_getrobust sysdeps/mach/hurd/pt-mutexattr-getrobust.c /^int pthread_mutexattr_getrobust (const pthread_mutexattr_t *attrp, int *outp)$/;" f
+pthread_mutexattr_gettype sysdeps/generic/pt-mutexattr-gettype.c /^pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)$/;" f
+pthread_mutexattr_gettype sysdeps/mach/hurd/pt-mutexattr-gettype.c /^int pthread_mutexattr_gettype (const pthread_mutexattr_t *attrp, int *outp)$/;" f
+pthread_mutexattr_setprioceiling sysdeps/generic/pt-mutexattr-setprioceiling.c /^pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr,$/;" f
+pthread_mutexattr_setprioceiling sysdeps/mach/hurd/pt-mutexattr-setprioceiling.c /^int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attrp, int cl)$/;" f
+pthread_mutexattr_setprotocol sysdeps/generic/pt-mutexattr-setprotocol.c /^pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr,$/;" f
+pthread_mutexattr_setprotocol sysdeps/mach/hurd/pt-mutexattr-setprotocol.c /^int pthread_mutexattr_setprotocol (pthread_mutexattr_t *attrp, int proto)$/;" f
+pthread_mutexattr_setpshared sysdeps/generic/pt-mutexattr-setpshared.c /^pthread_mutexattr_setpshared (pthread_mutexattr_t *attr,$/;" f
+pthread_mutexattr_setpshared sysdeps/mach/hurd/pt-mutexattr-setpshared.c /^int pthread_mutexattr_setpshared (pthread_mutexattr_t *attrp, int pshared)$/;" f
+pthread_mutexattr_setrobust sysdeps/mach/hurd/pt-mutexattr-setrobust.c /^int pthread_mutexattr_setrobust (pthread_mutexattr_t *attrp, int robust)$/;" f
+pthread_mutexattr_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_mutexattr pthread_mutexattr_t;$/;" t typeref:struct:__pthread_mutexattr
+pthread_once_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_once pthread_once_t;$/;" t typeref:struct:__pthread_once
+pthread_rwlock_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_rwlock pthread_rwlock_t;$/;" t typeref:struct:__pthread_rwlock
+pthread_rwlock_tryrdlock sysdeps/generic/pt-rwlock-tryrdlock.c /^pthread_rwlock_tryrdlock (struct __pthread_rwlock *rwlock)$/;" f
+pthread_rwlock_trywrlock sysdeps/generic/pt-rwlock-trywrlock.c /^pthread_rwlock_trywrlock (struct __pthread_rwlock *rwlock)$/;" f
+pthread_rwlockattr_destroy sysdeps/generic/pt-rwlockattr-destroy.c /^pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr)$/;" f
+pthread_rwlockattr_getpshared sysdeps/generic/pt-rwlockattr-getpshared.c /^pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr,$/;" f
+pthread_rwlockattr_init sysdeps/generic/pt-rwlockattr-init.c /^pthread_rwlockattr_init (pthread_rwlockattr_t *attr)$/;" f
+pthread_rwlockattr_setpshared sysdeps/generic/pt-rwlockattr-setpshared.c /^pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr,$/;" f
+pthread_rwlockattr_t sysdeps/generic/pthread/pthreadtypes.h /^typedef struct __pthread_rwlockattr pthread_rwlockattr_t;$/;" t typeref:struct:__pthread_rwlockattr
+pthread_setconcurrency sysdeps/generic/pt-setconcurrency.c /^pthread_setconcurrency (int new_level)$/;" f
+pthread_setschedprio sysdeps/generic/pt-setschedprio.c /^pthread_setschedprio (pthread_t thread, int prio)$/;" f
+pthread_sigmask pthread/pt-sigmask.c /^pthread_sigmask (int how, const sigset_t *set,$/;" f
+pthread_spin_destroy sysdeps/generic/pthread/pthread.h /^pthread_spin_destroy (pthread_spinlock_t *__lock)$/;" f
+pthread_spin_init sysdeps/generic/pthread/pthread.h /^pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)$/;" f
+pthread_spin_lock sysdeps/generic/pthread/pthread.h /^pthread_spin_lock (pthread_spinlock_t *__lock)$/;" f
+pthread_spin_trylock sysdeps/generic/pthread/pthread.h /^pthread_spin_trylock (pthread_spinlock_t *__lock)$/;" f
+pthread_spin_unlock sysdeps/generic/pthread/pthread.h /^pthread_spin_unlock (pthread_spinlock_t *__lock)$/;" f
+pthread_spinlock_t sysdeps/generic/pthread/pthreadtypes.h /^typedef __pthread_spinlock_t pthread_spinlock_t;$/;" t
+pthread_state pthread/pt-internal.h /^enum pthread_state$/;" g
+pthread_t sysdeps/generic/pthread/pthreadtypes.h /^typedef __pthread_t pthread_t;$/;" t
+pthread_testcancel pthread/pt-testcancel.c /^pthread_testcancel (void)$/;" f
+pthread_yield pthread/pt-yield.c /^int pthread_yield(void)$/;" f
+ptr__IO_flockfile sysdeps/pthread/pthread-functions.h /^ void (*ptr__IO_flockfile) (FILE *);$/;" m struct:pthread_functions
+ptr__IO_ftrylockfile sysdeps/pthread/pthread-functions.h /^ int (*ptr__IO_ftrylockfile) (FILE *);$/;" m struct:pthread_functions
+ptr__IO_funlockfile sysdeps/pthread/pthread-functions.h /^ void (*ptr__IO_funlockfile) (FILE *);$/;" m struct:pthread_functions
+ptr___pthread_exit sysdeps/pthread/pthread-functions.h /^ void (*ptr___pthread_exit) (void *);$/;" m struct:pthread_functions
+ptr___pthread_get_cleanup_stack sysdeps/pthread/pthread-functions.h /^ struct __pthread_cancelation_handler **(*ptr___pthread_get_cleanup_stack) (void);$/;" m struct:pthread_functions typeref:struct:pthread_functions::ptr___pthread_get_cleanup_stack
+ptr___pthread_getspecific sysdeps/pthread/pthread-functions.h /^ void *(*ptr___pthread_getspecific) (pthread_key_t);$/;" m struct:pthread_functions
+ptr___pthread_key_create sysdeps/pthread/pthread-functions.h /^ int (*ptr___pthread_key_create) (pthread_key_t *, void (*) (void *));$/;" m struct:pthread_functions
+ptr___pthread_setcancelstate sysdeps/pthread/pthread-functions.h /^ int (*ptr___pthread_setcancelstate) (int, int *);$/;" m struct:pthread_functions
+ptr___pthread_setspecific sysdeps/pthread/pthread-functions.h /^ int (*ptr___pthread_setspecific) (pthread_key_t, const void *);$/;" m struct:pthread_functions
+ptr_pthread_attr_destroy sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_destroy) (pthread_attr_t *);$/;" m struct:pthread_functions
+ptr_pthread_attr_getdetachstate sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);$/;" m struct:pthread_functions
+ptr_pthread_attr_getinheritsched sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);$/;" m struct:pthread_functions
+ptr_pthread_attr_getschedparam sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,$/;" m struct:pthread_functions
+ptr_pthread_attr_getschedpolicy sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);$/;" m struct:pthread_functions
+ptr_pthread_attr_getscope sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);$/;" m struct:pthread_functions
+ptr_pthread_attr_init sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_init) (pthread_attr_t *);$/;" m struct:pthread_functions
+ptr_pthread_attr_setdetachstate sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);$/;" m struct:pthread_functions
+ptr_pthread_attr_setinheritsched sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);$/;" m struct:pthread_functions
+ptr_pthread_attr_setschedparam sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,$/;" m struct:pthread_functions
+ptr_pthread_attr_setschedpolicy sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);$/;" m struct:pthread_functions
+ptr_pthread_attr_setscope sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);$/;" m struct:pthread_functions
+ptr_pthread_cond_broadcast sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_cond_broadcast) (pthread_cond_t *);$/;" m struct:pthread_functions
+ptr_pthread_cond_destroy sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_cond_destroy) (pthread_cond_t *);$/;" m struct:pthread_functions
+ptr_pthread_cond_init sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_cond_init) (pthread_cond_t *,$/;" m struct:pthread_functions
+ptr_pthread_cond_signal sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_cond_signal) (pthread_cond_t *);$/;" m struct:pthread_functions
+ptr_pthread_cond_timedwait sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,$/;" m struct:pthread_functions
+ptr_pthread_cond_wait sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);$/;" m struct:pthread_functions
+ptr_pthread_condattr_destroy sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);$/;" m struct:pthread_functions
+ptr_pthread_condattr_init sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_condattr_init) (pthread_condattr_t *);$/;" m struct:pthread_functions
+ptr_pthread_equal sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_equal) (pthread_t, pthread_t);$/;" m struct:pthread_functions
+ptr_pthread_getschedparam sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);$/;" m struct:pthread_functions
+ptr_pthread_mutex_destroy sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);$/;" m struct:pthread_functions
+ptr_pthread_mutex_init sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_mutex_init) (pthread_mutex_t *,$/;" m struct:pthread_functions
+ptr_pthread_mutex_lock sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);$/;" m struct:pthread_functions
+ptr_pthread_mutex_trylock sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *);$/;" m struct:pthread_functions
+ptr_pthread_mutex_unlock sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);$/;" m struct:pthread_functions
+ptr_pthread_once sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_once) (pthread_once_t *, void (*) (void));$/;" m struct:pthread_functions
+ptr_pthread_rwlock_rdlock sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_rwlock_rdlock) (pthread_rwlock_t *);$/;" m struct:pthread_functions
+ptr_pthread_rwlock_unlock sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_rwlock_unlock) (pthread_rwlock_t *);$/;" m struct:pthread_functions
+ptr_pthread_rwlock_wrlock sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_rwlock_wrlock) (pthread_rwlock_t *);$/;" m struct:pthread_functions
+ptr_pthread_self sysdeps/pthread/pthread-functions.h /^ pthread_t (*ptr_pthread_self) (void);$/;" m struct:pthread_functions
+ptr_pthread_setcanceltype sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_setcanceltype) (int, int *);$/;" m struct:pthread_functions
+ptr_pthread_setschedparam sysdeps/pthread/pthread-functions.h /^ int (*ptr_pthread_setschedparam) (pthread_t, int,$/;" m struct:pthread_functions
+raise sysdeps/generic/raise.c /^raise (int signo)$/;" f
+res_state pthread/pt-internal.h /^ struct __res_state res_state;$/;" m struct:__pthread typeref:struct:__pthread::__res_state
+routines Makefile /^routines := forward libc_pthread_init alloca_cutoff$/;" m
+rwlock tests/test-15.c /^pthread_rwlock_t rwlock;$/;" v
+self pthread/pt-internal.h /^ thread_t self; \/* This thread's control port. *\/$/;" m struct:__anon1
+sem_t sysdeps/pthread/semaphore.h /^typedef struct __semaphore sem_t;$/;" t typeref:struct:__semaphore
+shared-only-routines Makefile /^shared-only-routines = forward$/;" m
+sp sysdeps/i386/pt-machdep.h /^ void *sp;$/;" m struct:pthread_mcontext
+srcdir Makefile /^srcdir = .$/;" m
+stack pthread/pt-internal.h /^ int stack; \/* Nonzero if the stack was allocated. *\/$/;" m struct:__pthread
+stack_setup sysdeps/mach/hurd/i386/pt-setup.c /^stack_setup (struct __pthread *thread,$/;" f file:
+stackaddr pthread/pt-internal.h /^ void *stackaddr;$/;" m struct:__pthread
+stacksize pthread/pt-internal.h /^ size_t stacksize;$/;" m struct:__pthread
+stacksize tests/test-4.c /^size_t stacksize;$/;" v
+state pthread/pt-internal.h /^ enum pthread_state state;$/;" m struct:__pthread typeref:enum:__pthread::pthread_state
+state_cond pthread/pt-internal.h /^ pthread_cond_t state_cond; \/* Signalled when the state changes. *\/$/;" m struct:__pthread
+state_lock pthread/pt-internal.h /^ pthread_mutex_t state_lock; \/* Locks the state. *\/$/;" m struct:__pthread
+status pthread/pt-internal.h /^ void *status;$/;" m struct:__pthread
+subdir Makefile /^subdir := htl$/;" m
+tcb pthread/pt-internal.h /^ tcbhead_t *tcb;$/;" m struct:__pthread
+tcb pthread/pt-internal.h /^ void *tcb; \/* Points to this structure. *\/$/;" m struct:__anon1
+tcbhead_t pthread/pt-internal.h /^} tcbhead_t;$/;" t typeref:struct:__anon1
+test tests/test-15.c /^test (void *arg)$/;" f
+test tests/test-16.c /^test (void *arg)$/;" f
+test tests/test-__pthread_destroy_specific-skip.c /^test (void *x)$/;" f file:
+test1 tests/test-11.c /^test1 (void *arg)$/;" f
+testthread tests/test-16.c /^pthread_t testthread;$/;" v
+thr tests/test-4.c /^thr (void *arg)$/;" f
+thr tests/test-5.c /^thr (void *arg)$/;" f
+thr tests/test-7.c /^thr (void *arg)$/;" f
+thr tests/test-8.c /^thr (void *arg)$/;" f
+thr tests/test-9.c /^thr (void *arg)$/;" f
+thread pthread/pt-internal.h /^ pthread_t thread;$/;" m struct:__pthread
+thread tests/test-2.c /^thread (void *arg)$/;" f
+thread_attr_compare sysdeps/generic/timer_routines.h /^thread_attr_compare (const pthread_attr_t *left, const pthread_attr_t *right)$/;" f
+v tests/test-__pthread_destroy_specific-skip.c /^static volatile int v;$/;" v file:
+var tests/test-8.c /^int var;$/;" v
+wakeup sysdeps/generic/pt-cond-timedwait.c /^ struct __pthread *wakeup;$/;" m struct:cancel_ctx typeref:struct:cancel_ctx::__pthread file:
+weak_alias pthread/cthreads-compat.c /^weak_alias (__cthread_detach, cthread_detach)$/;" f
+weak_alias pthread/cthreads-compat.c /^weak_alias (__cthread_fork, cthread_fork)$/;" f
+weak_alias pthread/cthreads-compat.c /^weak_alias (__cthread_getspecific, cthread_getspecific)$/;" f
+weak_alias pthread/cthreads-compat.c /^weak_alias (__cthread_keycreate, cthread_keycreate)$/;" f
+weak_alias pthread/cthreads-compat.c /^weak_alias (__cthread_setspecific, cthread_setspecific)$/;" f
+work tests/test-17.c /^work (int iter)$/;" f
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..6ec1afb
--- /dev/null
+++ b/htl/tests/test-1.c
@@ -0,0 +1,50 @@
+#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..bec05c1
--- /dev/null
+++ b/htl/tests/test-10.c
@@ -0,0 +1,46 @@
+/* Test error checking mutexes. */
+
+#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..f5a5aa0
--- /dev/null
+++ b/htl/tests/test-11.c
@@ -0,0 +1,143 @@
+/* Test rwlocks. */
+
+#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..2b78490
--- /dev/null
+++ b/htl/tests/test-12.c
@@ -0,0 +1,29 @@
+/* Test concurrency level. */
+
+#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..13b0905
--- /dev/null
+++ b/htl/tests/test-13.c
@@ -0,0 +1,66 @@
+/* Test condition attributes and pthread_cond_timedwait. */
+
+#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..b1dbfa6
--- /dev/null
+++ b/htl/tests/test-14.c
@@ -0,0 +1,44 @@
+/* Test pthread_mutex_timedlock. */
+
+#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..173f8b6
--- /dev/null
+++ b/htl/tests/test-15.c
@@ -0,0 +1,87 @@
+/* Test pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock. */
+
+#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..3660f5f
--- /dev/null
+++ b/htl/tests/test-16.c
@@ -0,0 +1,71 @@
+/* Test pthread_kill.c. */
+
+#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..a8bd150
--- /dev/null
+++ b/htl/tests/test-17.c
@@ -0,0 +1,57 @@
+/* Test that the key reuse inside libpthread does not cause thread
+ specific values to persist. */
+
+#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..701462e
--- /dev/null
+++ b/htl/tests/test-2.c
@@ -0,0 +1,39 @@
+/* Test detachability. */
+#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..7db2e43
--- /dev/null
+++ b/htl/tests/test-3.c
@@ -0,0 +1,55 @@
+/* Test the thread attribute get and set methods. */
+
+#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..de9c8fe
--- /dev/null
+++ b/htl/tests/test-4.c
@@ -0,0 +1,86 @@
+/* Test the stack guard. */
+
+#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..0f5000b
--- /dev/null
+++ b/htl/tests/test-5.c
@@ -0,0 +1,75 @@
+/* Test signals. */
+
+#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..205c7a4
--- /dev/null
+++ b/htl/tests/test-6.c
@@ -0,0 +1,96 @@
+#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..be724ce
--- /dev/null
+++ b/htl/tests/test-7.c
@@ -0,0 +1,70 @@
+#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..85a7f8f
--- /dev/null
+++ b/htl/tests/test-8.c
@@ -0,0 +1,60 @@
+#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..8205157
--- /dev/null
+++ b/htl/tests/test-9.c
@@ -0,0 +1,88 @@
+/* Test recursive mutexes. */
+
+#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..b2c4c0b
--- /dev/null
+++ b/htl/tests/test-__pthread_destroy_specific-skip.c
@@ -0,0 +1,83 @@
+/* Check that __pthread_destroy_specific works correctly if it has to skip
+ unused slots. */
+
+#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/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..be93619
--- /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..13a8163
--- /dev/null
+++ b/sysdeps/htl/bits/pthread.h
@@ -0,0 +1,37 @@
+/* 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..3e42f50
--- /dev/null
+++ b/sysdeps/htl/bits/pthreadtypes.h
@@ -0,0 +1,133 @@
+/*
+ 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..94f4da2
--- /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..a4c0f61
--- /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..11c685e
--- /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..d12c0a2
--- /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..64b1c8c
--- /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..3459e48
--- /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..38bbe28
--- /dev/null
+++ b/sysdeps/htl/flockfile.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, 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..f46bb98
--- /dev/null
+++ b/sysdeps/htl/fork.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, 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..34f6e54
--- /dev/null
+++ b/sysdeps/htl/ftrylockfile.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, 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..ef51ce3
--- /dev/null
+++ b/sysdeps/htl/funlockfile.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, 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..d1f3086
--- /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..91cd43e
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getdetachstate.c
@@ -0,0 +1,30 @@
+/* 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..c6f8016
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getguardsize.c
@@ -0,0 +1,28 @@
+/* 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..2157cd7
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getinheritsched.c
@@ -0,0 +1,30 @@
+/* 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..b1b81d9
--- /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..88f448f
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getschedpolicy.c
@@ -0,0 +1,30 @@
+/* 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..4b013d2
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getscope.c
@@ -0,0 +1,30 @@
+/* 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..eaa7b6a
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getstack.c
@@ -0,0 +1,31 @@
+/* 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..6dc86c4
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getstackaddr.c
@@ -0,0 +1,28 @@
+/* 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..484076e
--- /dev/null
+++ b/sysdeps/htl/pt-attr-getstacksize.c
@@ -0,0 +1,28 @@
+/* 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..5380d16
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setdetachstate.c
@@ -0,0 +1,39 @@
+/* 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..63513fa
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setguardsize.c
@@ -0,0 +1,28 @@
+/* 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..b04cbf9
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setinheritsched.c
@@ -0,0 +1,39 @@
+/* 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..356f83b
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setschedparam.c
@@ -0,0 +1,39 @@
+/* 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..e70e348
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setschedpolicy.c
@@ -0,0 +1,43 @@
+/* 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..34de408
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setscope.c
@@ -0,0 +1,42 @@
+/* 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..61bc3c0
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setstack.c
@@ -0,0 +1,50 @@
+/* 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..ac37d97
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setstackaddr.c
@@ -0,0 +1,28 @@
+/* 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..ba6f2eb
--- /dev/null
+++ b/sysdeps/htl/pt-attr-setstacksize.c
@@ -0,0 +1,29 @@
+/* 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..5a56f7f
--- /dev/null
+++ b/sysdeps/htl/pt-attr.c
@@ -0,0 +1,40 @@
+/* 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..8940779
--- /dev/null
+++ b/sysdeps/htl/pt-barrier-init.c
@@ -0,0 +1,52 @@
+/* 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
+ || 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)
+ 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..5c01349
--- /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..846887d
--- /dev/null
+++ b/sysdeps/htl/pt-barrier.c
@@ -0,0 +1,25 @@
+/* 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..dced161
--- /dev/null
+++ b/sysdeps/htl/pt-barrierattr-setpshared.c
@@ -0,0 +1,38 @@
+/* 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..8cadc95
--- /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..e11fa85
--- /dev/null
+++ b/sysdeps/htl/pt-cond-init.c
@@ -0,0 +1,46 @@
+/* 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
+ || 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)
+ 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..68bd6d9
--- /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)
+ __pthread_dequeue (wakeup);
+ __pthread_spin_unlock (&cond->__lock);
+
+ if (wakeup)
+ __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..a7d5ce0
--- /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)
+ 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)
+ err = __pthread_timedblock (self, abstime, clock_id);
+ else
+ {
+ err = 0;
+ __pthread_block (self);
+ }
+
+ __pthread_spin_lock (&cond->__lock);
+ if (! self->prevp)
+ {
+ /* 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..ef04750
--- /dev/null
+++ b/sysdeps/htl/pt-cond.c
@@ -0,0 +1,28 @@
+/* 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..6b6d67d
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-getclock.c
@@ -0,0 +1,30 @@
+/* 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..7fbb74e
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-getpshared.c
@@ -0,0 +1,28 @@
+/* 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..231461f
--- /dev/null
+++ b/sysdeps/htl/pt-condattr-setpshared.c
@@ -0,0 +1,38 @@
+/* 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..60332b5
--- /dev/null
+++ b/sysdeps/htl/pt-destroy-specific.c
@@ -0,0 +1,76 @@
+/* __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)
+ 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)
+ {
+ 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..769954c
--- /dev/null
+++ b/sysdeps/htl/pt-getcpuclockid.c
@@ -0,0 +1,34 @@
+/* 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;
+stub_warning (pthread_getcpuclockid)
+#endif
+}
diff --git a/sysdeps/htl/pt-getschedparam.c b/sysdeps/htl/pt-getschedparam.c
new file mode 100644
index 0000000..25022b3
--- /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..3f57190
--- /dev/null
+++ b/sysdeps/htl/pt-key-create.c
@@ -0,0 +1,109 @@
+/* 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)
+ {
+ __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..ca08444
--- /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..e16e343
--- /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..177b8c7
--- /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..03c9a65
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-getprioceiling.c
@@ -0,0 +1,29 @@
+/* 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..8e563b4
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-init.c
@@ -0,0 +1,49 @@
+/* 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
+ || memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0))
+ /* The default attributes. */
+ return 0;
+
+ if (! mutex->__attr
+ || mutex->__attr == __PTHREAD_ERRORCHECK_MUTEXATTR
+ || mutex->__attr == __PTHREAD_RECURSIVE_MUTEXATTR)
+ mutex->__attr = malloc (sizeof *attr);
+
+ if (! mutex->__attr)
+ 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..266d17f
--- /dev/null
+++ b/sysdeps/htl/pt-mutex-setprioceiling.c
@@ -0,0 +1,29 @@
+/* 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..dcff333
--- /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)
+ /* 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);
+ mutex->__owner = _pthread_self ();
+ }
+#endif
+#endif
+
+ if (attr)
+ 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 || 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 && attr->__mutex_type != PTHREAD_MUTEX_NORMAL)
+#endif
+ assert (mutex->__owner);
+
+ if (abstime && (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)
+ err = __pthread_timedblock (self, abstime, CLOCK_REALTIME);
+ else
+ {
+ err = 0;
+ __pthread_block (self);
+ }
+
+ __pthread_spin_lock (&mutex->__lock);
+ if (! self->prevp)
+ /* 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 && attr->__mutex_type != PTHREAD_MUTEX_NORMAL)
+#endif
+ {
+ assert (mutex->__owner == self);
+ }
+
+ if (attr)
+ 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..6770879
--- /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)
+ 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 && 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 && 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..0c35a40
--- /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)
+ /* 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);
+ mutex->__owner = _pthread_self ();
+ }
+#endif
+#endif
+
+ if (attr)
+ 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)
+ {
+ 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..34bed33
--- /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 || 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 && 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..42ff8b1
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-getprotocol.c
@@ -0,0 +1,28 @@
+/* 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..e6478b3
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-getpshared.c
@@ -0,0 +1,28 @@
+/* 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..81aef55
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-setprioceiling.c
@@ -0,0 +1,29 @@
+/* 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..9985def
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-setprotocol.c
@@ -0,0 +1,41 @@
+/* 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..7fb7d6d
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr-setpshared.c
@@ -0,0 +1,38 @@
+/* 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..e6d64e0
--- /dev/null
+++ b/sysdeps/htl/pt-mutexattr.c
@@ -0,0 +1,44 @@
+/* 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..d9e90b7
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-attr.c
@@ -0,0 +1,25 @@
+/* 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..9ffc2c6
--- /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
+ || 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)
+ 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..1033d20
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-rdlock.c
@@ -0,0 +1,32 @@
+/* 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..db44000
--- /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 && (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)
+ err = __pthread_timedblock (self, abstime, CLOCK_REALTIME);
+ else
+ {
+ err = 0;
+ __pthread_block (self);
+ }
+
+ __pthread_spin_lock (&rwlock->__lock);
+ if (! self->prevp)
+ /* 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..3eddbe9
--- /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 && (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)
+ err = __pthread_timedblock (self, abstime, CLOCK_REALTIME);
+ else
+ {
+ err = 0;
+ __pthread_block (self);
+ }
+
+ __pthread_spin_lock (&rwlock->__lock);
+ if (! self->prevp)
+ /* 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..8745437
--- /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..32446e8
--- /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..d02036a
--- /dev/null
+++ b/sysdeps/htl/pt-rwlock-wrlock.c
@@ -0,0 +1,34 @@
+/* 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..04469f8
--- /dev/null
+++ b/sysdeps/htl/pt-rwlockattr-getpshared.c
@@ -0,0 +1,28 @@
+/* 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..b3997c0
--- /dev/null
+++ b/sysdeps/htl/pt-rwlockattr-setpshared.c
@@ -0,0 +1,38 @@
+/* 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..42763de
--- /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..e875bd1
--- /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 )
+ 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..49adbe5
--- /dev/null
+++ b/sysdeps/htl/pthread-functions.h
@@ -0,0 +1,140 @@
+/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, 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..13c5693
--- /dev/null
+++ b/sysdeps/htl/pthread.h
@@ -0,0 +1,882 @@
+/* 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..5559fd3
--- /dev/null
+++ b/sysdeps/htl/pthreadP.h
@@ -0,0 +1,45 @@
+/* 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..4571ef0
--- /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 && __pthread_threads)
+ {
+ 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..e74415a
--- /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);
+ sem->__value ++;
+ __pthread_spin_unlock (&sem->__lock);
+ return 0;
+ }
+
+ if (! sem->__queue)
+ /* 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..9830d5e
--- /dev/null
+++ b/sysdeps/htl/sem-timedwait.c
@@ -0,0 +1,99 @@
+/* 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 && (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)
+ err = __pthread_timedblock (self, timeout, CLOCK_REALTIME);
+ else
+ {
+ err = 0;
+ __pthread_block (self);
+ }
+
+ __pthread_spin_lock (&sem->__lock);
+ if (! self->prevp)
+ /* 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..c771634
--- /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..50b1721
--- /dev/null
+++ b/sysdeps/htl/shm-directory.h
@@ -0,0 +1,31 @@
+/* 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..21da7d9
--- /dev/null
+++ b/sysdeps/htl/timer_routines.h
@@ -0,0 +1,47 @@
+/* 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.
+ Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General 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..d1605e8
--- /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)
+ 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..57fc1ca
--- /dev/null
+++ b/sysdeps/i386/htl/bits/pthreadtypes-arch.h
@@ -0,0 +1,21 @@
+/* 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..5000468
--- /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..2167ca3
--- /dev/null
+++ b/sysdeps/mach/htl/pt-stack-alloc.c
@@ -0,0 +1,68 @@
+/* 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..257d5d2
--- /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..07fbc30
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-start.c
@@ -0,0 +1,50 @@
+/* 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..b9e094e
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-terminate.c
@@ -0,0 +1,84 @@
+/* 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..ad0ae0b
--- /dev/null
+++ b/sysdeps/mach/htl/pt-timedblock.c
@@ -0,0 +1,67 @@
+/* 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..71f6efa
--- /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..ed55331
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c
@@ -0,0 +1,28 @@
+/* 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..101ec6a
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c
@@ -0,0 +1,28 @@
+/* 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..767122d
--- /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..93dc25c
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
@@ -0,0 +1,168 @@
+/* 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 && (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)
+ 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)
+ /* 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)
+ /* 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..fd3e0bd
--- /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..771a1ef
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-consistent.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..eee55fc
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-destroy.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..367db3a
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..4e9720e
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-init.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..642129f
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-lock.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..a983886
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..006a8d8
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c
@@ -0,0 +1,80 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..794f325
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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)
+ 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..14144f5
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-trylock.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..80ca5b9
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-unlock.c
@@ -0,0 +1,90 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..cbf774e
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex.h
@@ -0,0 +1,91 @@
+/* Internal definitions for pthreads library.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the 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..7c9dab1
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..94a3b0c
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..3f7a4c9
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..322c9c8
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..68adf41
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..e3f9bd6
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..b15cff6
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-init.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..c37e300
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..6c45218
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..ceecbf0
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..e013d44
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..5bd890d
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <avarzille@riseup.net>, 2016.
+
+ 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..11299bf
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sigstate.c
@@ -0,0 +1,71 @@
+/* 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)
+ *oset = ss->blocked;
+
+ if (set)
+ {
+ 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..1478738
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.c
@@ -0,0 +1,97 @@
+/* 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)
+ /* Already initialized */
+ return 0;
+
+ /* Initialize the library. */
+ ___pthread_init ();
+
+ if (stack)
+ {
+ /* 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..e44da17
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.h
@@ -0,0 +1,66 @@
+/* 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_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/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..c43b00c
--- /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..96ea95c
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/htl/pt-setup.c
@@ -0,0 +1,109 @@
+/* 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)
+ {
+ /* 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;
+}
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a35d3a4a24c75c333221f6d20a9b1d100c104658
commit a35d3a4a24c75c333221f6d20a9b1d100c104658
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Sun Jan 28 23:29:47 2018 +0100
hurd: Add libphread.so ABI file
* sysdeps/mach/hurd/i386/libpthread.abilist: New file.
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
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9e42952f196bb3119a028beba7d5d95f3d367efa
commit 9e42952f196bb3119a028beba7d5d95f3d367efa
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Thu Jan 18 23:53:22 2018 +0100
t2.25/tls
Fix tls support for glibc 2.25
* csu/libc-start.c (LIBC_START_MAIN) [__GNU__]: Do not call
__libc_setup_tls.
* sysdeps/mach/hurd/i386/init-first.c (init): Call __libc_setup_tls.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 605222f..8e92cc0 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -193,8 +193,10 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
/* Perform IREL{,A} relocations. */
ARCH_SETUP_IREL ();
+#ifndef __GNU__
/* The stack guard goes into the TCB, so initialize it early. */
__libc_setup_tls ();
+#endif
/* In some architectures, IREL{,A} relocations happen after TLS setup in
order to let IFUNC resolvers benefit from TCB information, e.g. powerpc's
diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c
index a7288d1..434c0b7 100644
--- a/sysdeps/mach/hurd/i386/init-first.c
+++ b/sysdeps/mach/hurd/i386/init-first.c
@@ -186,7 +186,8 @@ init (int *data)
assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
}
- /* We need to setup TLS before starting the signal thread. */
+ /* We need to setup TLS before starting sigthread and set stack guard. */
+ __libc_setup_tls ();
extern void __pthread_initialize_minimal (void);
if (__pthread_initialize_minimal != NULL)
__pthread_initialize_minimal ();
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2be76feb8a76a5b5c175e65e4302ed08efb164ac
commit 2be76feb8a76a5b5c175e65e4302ed08efb164ac
Author: Samuel Thibault <samuel.thibault@gnu.org>
Date: Thu Jan 18 23:49:53 2018 +0100
t/tls
Fix errno access and initialization
diff --git a/include/errno.h b/include/errno.h
index 3c3d228..32c2f49 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -24,13 +24,15 @@ extern int rtld_errno attribute_hidden;
# include <tls.h>
-# undef errno
-# if IS_IN (libc)
-# define errno __libc_errno
-# else
-# define errno errno /* For #ifndef errno tests. */
-# endif
+# if !(defined(__GNU__) && IS_IN (rtld))
+# undef errno
+# if IS_IN (libc)
+# define errno __libc_errno
+# else
+# define errno errno /* For #ifndef errno tests. */
+# endif
extern __thread int errno attribute_tls_model_ie;
+# endif
# endif /* IS_IN_LIB */
diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c
index e272e32..a7288d1 100644
--- a/sysdeps/mach/hurd/i386/init-first.c
+++ b/sysdeps/mach/hurd/i386/init-first.c
@@ -107,33 +107,11 @@ init1 (int argc, char *arg0, ...)
/* If we are the bootstrap task started by the kernel,
then after the environment pointers there is no Hurd
data block; the argument strings start there. */
- if ((void *) d == argv[0] || d->phdr == 0)
- {
-#ifndef SHARED
- /* With a new enough linker (binutils-2.23 or better),
- the magic __ehdr_start symbol will be available and
- __libc_start_main will have done this that way already. */
- if (_dl_phdr == NULL)
- {
- /* We may need to see our own phdrs, e.g. for TLS setup.
- Try the usual kludge to find the headers without help from
- the exec server. */
- extern const void __executable_start;
- const ElfW(Ehdr) *const ehdr = &__executable_start;
- _dl_phdr = (const void *) ehdr + ehdr->e_phoff;
- _dl_phnum = ehdr->e_phnum;
- assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
- }
-#endif
- return;
- }
+ if ((void *) d == argv[0])
+ return;
#ifndef SHARED
__libc_enable_secure = d->flags & EXEC_SECURE;
-
- _dl_phdr = (ElfW(Phdr) *) d->phdr;
- _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
- assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
#endif
_hurd_init_dtable = d->dtable;
@@ -180,6 +158,39 @@ init (int *data)
++envp;
d = (void *) ++envp;
+#ifndef SHARED
+ /* If we are the bootstrap task started by the kernel,
+ then after the environment pointers there is no Hurd
+ data block; the argument strings start there. */
+ if ((void *) d == argv[0] || d->phdr == 0)
+ {
+ /* With a new enough linker (binutils-2.23 or better),
+ the magic __ehdr_start symbol will be available and
+ __libc_start_main will have done this that way already. */
+ if (_dl_phdr == NULL)
+ {
+ /* We may need to see our own phdrs, e.g. for TLS setup.
+ Try the usual kludge to find the headers without help from
+ the exec server. */
+ extern const void __executable_start;
+ const ElfW(Ehdr) *const ehdr = &__executable_start;
+ _dl_phdr = (const void *) ehdr + ehdr->e_phoff;
+ _dl_phnum = ehdr->e_phnum;
+ assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
+ }
+ }
+ else
+ {
+ _dl_phdr = (ElfW(Phdr) *) d->phdr;
+ _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
+ assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
+ }
+
+ /* We need to setup TLS before starting the signal thread. */
+ extern void __pthread_initialize_minimal (void);
+ if (__pthread_initialize_minimal != NULL)
+ __pthread_initialize_minimal ();
+#endif
/* After possibly switching stacks, call `init1' (above) with the user
code as the return address, and the argument data immediately above
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=778f865240e8ce926af058becba447541aae5b03
commit 778f865240e8ce926af058becba447541aae5b03
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Thu Jan 18 23:38:57 2018 +0100
t/posix_thread
Declare that we have a libpthread.
The additional version in Versions.def should be updated when we'd
actually get the libpthread commited into glibc (as well as in
libpthread/Versions).
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
diff --git a/sysdeps/mach/hurd/bits/local_lim.h b/sysdeps/mach/hurd/bits/local_lim.h
index 8a1af91..97f87ad 100644
--- a/sysdeps/mach/hurd/bits/local_lim.h
+++ b/sysdeps/mach/hurd/bits/local_lim.h
@@ -32,3 +32,12 @@
suitable, and `sysconf' will return a number at least as large. */
#define NGROUPS_MAX 256
+
+/* The number of data keys per process. */
+#define _POSIX_THREAD_KEYS_MAX 128
+
+/* Controlling the iterations of destructors for thread-specific data. */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+
+/* The number of threads per process. */
+#define _POSIX_THREAD_THREADS_MAX 64
diff --git a/sysdeps/mach/hurd/bits/posix_opt.h b/sysdeps/mach/hurd/bits/posix_opt.h
index 828d7ff..e0df9bf 100644
--- a/sysdeps/mach/hurd/bits/posix_opt.h
+++ b/sysdeps/mach/hurd/bits/posix_opt.h
@@ -71,24 +71,38 @@
/* XPG4.2 shared memory is not supported. */
#undef _XOPEN_SHM
-/* We do not have the POSIX threads interface. */
-#define _POSIX_THREADS -1
+/* Tell we have POSIX threads. */
+#define _POSIX_THREADS 200112L
/* We have the reentrant functions described in POSIX. */
#define _POSIX_REENTRANT_FUNCTIONS 1
#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
-/* These are all things that won't be supported when _POSIX_THREADS is not. */
+/* We do not provide priority scheduling for threads. */
#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
-#define _POSIX_THREAD_ATTR_STACKSIZE -1
-#define _POSIX_THREAD_ATTR_STACKADDR -1
+
+/* We support user-defined stack sizes. */
+#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
+
+/* We support user-defined stacks. */
+#define _POSIX_THREAD_ATTR_STACKADDR 200112L
+
+/* We do not support priority inheritence. */
#define _POSIX_THREAD_PRIO_INHERIT -1
+
+/* We do not support priority protection. */
#define _POSIX_THREAD_PRIO_PROTECT -1
+
#ifdef __USE_XOPEN2K8
+/* We do not support priority inheritence for robust mutexes. */
# define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1
+
+/* We do not support priority protection for robust mutexes. */
# define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1
#endif
-#define _POSIX_SEMAPHORES -1
+
+/* We support POSIX.1b semaphores. */
+#define _POSIX_SEMAPHORES 200112L
/* Real-time signals are not yet supported. */
#define _POSIX_REALTIME_SIGNALS -1
@@ -121,17 +135,17 @@
/* GNU libc provides regular expression handling. */
#define _POSIX_REGEXP 1
-/* Reader/Writer locks are not available. */
-#define _POSIX_READER_WRITER_LOCKS -1
+/* Reader/Writer locks are available. */
+#define _POSIX_READER_WRITER_LOCKS 200112L
/* We have a POSIX shell. */
#define _POSIX_SHELL 1
-/* We cannot support the Timeouts option without _POSIX_THREADS. */
-#define _POSIX_TIMEOUTS -1
+/* We support the Timeouts option. */
+#define _POSIX_TIMEOUTS 200112L
-/* We do not support spinlocks. */
-#define _POSIX_SPIN_LOCKS -1
+/* We support spinlocks. */
+#define _POSIX_SPIN_LOCKS 200112L
/* The `spawn' function family is supported. */
#define _POSIX_SPAWN 200809L
@@ -139,8 +153,8 @@
/* We do not have POSIX timers, but could in future without ABI change. */
#define _POSIX_TIMERS 0
-/* The barrier functions are not available. */
-#define _POSIX_BARRIERS -1
+/* We support barrier functions. */
+#define _POSIX_BARRIERS 200112L
/* POSIX message queues could be available in future. */
#define _POSIX_MESSAGE_PASSING 0
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f9879926e4e761929733b6f39b3192d90baf939e
commit f9879926e4e761929733b6f39b3192d90baf939e
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Thu Jan 18 23:38:29 2018 +0100
t/libpthread_depends
libpthread needs to be built before modules which need it.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
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
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources