aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/mach
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-04-02 01:43:22 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-04-02 01:44:14 +0200
commit33574c17eefcf326c1cd30eb9f915ad26d3d9ef2 (patch)
tree2c1b143f2b7a0ceba9fba000b70dd2889d56e60f /sysdeps/mach
parent03e2aa50fd512449025bba8c244d16338d8526a4 (diff)
downloadglibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.zip
glibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.tar.gz
glibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.tar.bz2
hurd: Add hurd thread library
Contributed by Agustina Arzille <avarzille@riseup.net> Amos Jeffries <squid3@treenet.co.nz> David Michael <fedora.dm0@gmail.com> Marco Gerards <marco@gnu.org> Marcus Brinkmann <marcus@gnu.org> Neal H. Walfield <neal@gnu.org> Pino Toscano <toscano.pino@tiscali.it> Richard Braun <rbraun@sceen.net> Roland McGrath <roland@gnu.org> Samuel Thibault <samuel.thibault@ens-lyon.org> Thomas DiModica <ricinwich@yahoo.com> Thomas Schwinge <tschwinge@gnu.org> * htl: New directory. * sysdeps/htl: New directory. * sysdeps/hurd/htl: New directory. * sysdeps/i386/htl: New directory. * sysdeps/mach/htl: New directory. * sysdeps/mach/hurd/htl: New directory. * sysdeps/mach/hurd/i386/htl: New directory. * nscd/Depend, resolv/Depend, rt/Depend: Add htl dependency. * sysdeps/mach/hurd/i386/Implies: Add mach/hurd/i386/htl imply. * sysdeps/mach/hurd/i386/libpthread.abilist: New file.
Diffstat (limited to 'sysdeps/mach')
-rw-r--r--sysdeps/mach/htl/Implies1
-rw-r--r--sysdeps/mach/htl/bits/spin-lock-inline.h87
-rw-r--r--sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h34
-rw-r--r--sysdeps/mach/htl/pt-block.c38
-rw-r--r--sysdeps/mach/htl/pt-spin.c31
-rw-r--r--sysdeps/mach/htl/pt-stack-alloc.c67
-rw-r--r--sysdeps/mach/htl/pt-thread-alloc.c94
-rw-r--r--sysdeps/mach/htl/pt-thread-start.c53
-rw-r--r--sysdeps/mach/htl/pt-thread-terminate.c82
-rw-r--r--sysdeps/mach/htl/pt-timedblock.c65
-rw-r--r--sysdeps/mach/htl/pt-wakeup.c37
-rw-r--r--sysdeps/mach/hurd/htl/Implies2
-rw-r--r--sysdeps/mach/hurd/htl/bits/pthread-np.h37
-rw-r--r--sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h49
-rw-r--r--sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c27
-rw-r--r--sysdeps/mach/hurd/htl/pt-attr-setstacksize.c27
-rw-r--r--sysdeps/mach/hurd/htl/pt-docancel.c65
-rw-r--r--sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c169
-rw-r--r--sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c40
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-consistent.c48
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-destroy.c38
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-init.c56
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-lock.c81
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c36
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-timedlock.c79
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c77
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-trylock.c85
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex-unlock.c92
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutex.h90
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c34
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c32
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c32
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c32
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-init.c40
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c34
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c35
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c37
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr-settype.c36
-rw-r--r--sysdeps/mach/hurd/htl/pt-mutexattr.c1
-rw-r--r--sysdeps/mach/hurd/htl/pt-sigstate-destroy.c26
-rw-r--r--sysdeps/mach/hurd/htl/pt-sigstate-init.c44
-rw-r--r--sysdeps/mach/hurd/htl/pt-sigstate.c70
-rw-r--r--sysdeps/mach/hurd/htl/pt-sysdep.c99
-rw-r--r--sysdeps/mach/hurd/htl/pt-sysdep.h65
-rw-r--r--sysdeps/mach/hurd/i386/Implies1
-rw-r--r--sysdeps/mach/hurd/i386/htl/Implies2
-rw-r--r--sysdeps/mach/hurd/i386/htl/pt-machdep.c82
-rw-r--r--sysdeps/mach/hurd/i386/htl/pt-setup.c110
-rw-r--r--sysdeps/mach/hurd/i386/libpthread.abilist151
53 files changed, 2790 insertions, 0 deletions
diff --git a/sysdeps/mach/htl/Implies b/sysdeps/mach/htl/Implies
new file mode 100644
index 0000000..5215f33
--- /dev/null
+++ b/sysdeps/mach/htl/Implies
@@ -0,0 +1 @@
+htl
diff --git a/sysdeps/mach/htl/bits/spin-lock-inline.h b/sysdeps/mach/htl/bits/spin-lock-inline.h
new file mode 100644
index 0000000..695c6dc
--- /dev/null
+++ b/sysdeps/mach/htl/bits/spin-lock-inline.h
@@ -0,0 +1,87 @@
+/* Definitions of user-visible names for spin locks.
+ Copyright (C) 1994-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_SPIN_LOCK_INLINE_H
+#define _BITS_SPIN_LOCK_INLINE_H 1
+
+#include <features.h>
+#include <bits/types/__pthread_spinlock_t.h>
+#include <lock-intern.h> /* This does all the work. */
+
+__BEGIN_DECLS
+
+#if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES
+
+# ifndef __EBUSY
+# include <errno.h>
+# define __EBUSY EBUSY
+# endif
+
+# ifndef __PT_SPIN_INLINE
+# define __PT_SPIN_INLINE __extern_inline
+# endif
+
+__PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_destroy (__pthread_spinlock_t *__lock)
+{
+ return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock,
+ int __pshared);
+
+__PT_SPIN_INLINE int
+__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared)
+{
+ *__lock = __PTHREAD_SPIN_LOCK_INITIALIZER;
+ return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_trylock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_trylock (__pthread_spinlock_t *__lock)
+{
+ return __spin_try_lock ((__spin_lock_t *) __lock) ? 0 : __EBUSY;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_lock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_lock (__pthread_spinlock_t *__lock)
+{
+ __spin_lock ((__spin_lock_t *) __lock);
+ return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_unlock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_unlock (__pthread_spinlock_t *__lock)
+{
+ __spin_unlock ((__spin_lock_t *) __lock);
+ return 0;
+}
+
+#endif /* Use extern inlines or force inlines. */
+
+__END_DECLS
+
+#endif /* bits/types/__pthread_spinlock_t.h */
diff --git a/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h b/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h
new file mode 100644
index 0000000..038e2b4
--- /dev/null
+++ b/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h
@@ -0,0 +1,34 @@
+/* Definitions of user-visible names for spin locks.
+ Copyright (C) 1994-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_TYPES___PTHREAD_SPINLOCK_T_H
+#define _BITS_TYPES___PTHREAD_SPINLOCK_T_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* The type of a spin lock object. */
+typedef volatile int __pthread_spinlock_t;
+
+/* Initializer for a spin lock object. */
+#define __PTHREAD_SPIN_LOCK_INITIALIZER 0
+
+__END_DECLS
+
+#endif /* bits/types/__pthread_spinlock_t.h */
diff --git a/sysdeps/mach/htl/pt-block.c b/sysdeps/mach/htl/pt-block.c
new file mode 100644
index 0000000..1ffda81
--- /dev/null
+++ b/sysdeps/mach/htl/pt-block.c
@@ -0,0 +1,38 @@
+/* Block a thread. Mach version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/message.h>
+
+#include <pt-internal.h>
+
+/* Block THREAD. */
+void
+__pthread_block (struct __pthread *thread)
+{
+ mach_msg_header_t msg;
+ error_t err;
+
+ err = __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof msg,
+ thread->wakeupmsg.msgh_remote_port,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ assert_perror (err);
+}
diff --git a/sysdeps/mach/htl/pt-spin.c b/sysdeps/mach/htl/pt-spin.c
new file mode 100644
index 0000000..b2e00ea
--- /dev/null
+++ b/sysdeps/mach/htl/pt-spin.c
@@ -0,0 +1,31 @@
+/* Spin locks. Mach version.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <machine-lock.h>
+
+/* In glibc. */
+extern void __spin_lock_solid (__spin_lock_t *lock);
+
+/* Lock the spin lock object LOCK. If the lock is held by another
+ thread spin until it becomes available. */
+int
+_pthread_spin_lock (__spin_lock_t *lock)
+{
+ __spin_lock_solid (lock);
+ return 0;
+}
diff --git a/sysdeps/mach/htl/pt-stack-alloc.c b/sysdeps/mach/htl/pt-stack-alloc.c
new file mode 100644
index 0000000..6c38c92
--- /dev/null
+++ b/sysdeps/mach/htl/pt-stack-alloc.c
@@ -0,0 +1,67 @@
+/* Allocate a new stack. Mach version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/machine/vm_param.h>
+
+#include <pt-internal.h>
+
+/* The next address to use for stack allocation. */
+static vm_address_t next_stack_base = VM_MIN_ADDRESS;
+
+
+/* Allocate a new stack of size STACKSIZE. If successful, store the
+ address of the newly allocated stack in *STACKADDR and return 0.
+ Otherwise return an error code (EINVAL for an invalid stack size,
+ EAGAIN if the system lacked the necessary resources to allocate a
+ new stack). */
+int
+__pthread_stack_alloc (void **stackaddr, size_t stacksize)
+{
+ vm_offset_t base;
+ int i = 0;
+
+get_stack:
+ i++;
+ for (base = next_stack_base;
+ base < VM_MAX_ADDRESS
+ && __vm_allocate (__mach_task_self (), &base,
+ stacksize, FALSE) != KERN_SUCCESS; base += stacksize)
+ ;
+
+ if (base >= VM_MAX_ADDRESS)
+ {
+ if (i == 1)
+ {
+ next_stack_base = VM_MIN_ADDRESS;
+ goto get_stack;
+ }
+ else
+ return EAGAIN;
+ }
+
+ if (base >= VM_MAX_ADDRESS)
+ return EAGAIN;
+
+ next_stack_base = base + stacksize;
+
+ (*stackaddr) = (void *) base;
+ return 0;
+}
diff --git a/sysdeps/mach/htl/pt-thread-alloc.c b/sysdeps/mach/htl/pt-thread-alloc.c
new file mode 100644
index 0000000..3c763ef
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-alloc.c
@@ -0,0 +1,94 @@
+/* Start thread. Mach version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <mach.h>
+
+#include <pt-internal.h>
+
+/* Prepare a wakeup message. */
+static error_t
+create_wakeupmsg (struct __pthread *thread)
+{
+ kern_return_t err;
+
+ /* Build wakeup message. */
+ thread->wakeupmsg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
+ thread->wakeupmsg.msgh_size = 0;
+
+ err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &thread->wakeupmsg.msgh_remote_port);
+ if (err)
+ return EAGAIN;
+
+ thread->wakeupmsg.msgh_local_port = MACH_PORT_NULL;
+ thread->wakeupmsg.msgh_seqno = 0;
+ thread->wakeupmsg.msgh_id = 0;
+
+ err = __mach_port_insert_right (__mach_task_self (),
+ thread->wakeupmsg.msgh_remote_port,
+ thread->wakeupmsg.msgh_remote_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ if (err)
+ {
+ __mach_port_destroy (__mach_task_self (),
+ thread->wakeupmsg.msgh_remote_port);
+ return EAGAIN;
+ }
+
+ /* No need to queue more than one wakeup message on this port. */
+ __mach_port_set_qlimit (__mach_task_self (),
+ thread->wakeupmsg.msgh_remote_port, 1);
+
+ return 0;
+}
+
+/* Allocate any resouces for THREAD. The new kernel thread should not
+ be eligible to be scheduled. */
+int
+__pthread_thread_alloc (struct __pthread *thread)
+{
+ static int do_create;
+ error_t err;
+
+ err = create_wakeupmsg (thread);
+ if (err)
+ return err;
+
+ if (!do_create)
+ {
+ assert (__pthread_total == 0);
+ thread->kernel_thread = __mach_thread_self ();
+ do_create = 1;
+ }
+ else
+ {
+ err = __thread_create (__mach_task_self (), &thread->kernel_thread);
+ if (err)
+ {
+ __mach_port_destroy (__mach_task_self (),
+ thread->wakeupmsg.msgh_remote_port);
+ return EAGAIN;
+ }
+ }
+
+ return 0;
+}
diff --git a/sysdeps/mach/htl/pt-thread-start.c b/sysdeps/mach/htl/pt-thread-start.c
new file mode 100644
index 0000000..571c1f2
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-start.c
@@ -0,0 +1,53 @@
+/* Start thread. Mach version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+#include <mach.h>
+
+#include <pt-internal.h>
+
+/* Start THREAD. Get the kernel thread scheduled and running. */
+int
+__pthread_thread_start (struct __pthread *thread)
+{
+ static int do_start;
+ error_t err;
+
+ if (!do_start)
+ {
+ /* The main thread is already running: do nothing. */
+ assert (__pthread_total == 1);
+ assert ((
+ {
+ mach_port_t ktid = __mach_thread_self ();
+ int ok = thread->kernel_thread == ktid;
+ __mach_port_deallocate (__mach_task_self (),
+ thread->kernel_thread);
+ ok;
+ }));
+ do_start = 1;
+ }
+ else
+ {
+ err = __thread_resume (thread->kernel_thread);
+ assert_perror (err);
+ }
+
+ return 0;
+}
diff --git a/sysdeps/mach/htl/pt-thread-terminate.c b/sysdeps/mach/htl/pt-thread-terminate.c
new file mode 100644
index 0000000..418fb40
--- /dev/null
+++ b/sysdeps/mach/htl/pt-thread-terminate.c
@@ -0,0 +1,82 @@
+/* Deallocate the kernel thread resources. Mach version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+#include <mach.h>
+
+#include <mach/mig_support.h>
+
+#include <pt-internal.h>
+
+/* Terminate the kernel thread associated with THREAD, and deallocate its
+ right reference and its stack. The function also drops a reference
+ on THREAD. */
+void
+__pthread_thread_terminate (struct __pthread *thread)
+{
+ thread_t kernel_thread, self_ktid;
+ mach_port_t wakeup_port, reply_port;
+ void *stackaddr;
+ size_t stacksize;
+ error_t err;
+
+ kernel_thread = thread->kernel_thread;
+
+ if (thread->stack)
+ {
+ stackaddr = thread->stackaddr;
+ stacksize = ((thread->guardsize + __vm_page_size - 1)
+ / __vm_page_size) * __vm_page_size + thread->stacksize;
+ }
+ else
+ {
+ stackaddr = NULL;
+ stacksize = 0;
+ }
+
+ wakeup_port = thread->wakeupmsg.msgh_remote_port;
+
+ /* Each thread has its own reply port, allocated from MiG stub code calling
+ __mig_get_reply_port. Destroying it is a bit tricky because the calls
+ involved are also RPCs, causing the creation of a new reply port if
+ currently null. The __thread_terminate_release call is actually a one way
+ simple routine designed not to require a reply port. */
+ self_ktid = __mach_thread_self ();
+ reply_port = (self_ktid == kernel_thread)
+ ? __mig_get_reply_port () : MACH_PORT_NULL;
+ __mach_port_deallocate (__mach_task_self (), self_ktid);
+
+ /* Finally done with the thread structure. */
+ __pthread_dealloc (thread);
+
+ /* The wake up port is now no longer needed. */
+ __mach_port_destroy (__mach_task_self (), wakeup_port);
+
+ /* Terminate and release all that's left. */
+ err = __thread_terminate_release (kernel_thread, mach_task_self (),
+ kernel_thread, reply_port,
+ (vm_address_t) stackaddr, stacksize);
+
+ /* The kernel does not support it yet. Leak but at least terminate
+ correctly. */
+ err = __thread_terminate (kernel_thread);
+
+ /* We are out of luck. */
+ assert_perror (err);
+}
diff --git a/sysdeps/mach/htl/pt-timedblock.c b/sysdeps/mach/htl/pt-timedblock.c
new file mode 100644
index 0000000..4255f77
--- /dev/null
+++ b/sysdeps/mach/htl/pt-timedblock.c
@@ -0,0 +1,65 @@
+/* Block a thread with a timeout. Mach version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <mach.h>
+#include <mach/message.h>
+
+#include <pt-internal.h>
+
+/* Block THREAD. */
+error_t
+__pthread_timedblock (struct __pthread *thread,
+ const struct timespec *abstime, clockid_t clock_id)
+{
+ error_t err;
+ mach_msg_header_t msg;
+ mach_msg_timeout_t timeout;
+ struct timespec now;
+
+ /* We have an absolute time and now we have to convert it to a
+ relative time. Arg. */
+
+ err = clock_gettime (clock_id, &now);
+ assert (!err);
+
+ if (now.tv_sec > abstime->tv_sec
+ || (now.tv_sec == abstime->tv_sec && now.tv_nsec > abstime->tv_nsec))
+ return ETIMEDOUT;
+
+ timeout = (abstime->tv_sec - now.tv_sec) * 1000;
+
+ if (abstime->tv_nsec >= now.tv_nsec)
+ timeout += (abstime->tv_nsec - now.tv_nsec + 999999) / 1000000;
+ else
+ /* Need to do a carry. */
+ timeout -= (now.tv_nsec - abstime->tv_nsec + 999999) / 1000000;
+
+ err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
+ sizeof msg, thread->wakeupmsg.msgh_remote_port,
+ timeout, MACH_PORT_NULL);
+ if (err == EMACH_RCV_TIMED_OUT)
+ return ETIMEDOUT;
+
+ assert_perror (err);
+ return 0;
+}
diff --git a/sysdeps/mach/htl/pt-wakeup.c b/sysdeps/mach/htl/pt-wakeup.c
new file mode 100644
index 0000000..1e5488f
--- /dev/null
+++ b/sysdeps/mach/htl/pt-wakeup.c
@@ -0,0 +1,37 @@
+/* Wakeup a thread. Mach version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/message.h>
+
+#include <pt-internal.h>
+
+/* Wakeup THREAD. */
+void
+__pthread_wakeup (struct __pthread *thread)
+{
+ error_t err;
+
+ err = __mach_msg (&thread->wakeupmsg, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
+ sizeof (thread->wakeupmsg), 0, MACH_PORT_NULL,
+ 0, MACH_PORT_NULL);
+ assert_perror (err);
+}
diff --git a/sysdeps/mach/hurd/htl/Implies b/sysdeps/mach/hurd/htl/Implies
new file mode 100644
index 0000000..64daad1
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/Implies
@@ -0,0 +1,2 @@
+hurd/htl
+mach/htl
diff --git a/sysdeps/mach/hurd/htl/bits/pthread-np.h b/sysdeps/mach/hurd/htl/bits/pthread-np.h
new file mode 100644
index 0000000..0acee62
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/bits/pthread-np.h
@@ -0,0 +1,37 @@
+/* Non-portable functions. Hurd on Mach version.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+/*
+ * Never include this file directly; use <pthread.h> or <cthreads.h> instead.
+ */
+
+#ifndef _BITS_PTHREAD_NP_H
+#define _BITS_PTHREAD_NP_H 1
+
+/* Same as pthread_cond_wait, but for Hurd-specific cancellation.
+ See hurd_thread_cancel. */
+extern int pthread_hurd_cond_wait_np (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex);
+
+/* Same as pthread_cond_timedwait, but for Hurd-specific cancellation.
+ See hurd_thread_cancel. */
+extern int pthread_hurd_cond_timedwait_np (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex,
+ const struct timespec *__abstime);
+
+#endif /* bits/pthread-np.h */
diff --git a/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h b/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h
new file mode 100644
index 0000000..4fe87cc
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h
@@ -0,0 +1,49 @@
+/* Mutex type. Generic version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H
+#define _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H 1
+
+#include <bits/types/struct___pthread_mutexattr.h>
+
+/* User visible part of a mutex. */
+struct __pthread_mutex
+{
+ unsigned int __lock;
+ unsigned int __owner_id;
+ unsigned int __cnt;
+ int __shpid;
+ int __type;
+ int __flags;
+ unsigned int __reserved1;
+ unsigned int __reserved2;
+};
+
+/* Static mutex initializers. */
+#define __PTHREAD_MUTEX_INITIALIZER \
+ { 0, 0, 0, 0, __PTHREAD_MUTEX_TIMED, 0, 0, 0 }
+
+/* The +1 is to mantain binary compatibility with the old
+ * libpthread implementation. */
+#define __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER \
+ { 0, 0, 0, 0, __PTHREAD_MUTEX_ERRORCHECK + 1, 0, 0, 0 }
+
+#define __PTHREAD_RECURSIVE_MUTEX_INITIALIZER \
+ { 0, 0, 0, 0, __PTHREAD_MUTEX_RECURSIVE + 1, 0, 0, 0 }
+
+#endif /* bits/types/struct___pthread_mutex.h */
diff --git a/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c b/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c
new file mode 100644
index 0000000..711ae67
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c
@@ -0,0 +1,27 @@
+/* pthread_attr_setstackaddr. Hurd on Mach version.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr)
+{
+ attr->__stackaddr = stackaddr;
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c b/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c
new file mode 100644
index 0000000..6a96370
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c
@@ -0,0 +1,27 @@
+/* pthread_attr_setstacksize. Hurd on Mach version.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <pt-internal.h>
+
+int
+pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize)
+{
+ attr->__stacksize = stacksize;
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-docancel.c b/sysdeps/mach/hurd/htl/pt-docancel.c
new file mode 100644
index 0000000..a8bcb24
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-docancel.c
@@ -0,0 +1,65 @@
+/* Cancel a thread.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+static void
+call_exit (void)
+{
+ pthread_exit (0);
+}
+
+int
+__pthread_do_cancel (struct __pthread *p)
+{
+ mach_port_t ktid;
+ int me;
+
+ assert (p->cancel_pending == 1);
+ assert (p->cancel_state == PTHREAD_CANCEL_ENABLE);
+
+ __pthread_mutex_unlock (&p->cancel_lock);
+
+ ktid = __mach_thread_self ();
+ me = p->kernel_thread == ktid;
+ __mach_port_deallocate (__mach_task_self (), ktid);
+
+ if (me)
+ call_exit ();
+ else
+ {
+ error_t err;
+
+ err = __thread_suspend (p->kernel_thread);
+ assert_perror (err);
+
+ err = __thread_abort (p->kernel_thread);
+ assert_perror (err);
+
+ err = __thread_set_pcsptp (p->kernel_thread,
+ 1, (void *) call_exit, 0, 0, 0, 0);
+ assert_perror (err);
+
+ err = __thread_resume (p->kernel_thread);
+ assert_perror (err);
+ }
+
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
new file mode 100644
index 0000000..41792e3
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
@@ -0,0 +1,169 @@
+/* pthread_hurd_cond_timedwait_np. Hurd-specific wait on a condition.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <hurd/signal.h>
+
+#include <pt-internal.h>
+
+extern int __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec
+ *abstime);
+
+int
+__pthread_hurd_cond_timedwait_np (pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime)
+{
+ return __pthread_hurd_cond_timedwait_internal (cond, mutex, abstime);
+}
+
+strong_alias (__pthread_hurd_cond_timedwait_np, pthread_hurd_cond_timedwait_np);
+
+int
+__pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime)
+{
+ struct hurd_sigstate *ss = _hurd_self_sigstate ();
+ struct __pthread *self = _pthread_self ();
+ error_t err = 0;
+ int cancel, drain;
+ clockid_t clock_id = __pthread_default_condattr.__clock;
+
+ /* This function will be called by hurd_thread_cancel while we are blocked
+ We wake up our thread if it's still blocking or about to block, so it will
+ progress and notice the cancellation flag. */
+ void cancel_me (void)
+ {
+ int unblock;
+
+ __pthread_spin_lock (&cond->__lock);
+ /* The thread only needs to be awaken if it's blocking or about to block.
+ If it was already unblocked, it's not queued any more. */
+ unblock = self->prevp != NULL;
+ if (unblock)
+ __pthread_dequeue (self);
+ __pthread_spin_unlock (&cond->__lock);
+
+ if (unblock)
+ __pthread_wakeup (self);
+ }
+
+ assert (ss->intr_port == MACH_PORT_NULL); /* Sanity check for signal bugs. */
+
+ if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+ return EINVAL;
+
+ /* Atomically enqueue our thread on the condition variable's queue of
+ waiters, and mark our sigstate to indicate that `cancel_me' must be
+ called to wake us up. We must hold the sigstate lock while acquiring
+ the condition variable's lock and tweaking it, so that
+ hurd_thread_cancel can never suspend us and then deadlock waiting for
+ the condition variable's lock. */
+
+ __spin_lock (&ss->lock);
+ __pthread_spin_lock (&cond->__lock);
+ cancel = ss->cancel;
+ if (cancel)
+ /* We were cancelled before doing anything. Don't block at all. */
+ ss->cancel = 0;
+ else
+ {
+ /* Put us on the queue so that pthread_cond_broadcast will know to wake
+ us up. */
+ __pthread_enqueue (&cond->__queue, self);
+ if (cond->__attr)
+ clock_id = cond->__attr->__clock;
+ /* Tell hurd_thread_cancel how to unblock us. */
+ ss->cancel_hook = &cancel_me;
+ }
+ __pthread_spin_unlock (&cond->__lock);
+ __spin_unlock (&ss->lock);
+
+ if (cancel)
+ {
+ /* Cancelled on entry. Just leave the mutex locked. */
+ mutex = NULL;
+
+ __spin_lock (&ss->lock);
+ }
+ else
+ {
+ /* Release MUTEX before blocking. */
+ __pthread_mutex_unlock (mutex);
+
+ /* Block the thread. */
+ if (abstime != NULL)
+ err = __pthread_timedblock (self, abstime, clock_id);
+ else
+ {
+ err = 0;
+ __pthread_block (self);
+ }
+
+ /* As it was done when enqueueing, prevent hurd_thread_cancel from
+ suspending us while the condition lock is held. */
+ __spin_lock (&ss->lock);
+ __pthread_spin_lock (&cond->__lock);
+ if (self->prevp == NULL)
+ /* Another thread removed us from the list of waiters, which means
+ a wakeup message has been sent. It was either consumed while
+ we were blocking, or queued after we timed out and before we
+ acquired the condition lock, in which case the message queue
+ must be drained. */
+ drain = err ? 1 : 0;
+ else
+ {
+ /* We're still in the list of waiters. Noone attempted to wake us
+ up, i.e. we timed out. */
+ __pthread_dequeue (self);
+ drain = 0;
+ }
+ __pthread_spin_unlock (&cond->__lock);
+
+ if (drain)
+ __pthread_block (self);
+ }
+
+ /* Clear the hook, now that we are done blocking. */
+ ss->cancel_hook = NULL;
+ /* Check the cancellation flag; we might have unblocked due to
+ cancellation rather than a normal pthread_cond_signal or
+ pthread_cond_broadcast (or we might have just happened to get cancelled
+ right after waking up). */
+ cancel |= ss->cancel;
+ ss->cancel = 0;
+ __spin_unlock (&ss->lock);
+
+ if (mutex != NULL)
+ /* Reacquire the mutex and return. */
+ __pthread_mutex_lock (mutex);
+
+ if (cancel)
+ return EINTR;
+ else if (err)
+ {
+ assert (err == ETIMEDOUT);
+ return err;
+ }
+
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c
new file mode 100644
index 0000000..2f2b6c2
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c
@@ -0,0 +1,40 @@
+/* pthread_hurd_cond_wait. Hurd-specific wait on a condition.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <hurd/signal.h>
+
+#include <pt-internal.h>
+
+/* Implemented in pt-hurd-cond-timedwait.c. */
+extern int __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec
+ *abstime);
+
+int
+__pthread_hurd_cond_wait_np (pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ error_t err;
+
+ err = __pthread_hurd_cond_timedwait_internal (cond, mutex, NULL);
+ return err == EINTR;
+}
+
+strong_alias (__pthread_hurd_cond_wait_np, pthread_hurd_cond_wait_np);
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-consistent.c b/sysdeps/mach/hurd/htl/pt-mutex-consistent.c
new file mode 100644
index 0000000..9fd6342
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-consistent.c
@@ -0,0 +1,48 @@
+/* pthread_mutex_consistent. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_consistent (pthread_mutex_t *mtxp)
+{
+ int ret = EINVAL;
+ unsigned int val = mtxp->__lock;
+
+ if ((mtxp->__flags & PTHREAD_MUTEX_ROBUST) != 0 &&
+ (val & LLL_DEAD_OWNER) != 0 &&
+ atomic_compare_and_exchange_bool_acq (&mtxp->__lock,
+ __getpid () | LLL_WAITERS,
+ val) == 0)
+ {
+ /* The mutex is now ours, and it's consistent. */
+ mtxp->__owner_id = _pthread_self ()->thread;
+ mtxp->__cnt = 1;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+weak_alias (pthread_mutex_consistent, pthread_mutex_consistent_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-destroy.c b/sysdeps/mach/hurd/htl/pt-mutex-destroy.c
new file mode 100644
index 0000000..89b4916
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-destroy.c
@@ -0,0 +1,38 @@
+/* pthread_mutex_destroy. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+_pthread_mutex_destroy (pthread_mutex_t *mtxp)
+{
+ atomic_read_barrier ();
+ if (*(volatile unsigned int *) &mtxp->__lock != 0)
+ return EBUSY;
+
+ mtxp->__type = -1;
+ return 0;
+}
+
+strong_alias (_pthread_mutex_destroy, pthread_mutex_destroy)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c
new file mode 100644
index 0000000..fa6b82b
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c
@@ -0,0 +1,35 @@
+/* pthread_mutex_getprioceiling. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_getprioceiling (const pthread_mutex_t *mtxp, int *clp)
+{
+ (void) mtxp;
+ (void) clp;
+ return ENOSYS;
+}
+
+stub_warning (pthread_mutex_getprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-init.c b/sysdeps/mach/hurd/htl/pt-mutex-init.c
new file mode 100644
index 0000000..8218eb1
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-init.c
@@ -0,0 +1,56 @@
+/* pthread_mutex_init. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+static const pthread_mutexattr_t dfl_attr = {
+ .__prioceiling = 0,
+ .__protocol = PTHREAD_PRIO_NONE,
+ .__pshared = PTHREAD_PROCESS_PRIVATE,
+ .__mutex_type = __PTHREAD_MUTEX_TIMED
+};
+
+int
+_pthread_mutex_init (pthread_mutex_t *mtxp, const pthread_mutexattr_t *attrp)
+{
+ if (attrp == NULL)
+ attrp = &dfl_attr;
+
+ mtxp->__flags = (attrp->__pshared == PTHREAD_PROCESS_SHARED ?
+ GSYNC_SHARED : 0) | ((attrp->
+ __prioceiling & PTHREAD_MUTEX_ROBUST) ?
+ PTHREAD_MUTEX_ROBUST : 0);
+
+ mtxp->__type = attrp->__mutex_type +
+ (attrp->__mutex_type != __PTHREAD_MUTEX_TIMED);
+
+ mtxp->__owner_id = 0;
+ mtxp->__shpid = 0;
+ mtxp->__cnt = 0;
+ mtxp->__lock = 0;
+
+ return 0;
+}
+
+strong_alias (_pthread_mutex_init, pthread_mutex_init)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-lock.c b/sysdeps/mach/hurd/htl/pt-mutex-lock.c
new file mode 100644
index 0000000..e4a86f0
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-lock.c
@@ -0,0 +1,81 @@
+/* pthread_mutex_lock. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_lock (pthread_mutex_t *mtxp)
+{
+ struct __pthread *self;
+ int flags = mtxp->__flags & GSYNC_SHARED;
+ int ret = 0;
+
+ switch (MTX_TYPE (mtxp))
+ {
+ case PT_MTX_NORMAL:
+ lll_lock (&mtxp->__lock, flags);
+ break;
+
+ case PT_MTX_RECURSIVE:
+ self = _pthread_self ();
+ if (mtx_owned_p (mtxp, self, flags))
+ {
+ if (__glibc_unlikely (mtxp->__cnt + 1 == 0))
+ return EAGAIN;
+
+ ++mtxp->__cnt;
+ return ret;
+ }
+
+ lll_lock (&mtxp->__lock, flags);
+ mtx_set_owner (mtxp, self, flags);
+ mtxp->__cnt = 1;
+ break;
+
+ case PT_MTX_ERRORCHECK:
+ self = _pthread_self ();
+ if (mtx_owned_p (mtxp, self, flags))
+ return EDEADLK;
+
+ lll_lock (&mtxp->__lock, flags);
+ mtx_set_owner (mtxp, self, flags);
+ break;
+
+ case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+ self = _pthread_self ();
+ ROBUST_LOCK (self, mtxp, __lll_robust_lock, flags);
+ break;
+
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+strong_alias (__pthread_mutex_lock, _pthread_mutex_lock)
+strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c
new file mode 100644
index 0000000..5f39ebb
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c
@@ -0,0 +1,36 @@
+/* pthread_mutex_setprioceiling. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_setprioceiling (pthread_mutex_t *mtxp, int cl, int *prp)
+{
+ (void) mtxp;
+ (void) cl;
+ (void) prp;
+ return ENOSYS;
+}
+
+stub_warning (pthread_mutex_setprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c b/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c
new file mode 100644
index 0000000..0457445
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c
@@ -0,0 +1,79 @@
+/* pthread_mutex_timedlock. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp)
+{
+ struct __pthread *self;
+ int ret, flags = mtxp->__flags & GSYNC_SHARED;
+
+ switch (MTX_TYPE (mtxp))
+ {
+ case PT_MTX_NORMAL:
+ ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags);
+ break;
+
+ case PT_MTX_RECURSIVE:
+ self = _pthread_self ();
+ if (mtx_owned_p (mtxp, self, flags))
+ {
+ if (__glibc_unlikely (mtxp->__cnt + 1 == 0))
+ return EAGAIN;
+
+ ++mtxp->__cnt;
+ ret = 0;
+ }
+ else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0)
+ {
+ mtx_set_owner (mtxp, self, flags);
+ mtxp->__cnt = 1;
+ }
+
+ break;
+
+ case PT_MTX_ERRORCHECK:
+ self = _pthread_self ();
+ if (mtx_owned_p (mtxp, self, flags))
+ ret = EDEADLK;
+ else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0)
+ mtx_set_owner (mtxp, self, flags);
+
+ break;
+
+ case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+ self = _pthread_self ();
+ ROBUST_LOCK (self, mtxp, lll_robust_abstimed_lock, tsp, flags);
+ break;
+
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return ret;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c b/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c
new file mode 100644
index 0000000..e89c8dc
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c
@@ -0,0 +1,77 @@
+/* pthread_mutex_transfer_np. Transfer mutex ownership to another thread.
+ Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_transfer_np (pthread_mutex_t *mtxp, pthread_t th)
+{
+ struct __pthread *self = _pthread_self ();
+ struct __pthread *pt = __pthread_getid (th);
+
+ if (pt == NULL)
+ return ESRCH;
+ else if (pt == self)
+ return 0;
+
+ int ret = 0;
+ int flags = mtxp->__flags & GSYNC_SHARED;
+
+ switch (MTX_TYPE (mtxp))
+ {
+ case PT_MTX_NORMAL:
+ break;
+
+ case PT_MTX_RECURSIVE:
+ case PT_MTX_ERRORCHECK:
+ if (!mtx_owned_p (mtxp, self, flags))
+ ret = EPERM;
+ else
+ mtx_set_owner (mtxp, pt, flags);
+
+ break;
+
+ case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+ /* Note that this can be used to transfer an inconsistent
+ * mutex as well. The new owner will still have the same
+ * flags as the original. */
+ if (mtxp->__owner_id != self->thread ||
+ (int) (mtxp->__lock & LLL_OWNER_MASK) != __getpid ())
+ ret = EPERM;
+ else
+ mtxp->__owner_id = pt->thread;
+
+ break;
+
+ default:
+ ret = EINVAL;
+ }
+
+ return ret;
+}
+
+weak_alias (__pthread_mutex_transfer_np, pthread_mutex_transfer_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-trylock.c b/sysdeps/mach/hurd/htl/pt-mutex-trylock.c
new file mode 100644
index 0000000..36d4f59
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-trylock.c
@@ -0,0 +1,85 @@
+/* pthread_mutex_trylock. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_trylock (pthread_mutex_t *mtxp)
+{
+ struct __pthread *self;
+ int ret;
+
+ switch (MTX_TYPE (mtxp))
+ {
+ case PT_MTX_NORMAL:
+ ret = lll_trylock (&mtxp->__lock);
+ if (ret)
+ ret = EBUSY;
+ break;
+
+ case PT_MTX_RECURSIVE:
+ self = _pthread_self ();
+ if (mtx_owned_p (mtxp, self, mtxp->__flags))
+ {
+ if (__glibc_unlikely (mtxp->__cnt + 1 == 0))
+ return EAGAIN;
+
+ ++mtxp->__cnt;
+ ret = 0;
+ }
+ else if ((ret = lll_trylock (&mtxp->__lock)) == 0)
+ {
+ mtx_set_owner (mtxp, self, mtxp->__flags);
+ mtxp->__cnt = 1;
+ }
+ else
+ ret = EBUSY;
+
+ break;
+
+ case PT_MTX_ERRORCHECK:
+ self = _pthread_self ();
+ if ((ret = lll_trylock (&mtxp->__lock)) == 0)
+ mtx_set_owner (mtxp, self, mtxp->__flags);
+ else
+ ret = EBUSY;
+ break;
+
+ case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+ self = _pthread_self ();
+ ROBUST_LOCK (self, mtxp, __lll_robust_trylock);
+ break;
+
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+strong_alias (__pthread_mutex_trylock, _pthread_mutex_trylock)
+strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex-unlock.c b/sysdeps/mach/hurd/htl/pt-mutex-unlock.c
new file mode 100644
index 0000000..30c62fc
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex-unlock.c
@@ -0,0 +1,92 @@
+/* pthread_mutex_unlock. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutex_unlock (pthread_mutex_t *mtxp)
+{
+ struct __pthread *self;
+ int ret = 0, flags = mtxp->__flags & GSYNC_SHARED;
+
+ switch (MTX_TYPE (mtxp))
+ {
+ case PT_MTX_NORMAL:
+ lll_unlock (&mtxp->__lock, flags);
+ break;
+
+ case PT_MTX_RECURSIVE:
+ self = _pthread_self ();
+ if (!mtx_owned_p (mtxp, self, flags))
+ ret = EPERM;
+ else if (--mtxp->__cnt == 0)
+ {
+ mtxp->__owner_id = mtxp->__shpid = 0;
+ lll_unlock (&mtxp->__lock, flags);
+ }
+
+ break;
+
+ case PT_MTX_ERRORCHECK:
+ self = _pthread_self ();
+ if (!mtx_owned_p (mtxp, self, flags))
+ ret = EPERM;
+ else
+ {
+ mtxp->__owner_id = mtxp->__shpid = 0;
+ lll_unlock (&mtxp->__lock, flags);
+ }
+
+ break;
+
+ case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
+ case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
+ self = _pthread_self ();
+ if (mtxp->__owner_id == NOTRECOVERABLE_ID)
+ ; /* Nothing to do. */
+ else if (mtxp->__owner_id != self->thread ||
+ (int) (mtxp->__lock & LLL_OWNER_MASK) != __getpid ())
+ ret = EPERM;
+ else if (--mtxp->__cnt == 0)
+ {
+ /* Release the lock. If it's in an inconsistent
+ * state, mark it as irrecoverable. */
+ mtxp->__owner_id = (mtxp->__lock & LLL_DEAD_OWNER) ?
+ NOTRECOVERABLE_ID : 0;
+ __lll_robust_unlock (&mtxp->__lock, flags);
+ }
+
+ break;
+
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+strong_alias (__pthread_mutex_unlock, _pthread_mutex_unlock)
+strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
diff --git a/sysdeps/mach/hurd/htl/pt-mutex.h b/sysdeps/mach/hurd/htl/pt-mutex.h
new file mode 100644
index 0000000..2daf63e
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutex.h
@@ -0,0 +1,90 @@
+/* Internal definitions for pthreads library.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _PT_MUTEX_H
+#define _PT_MUTEX_H 1
+
+/* Special ID used to signal an unrecoverable robust mutex. */
+#define NOTRECOVERABLE_ID (1U << 31)
+
+/* Common path for robust mutexes. Assumes the variable 'ret'
+ * is bound in the function this is called from. */
+#define ROBUST_LOCK(self, mtxp, cb, ...) \
+ if (mtxp->__owner_id == NOTRECOVERABLE_ID) \
+ return ENOTRECOVERABLE; \
+ else if (mtxp->__owner_id == self->thread && \
+ __getpid () == (int)(mtxp->__lock & LLL_OWNER_MASK)) \
+ { \
+ if (mtxp->__type == PT_MTX_RECURSIVE) \
+ { \
+ if (__glibc_unlikely (mtxp->__cnt + 1 == 0)) \
+ return EAGAIN; \
+ \
+ ++mtxp->__cnt; \
+ return 0; \
+ } \
+ else if (mtxp->__type == PT_MTX_ERRORCHECK) \
+ return EDEADLK; \
+ } \
+ \
+ ret = cb (&mtxp->__lock, ##__VA_ARGS__); \
+ if (ret == 0 || ret == EOWNERDEAD) \
+ { \
+ if (mtxp->__owner_id == ENOTRECOVERABLE) \
+ ret = ENOTRECOVERABLE; \
+ else \
+ { \
+ mtxp->__owner_id = self->thread; \
+ mtxp->__cnt = 1; \
+ if (ret == EOWNERDEAD) \
+ { \
+ mtxp->__lock = mtxp->__lock | LLL_DEAD_OWNER; \
+ atomic_write_barrier (); \
+ } \
+ } \
+ } \
+ (void)0
+
+/* Check that a thread owns the mutex. For non-robust, task-shared
+ * objects, we have to check the thread *and* process-id. */
+#define mtx_owned_p(mtx, pt, flags) \
+ ((mtx)->__owner_id == (pt)->thread && \
+ (((flags) & GSYNC_SHARED) == 0 || \
+ (mtx)->__shpid == __getpid ()))
+
+/* Record a thread as the owner of the mutex. */
+#define mtx_set_owner(mtx, pt, flags) \
+ (void) \
+ ({ \
+ (mtx)->__owner_id = (pt)->thread; \
+ if ((flags) & GSYNC_SHARED) \
+ (mtx)->__shpid = __getpid (); \
+ })
+
+/* Redefined mutex types. The +1 is for binary compatibility. */
+#define PT_MTX_NORMAL __PTHREAD_MUTEX_TIMED
+#define PT_MTX_RECURSIVE (__PTHREAD_MUTEX_RECURSIVE + 1)
+#define PT_MTX_ERRORCHECK (__PTHREAD_MUTEX_ERRORCHECK + 1)
+
+/* Mutex type, including robustness. */
+#define MTX_TYPE(mtxp) \
+ ((mtxp)->__type | ((mtxp)->__flags & PTHREAD_MUTEX_ROBUST))
+
+extern int __getpid (void) __attribute__ ((const));
+
+#endif /* pt-mutex.h */
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c b/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c
new file mode 100644
index 0000000..9c6cffc
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c
@@ -0,0 +1,34 @@
+/* pthread_mutexattr_destroy. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutexattr_destroy (pthread_mutexattr_t *attrp)
+{
+ (void) attrp;
+ return 0;
+}
+
+weak_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c
new file mode 100644
index 0000000..4532eca
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_getprioceiling. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *ap, int *clp)
+{
+ (void) ap;
+ (void) clp;
+ return ENOSYS;
+}
+
+stub_warning (pthread_mutexattr_getprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c
new file mode 100644
index 0000000..33cdc15
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c
@@ -0,0 +1,32 @@
+/* pthread_mutexattr_getprotocol. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attrp, int *ptp)
+{
+ *ptp = attrp->__protocol;
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c
new file mode 100644
index 0000000..d393b4b
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c
@@ -0,0 +1,32 @@
+/* pthread_mutexattr_getpshared. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getpshared (const pthread_mutexattr_t *attrp, int *outp)
+{
+ *outp = attrp->__pshared;
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c
new file mode 100644
index 0000000..0999db0
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_getrobust. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_getrobust (const pthread_mutexattr_t *attrp, int *outp)
+{
+ *outp = (attrp->__prioceiling & PTHREAD_MUTEX_ROBUST) ?
+ PTHREAD_MUTEX_ROBUST : PTHREAD_MUTEX_STALLED;
+ return 0;
+}
+
+weak_alias (pthread_mutexattr_getrobust, pthread_mutexattr_getrobust_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c b/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c
new file mode 100644
index 0000000..6881a5b
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c
@@ -0,0 +1,32 @@
+/* pthread_mutexattr_gettype. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_gettype (const pthread_mutexattr_t *attrp, int *outp)
+{
+ *outp = attrp->__mutex_type;
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-init.c b/sysdeps/mach/hurd/htl/pt-mutexattr-init.c
new file mode 100644
index 0000000..b135126
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-init.c
@@ -0,0 +1,40 @@
+/* pthread_mutexattr_init. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+static const pthread_mutexattr_t dfl_attr = {
+ .__prioceiling = 0,
+ .__protocol = PTHREAD_PRIO_NONE,
+ .__pshared = PTHREAD_PROCESS_PRIVATE,
+ .__mutex_type = __PTHREAD_MUTEX_TIMED
+};
+
+int
+__pthread_mutexattr_init (pthread_mutexattr_t *attrp)
+{
+ *attrp = dfl_attr;
+ return 0;
+}
+weak_alias (__pthread_mutexattr_init, pthread_mutexattr_init)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c
new file mode 100644
index 0000000..6011ffb
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_setprioceiling. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attrp, int cl)
+{
+ (void) attrp;
+ (void) cl;
+ return ENOSYS;
+}
+
+stub_warning (pthread_mutexattr_setprioceiling)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c
new file mode 100644
index 0000000..5173a48
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c
@@ -0,0 +1,34 @@
+/* pthread_mutexattr_setprotocol. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setprotocol (pthread_mutexattr_t *attrp, int proto)
+{
+ (void) attrp;
+ return proto == PTHREAD_PRIO_NONE ? 0 :
+ proto != PTHREAD_PRIO_INHERIT &&
+ proto != PTHREAD_PRIO_PROTECT ? EINVAL : ENOTSUP;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c
new file mode 100644
index 0000000..7e0e607
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c
@@ -0,0 +1,35 @@
+/* pthread_mutexattr_setpshared. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setpshared (pthread_mutexattr_t *attrp, int pshared)
+{
+ if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED)
+ return EINVAL;
+
+ attrp->__pshared = pshared;
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c
new file mode 100644
index 0000000..f38c7a7
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c
@@ -0,0 +1,37 @@
+/* pthread_mutexattr_setrobust. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+pthread_mutexattr_setrobust (pthread_mutexattr_t *attrp, int robust)
+{
+ if (robust != PTHREAD_MUTEX_ROBUST && robust != PTHREAD_MUTEX_STALLED)
+ return EINVAL;
+
+ attrp->__prioceiling |= robust;
+ return 0;
+}
+
+weak_alias (pthread_mutexattr_setrobust, pthread_mutexattr_setrobust_np)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c b/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c
new file mode 100644
index 0000000..c856fd7
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c
@@ -0,0 +1,36 @@
+/* pthread_mutexattr_settype. Hurd version.
+ Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either
+ version 2 of the license, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pt-internal.h>
+#include "pt-mutex.h"
+#include <hurdlock.h>
+
+int
+__pthread_mutexattr_settype (pthread_mutexattr_t *attrp, int type)
+{
+ if (type < 0 || type > __PTHREAD_MUTEX_RECURSIVE)
+ return EINVAL;
+
+ attrp->__mutex_type = type;
+ return 0;
+}
+weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype)
diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr.c b/sysdeps/mach/hurd/htl/pt-mutexattr.c
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-mutexattr.c
@@ -0,0 +1 @@
+/* empty */
diff --git a/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c b/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c
new file mode 100644
index 0000000..69de5ca
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c
@@ -0,0 +1,26 @@
+/* Destroy the signal state. Hurd on Mach version.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+
+#include <pt-internal.h>
+
+void
+__pthread_sigstate_destroy (struct __pthread *thread)
+{
+}
diff --git a/sysdeps/mach/hurd/htl/pt-sigstate-init.c b/sysdeps/mach/hurd/htl/pt-sigstate-init.c
new file mode 100644
index 0000000..a6b4f76
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sigstate-init.c
@@ -0,0 +1,44 @@
+/* Initialize the signal state. Hurd on Mach version.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <pt-internal.h>
+#include <hurd/signal.h>
+
+error_t
+__pthread_sigstate_init (struct __pthread *thread)
+{
+ static int do_init_global;
+
+ /* Mark the thread as a global signal receiver so as to conform with
+ the pthread semantics. However, we must be careful. The first
+ pthread created is the main thread, during libpthread initialization.
+ We must not mark it, otherwise the sigprocmask call in
+ __pthread_create would try to access _hurd_global_sigstate,
+ which is not initialized yet. When glibc runs _hurdsig_init later
+ on, the message thread is created, which must not be marked either. */
+ if (do_init_global)
+ {
+ struct hurd_sigstate *ss = _hurd_thread_sigstate (thread->kernel_thread);
+ (void) ss;
+ }
+ else if (__pthread_num_threads >= 2)
+ do_init_global = 1;
+
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-sigstate.c b/sysdeps/mach/hurd/htl/pt-sigstate.c
new file mode 100644
index 0000000..5f0a1b4
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sigstate.c
@@ -0,0 +1,70 @@
+/* Set a thread's signal state. Hurd on Mach version.
+ Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <signal.h>
+#include <hurd/signal.h>
+
+#include <pt-internal.h>
+
+error_t
+__pthread_sigstate (struct __pthread *thread, int how,
+ const sigset_t *set, sigset_t *oset, int clear_pending)
+{
+ error_t err = 0;
+ struct hurd_sigstate *ss;
+
+ ss = _hurd_thread_sigstate (thread->kernel_thread);
+ assert (ss);
+
+ __spin_lock (&ss->lock);
+
+ if (oset != NULL)
+ *oset = ss->blocked;
+
+ if (set != NULL)
+ {
+ switch (how)
+ {
+ case SIG_BLOCK:
+ ss->blocked |= *set;
+ break;
+
+ case SIG_SETMASK:
+ ss->blocked = *set;
+ break;
+
+ case SIG_UNBLOCK:
+ ss->blocked &= ~*set;
+ break;
+
+ default:
+ err = EINVAL;
+ break;
+ }
+ ss->blocked &= ~_SIG_CANT_MASK;
+ }
+
+ if (!err && clear_pending)
+ __sigemptyset (&ss->pending);
+
+ __spin_unlock (&ss->lock);
+
+ return err;
+}
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.c b/sysdeps/mach/hurd/htl/pt-sysdep.c
new file mode 100644
index 0000000..40ebc8e
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.c
@@ -0,0 +1,99 @@
+/* System dependent pthreads code. Hurd version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <mach.h>
+#include <mach/mig_support.h>
+
+#include <pt-internal.h>
+
+__thread struct __pthread *___pthread_self;
+
+/* Forward. */
+static void *init_routine (void);
+
+/* OK, the name of this variable isn't really appropriate, but I don't
+ want to change it yet. */
+void *(*_cthread_init_routine) (void) = &init_routine;
+
+/* This function is called from the Hurd-specific startup code. It
+ should return a new stack pointer for the main thread. The caller
+ will switch to this new stack before doing anything serious. */
+static void *
+_init_routine (void *stack)
+{
+ struct __pthread *thread;
+ int err;
+ pthread_attr_t attr, *attrp = 0;
+
+ if (__pthread_threads != NULL)
+ /* Already initialized */
+ return 0;
+
+ /* Initialize the library. */
+ ___pthread_init ();
+
+ if (stack != NULL)
+ {
+ /* We are getting initialized due to dlopening a library using libpthread
+ while the main program was not linked against libpthread. */
+ /* Avoid allocating another stack */
+ attrp = &attr;
+ pthread_attr_init (attrp);
+ pthread_attr_setstack (attrp, stack, __vm_page_size);
+ }
+
+ /* Create the pthread structure for the main thread (i.e. us). */
+ err = __pthread_create_internal (&thread, attrp, 0, 0);
+ assert_perror (err);
+
+ /* XXX The caller copies the command line arguments and the environment
+ to the new stack. Pretend it wasn't allocated so that it remains
+ valid if the main thread terminates. */
+ thread->stack = 0;
+
+ ___pthread_self = thread;
+
+ /* Decrease the number of threads, to take into account that the
+ signal thread (which will be created by the glibc startup code
+ when we return from here) shouldn't be seen as a user thread. */
+ __pthread_total--;
+
+ /* Make MiG code thread aware. */
+ __mig_init (thread->stackaddr);
+
+ return thread->mcontext.sp;
+}
+
+static void *
+init_routine (void)
+{
+ return _init_routine (0);
+}
+
+#ifdef SHARED
+__attribute__ ((constructor))
+static void
+dynamic_init_routine (void)
+{
+ _init_routine (__libc_stack_end);
+}
+#endif
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.h b/sysdeps/mach/hurd/htl/pt-sysdep.h
new file mode 100644
index 0000000..0977806
--- /dev/null
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.h
@@ -0,0 +1,65 @@
+/* Internal definitions for pthreads library.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _PT_SYSDEP_H
+#define _PT_SYSDEP_H 1
+
+#include <mach.h>
+
+/* XXX */
+#define _POSIX_THREAD_THREADS_MAX 64
+
+/* The default stack size. */
+#define PTHREAD_STACK_DEFAULT (8 * 1024 * 1024)
+
+#define PTHREAD_SYSDEP_MEMBERS \
+ thread_t kernel_thread; \
+ mach_msg_header_t wakeupmsg;
+
+extern __thread struct __pthread *___pthread_self;
+#define _pthread_self() \
+ ({ \
+ struct __pthread *thread; \
+ \
+ assert (__pthread_threads); \
+ thread = ___pthread_self; \
+ \
+ assert (thread); \
+ assert (({ mach_port_t ktid = __mach_thread_self (); \
+ int ok = thread->kernel_thread == ktid; \
+ __mach_port_deallocate (__mach_task_self (), ktid);\
+ ok; })); \
+ thread; \
+ })
+
+extern inline void
+__attribute__ ((__always_inline__))
+__pthread_stack_dealloc (void *stackaddr, size_t stacksize)
+{
+ __vm_deallocate (__mach_task_self (), (vm_offset_t) stackaddr, stacksize);
+}
+
+/* Change thread THREAD's program counter to PC if SET_PC is true,
+ its stack pointer to SP if SET_IP is true, and its thread pointer
+ to TP if SET_TP is true. */
+extern int __thread_set_pcsptp (thread_t thread,
+ int set_pc, void *pc,
+ int set_sp, void *sp, int set_tp, void *tp);
+
+
+#endif /* pt-sysdep.h */
diff --git a/sysdeps/mach/hurd/i386/Implies b/sysdeps/mach/hurd/i386/Implies
index 94db5e9..eedc9ea 100644
--- a/sysdeps/mach/hurd/i386/Implies
+++ b/sysdeps/mach/hurd/i386/Implies
@@ -1 +1,2 @@
mach/hurd/x86
+mach/hurd/i386/htl
diff --git a/sysdeps/mach/hurd/i386/htl/Implies b/sysdeps/mach/hurd/i386/htl/Implies
new file mode 100644
index 0000000..7a0f99d
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/htl/Implies
@@ -0,0 +1,2 @@
+mach/hurd/htl
+i386/htl
diff --git a/sysdeps/mach/hurd/i386/htl/pt-machdep.c b/sysdeps/mach/hurd/i386/htl/pt-machdep.c
new file mode 100644
index 0000000..9b2083d
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/htl/pt-machdep.c
@@ -0,0 +1,82 @@
+/* Machine dependent pthreads code. Hurd/i386 version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+
+#include <mach.h>
+#include <mach/i386/thread_status.h>
+#include <mach/i386/mach_i386.h>
+#include <mach/mig_errors.h>
+#include <mach/thread_status.h>
+
+#define HURD_TLS_DESC_DECL(desc, tcb) \
+ struct descriptor desc = \
+ { /* low word: */ \
+ 0xffff /* limit 0..15 */ \
+ | (((unsigned int) (tcb)) << 16) /* base 0..15 */ \
+ , /* high word: */ \
+ ((((unsigned int) (tcb)) >> 16) & 0xff) /* base 16..23 */ \
+ | ((0x12 | 0x60 | 0x80) << 8) /* access = ACC_DATA_W|ACC_PL_U|ACC_P */ \
+ | (0xf << 16) /* limit 16..19 */ \
+ | ((4 | 8) << 20) /* granularity = SZ_32|SZ_G */ \
+ | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */ \
+ }
+
+int
+__thread_set_pcsptp (thread_t thread,
+ int set_ip, void *ip,
+ int set_sp, void *sp,
+ int set_tp, void *tp)
+{
+ error_t err;
+ struct i386_thread_state state;
+ mach_msg_type_number_t state_count;
+
+ state_count = i386_THREAD_STATE_COUNT;
+
+ err = __thread_get_state (thread, i386_REGS_SEGS_STATE,
+ (thread_state_t) &state, &state_count);
+ if (err)
+ return err;
+
+ if (set_sp)
+ state.uesp = (unsigned int) sp;
+ if (set_ip)
+ state.eip = (unsigned int) ip;
+ if (set_tp)
+ {
+ HURD_TLS_DESC_DECL (desc, tp);
+ int sel;
+
+ asm ("mov %%gs, %w0": "=q" (sel):"0" (0));
+ if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
+ err = __i386_set_ldt (thread, sel, &desc, 1);
+ else
+ err = __i386_set_gdt (thread, &sel, desc);
+ if (err)
+ return err;
+ state.gs = sel;
+ }
+
+ err = __thread_set_state (thread, i386_REGS_SEGS_STATE,
+ (thread_state_t) &state, i386_THREAD_STATE_COUNT);
+ if (err)
+ return err;
+
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/i386/htl/pt-setup.c b/sysdeps/mach/hurd/i386/htl/pt-setup.c
new file mode 100644
index 0000000..a59f71b
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/htl/pt-setup.c
@@ -0,0 +1,110 @@
+/* Setup thread stack. Hurd/i386 version.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <stdint.h>
+#include <assert.h>
+#include <mach.h>
+
+#include <pt-internal.h>
+
+/* The stack layout used on the i386 is:
+
+ -----------------
+ | ARG |
+ -----------------
+ | START_ROUTINE |
+ -----------------
+ | 0 |
+ -----------------
+ */
+
+/* Set up the stack for THREAD, such that it appears as if
+ START_ROUTINE and ARG were passed to the new thread's entry-point.
+ Return the stack pointer for the new thread. */
+static void *
+stack_setup (struct __pthread *thread,
+ void *(*start_routine) (void *), void *arg)
+{
+ error_t err;
+ uintptr_t *bottom, *top;
+
+ /* Calculate the top of the new stack. */
+ bottom = thread->stackaddr;
+ top = (uintptr_t *) ((uintptr_t) bottom + thread->stacksize
+ + ((thread->guardsize + __vm_page_size - 1)
+ / __vm_page_size) * __vm_page_size);
+
+ if (start_routine != NULL)
+ {
+ /* And then the call frame. */
+ top -= 3;
+ top = (uintptr_t *) ((uintptr_t) top & ~0xf);
+ top[2] = (uintptr_t) arg; /* Argument to START_ROUTINE. */
+ top[1] = (uintptr_t) start_routine;
+ top[0] = (uintptr_t) thread;
+ *--top = 0; /* Fake return address. */
+ }
+
+ if (thread->guardsize)
+ {
+ err = __vm_protect (__mach_task_self (), (vm_address_t) bottom,
+ thread->guardsize, 0, 0);
+ assert_perror (err);
+ }
+
+ return top;
+}
+
+int
+__pthread_setup (struct __pthread *thread,
+ void (*entry_point) (struct __pthread *, void *(*)(void *),
+ void *), void *(*start_routine) (void *),
+ void *arg)
+{
+ tcbhead_t *tcb;
+ error_t err;
+ mach_port_t ktid;
+
+ thread->mcontext.pc = entry_point;
+ thread->mcontext.sp = stack_setup (thread, start_routine, arg);
+
+ ktid = __mach_thread_self ();
+ if (thread->kernel_thread == ktid)
+ /* Fix up the TCB for the main thread. The C library has already
+ installed a TCB, which we want to keep using. This TCB must not
+ be freed so don't register it in the thread structure. On the
+ other hand, it's not yet possible to reliably release a TCB.
+ Leave the unused one registered so that it doesn't leak. The
+ only thing left to do is to correctly set the `self' member in
+ the already existing TCB. */
+ tcb = THREAD_SELF;
+ else
+ {
+ err = __thread_set_pcsptp (thread->kernel_thread,
+ 1, thread->mcontext.pc,
+ 1, thread->mcontext.sp,
+ 1, thread->tcb);
+ assert_perror (err);
+ tcb = thread->tcb;
+ }
+ __mach_port_deallocate (__mach_task_self (), ktid);
+
+ tcb->self = thread->kernel_thread;
+
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist
new file mode 100644
index 0000000..e11569f
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/libpthread.abilist
@@ -0,0 +1,151 @@
+GLIBC_2.12 GLIBC_2.12 A
+GLIBC_2.12 __mutex_lock_solid F
+GLIBC_2.12 __mutex_unlock_solid F
+GLIBC_2.12 __pthread_get_cleanup_stack F
+GLIBC_2.12 __pthread_key_create F
+GLIBC_2.12 __pthread_kill F
+GLIBC_2.12 __pthread_mutex_transfer_np F
+GLIBC_2.12 __pthread_spin_destroy F
+GLIBC_2.12 __pthread_spin_init F
+GLIBC_2.12 __pthread_spin_lock F
+GLIBC_2.12 __pthread_spin_trylock F
+GLIBC_2.12 __pthread_spin_unlock F
+GLIBC_2.12 _cthread_init_routine D 0x4
+GLIBC_2.12 _cthreads_flockfile F
+GLIBC_2.12 _cthreads_ftrylockfile F
+GLIBC_2.12 _cthreads_funlockfile F
+GLIBC_2.12 _pthread_mutex_destroy F
+GLIBC_2.12 _pthread_mutex_init F
+GLIBC_2.12 _pthread_mutex_lock F
+GLIBC_2.12 _pthread_mutex_trylock F
+GLIBC_2.12 _pthread_mutex_unlock F
+GLIBC_2.12 _pthread_rwlock_destroy F
+GLIBC_2.12 _pthread_rwlock_init F
+GLIBC_2.12 _pthread_spin_lock F
+GLIBC_2.12 cthread_detach F
+GLIBC_2.12 cthread_fork F
+GLIBC_2.12 cthread_getspecific F
+GLIBC_2.12 cthread_keycreate F
+GLIBC_2.12 cthread_setspecific F
+GLIBC_2.12 flockfile F
+GLIBC_2.12 ftrylockfile F
+GLIBC_2.12 funlockfile F
+GLIBC_2.12 pthread_atfork F
+GLIBC_2.12 pthread_attr_destroy F
+GLIBC_2.12 pthread_attr_getdetachstate F
+GLIBC_2.12 pthread_attr_getguardsize F
+GLIBC_2.12 pthread_attr_getinheritsched F
+GLIBC_2.12 pthread_attr_getschedparam F
+GLIBC_2.12 pthread_attr_getschedpolicy F
+GLIBC_2.12 pthread_attr_getscope F
+GLIBC_2.12 pthread_attr_getstack F
+GLIBC_2.12 pthread_attr_getstackaddr F
+GLIBC_2.12 pthread_attr_getstacksize F
+GLIBC_2.12 pthread_attr_init F
+GLIBC_2.12 pthread_attr_setdetachstate F
+GLIBC_2.12 pthread_attr_setguardsize F
+GLIBC_2.12 pthread_attr_setinheritsched F
+GLIBC_2.12 pthread_attr_setschedparam F
+GLIBC_2.12 pthread_attr_setschedpolicy F
+GLIBC_2.12 pthread_attr_setscope F
+GLIBC_2.12 pthread_attr_setstack F
+GLIBC_2.12 pthread_attr_setstackaddr F
+GLIBC_2.12 pthread_attr_setstacksize F
+GLIBC_2.12 pthread_barrier_destroy F
+GLIBC_2.12 pthread_barrier_init F
+GLIBC_2.12 pthread_barrier_wait F
+GLIBC_2.12 pthread_barrierattr_destroy F
+GLIBC_2.12 pthread_barrierattr_getpshared F
+GLIBC_2.12 pthread_barrierattr_init F
+GLIBC_2.12 pthread_barrierattr_setpshared F
+GLIBC_2.12 pthread_cancel F
+GLIBC_2.12 pthread_cond_broadcast F
+GLIBC_2.12 pthread_cond_destroy F
+GLIBC_2.12 pthread_cond_init F
+GLIBC_2.12 pthread_cond_signal F
+GLIBC_2.12 pthread_cond_timedwait F
+GLIBC_2.12 pthread_cond_wait F
+GLIBC_2.12 pthread_condattr_destroy F
+GLIBC_2.12 pthread_condattr_getclock F
+GLIBC_2.12 pthread_condattr_getpshared F
+GLIBC_2.12 pthread_condattr_init F
+GLIBC_2.12 pthread_condattr_setclock F
+GLIBC_2.12 pthread_condattr_setpshared F
+GLIBC_2.12 pthread_create F
+GLIBC_2.12 pthread_detach F
+GLIBC_2.12 pthread_equal F
+GLIBC_2.12 pthread_exit F
+GLIBC_2.12 pthread_getattr_np F
+GLIBC_2.12 pthread_getconcurrency F
+GLIBC_2.12 pthread_getcpuclockid F
+GLIBC_2.12 pthread_getschedparam F
+GLIBC_2.12 pthread_getspecific F
+GLIBC_2.12 pthread_join F
+GLIBC_2.12 pthread_key_create F
+GLIBC_2.12 pthread_key_delete F
+GLIBC_2.12 pthread_kill F
+GLIBC_2.12 pthread_mutex_destroy F
+GLIBC_2.12 pthread_mutex_getprioceiling F
+GLIBC_2.12 pthread_mutex_init F
+GLIBC_2.12 pthread_mutex_lock F
+GLIBC_2.12 pthread_mutex_setprioceiling F
+GLIBC_2.12 pthread_mutex_timedlock F
+GLIBC_2.12 pthread_mutex_transfer_np F
+GLIBC_2.12 pthread_mutex_trylock F
+GLIBC_2.12 pthread_mutex_unlock F
+GLIBC_2.12 pthread_mutexattr_destroy F
+GLIBC_2.12 pthread_mutexattr_getprioceiling F
+GLIBC_2.12 pthread_mutexattr_getprotocol F
+GLIBC_2.12 pthread_mutexattr_getpshared F
+GLIBC_2.12 pthread_mutexattr_gettype F
+GLIBC_2.12 pthread_mutexattr_init F
+GLIBC_2.12 pthread_mutexattr_setprioceiling F
+GLIBC_2.12 pthread_mutexattr_setprotocol F
+GLIBC_2.12 pthread_mutexattr_setpshared F
+GLIBC_2.12 pthread_mutexattr_settype F
+GLIBC_2.12 pthread_once F
+GLIBC_2.12 pthread_rwlock_destroy F
+GLIBC_2.12 pthread_rwlock_init F
+GLIBC_2.12 pthread_rwlock_rdlock F
+GLIBC_2.12 pthread_rwlock_timedrdlock F
+GLIBC_2.12 pthread_rwlock_timedwrlock F
+GLIBC_2.12 pthread_rwlock_tryrdlock F
+GLIBC_2.12 pthread_rwlock_trywrlock F
+GLIBC_2.12 pthread_rwlock_unlock F
+GLIBC_2.12 pthread_rwlock_wrlock F
+GLIBC_2.12 pthread_rwlockattr_destroy F
+GLIBC_2.12 pthread_rwlockattr_getpshared F
+GLIBC_2.12 pthread_rwlockattr_init F
+GLIBC_2.12 pthread_rwlockattr_setpshared F
+GLIBC_2.12 pthread_self F
+GLIBC_2.12 pthread_setcancelstate F
+GLIBC_2.12 pthread_setcanceltype F
+GLIBC_2.12 pthread_setconcurrency F
+GLIBC_2.12 pthread_setschedparam F
+GLIBC_2.12 pthread_setschedprio F
+GLIBC_2.12 pthread_setspecific F
+GLIBC_2.12 pthread_sigmask F
+GLIBC_2.12 pthread_spin_destroy F
+GLIBC_2.12 pthread_spin_init F
+GLIBC_2.12 pthread_spin_lock F
+GLIBC_2.12 pthread_spin_trylock F
+GLIBC_2.12 pthread_spin_unlock F
+GLIBC_2.12 pthread_testcancel F
+GLIBC_2.12 pthread_yield F
+GLIBC_2.12 sem_close F
+GLIBC_2.12 sem_destroy F
+GLIBC_2.12 sem_getvalue F
+GLIBC_2.12 sem_init F
+GLIBC_2.12 sem_open F
+GLIBC_2.12 sem_post F
+GLIBC_2.12 sem_timedwait F
+GLIBC_2.12 sem_trywait F
+GLIBC_2.12 sem_unlink F
+GLIBC_2.12 sem_wait F
+GLIBC_2.2.6 GLIBC_2.2.6 A
+GLIBC_2.2.6 _IO_flockfile F
+GLIBC_2.2.6 _IO_ftrylockfile F
+GLIBC_2.2.6 _IO_funlockfile F
+GLIBC_2.21 GLIBC_2.21 A
+GLIBC_2.21 pthread_hurd_cond_timedwait_np F
+GLIBC_2.21 pthread_hurd_cond_wait_np F