aboutsummaryrefslogtreecommitdiff
path: root/REORG.TODO/sysdeps/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/sysdeps/nptl')
-rw-r--r--REORG.TODO/sysdeps/nptl/Implies1
-rw-r--r--REORG.TODO/sysdeps/nptl/Makeconfig28
-rw-r--r--REORG.TODO/sysdeps/nptl/Makefile33
-rw-r--r--REORG.TODO/sysdeps/nptl/Subdirs2
-rw-r--r--REORG.TODO/sysdeps/nptl/aio_misc.h74
-rw-r--r--REORG.TODO/sysdeps/nptl/allocrtsig.c50
-rw-r--r--REORG.TODO/sysdeps/nptl/bits/pthreadtypes.h121
-rw-r--r--REORG.TODO/sysdeps/nptl/bits/thread-shared-types.h156
-rw-r--r--REORG.TODO/sysdeps/nptl/fork.c255
-rw-r--r--REORG.TODO/sysdeps/nptl/fork.h59
-rw-r--r--REORG.TODO/sysdeps/nptl/futex-internal.h203
-rw-r--r--REORG.TODO/sysdeps/nptl/gai_misc.h123
-rw-r--r--REORG.TODO/sysdeps/nptl/internaltypes.h179
-rw-r--r--REORG.TODO/sysdeps/nptl/jmp-unwind.c32
-rw-r--r--REORG.TODO/sysdeps/nptl/libc-lock.h187
-rw-r--r--REORG.TODO/sysdeps/nptl/libc-lockP.h438
-rw-r--r--REORG.TODO/sysdeps/nptl/librt-cancellation.c24
-rw-r--r--REORG.TODO/sysdeps/nptl/lowlevellock-futex.h86
-rw-r--r--REORG.TODO/sysdeps/nptl/lowlevellock.h205
-rw-r--r--REORG.TODO/sysdeps/nptl/malloc-machine.h27
-rw-r--r--REORG.TODO/sysdeps/nptl/nptl-signals.h22
-rw-r--r--REORG.TODO/sysdeps/nptl/pthread-functions.h117
-rw-r--r--REORG.TODO/sysdeps/nptl/pthread.h1162
-rw-r--r--REORG.TODO/sysdeps/nptl/setxid.h62
-rw-r--r--REORG.TODO/sysdeps/nptl/shm-directory.h31
-rw-r--r--REORG.TODO/sysdeps/nptl/sigfillset.c20
-rw-r--r--REORG.TODO/sysdeps/nptl/stdio-lock.h111
-rw-r--r--REORG.TODO/sysdeps/nptl/sys/procfs.h39
-rw-r--r--REORG.TODO/sysdeps/nptl/tcb-offsets.h1
-rw-r--r--REORG.TODO/sysdeps/nptl/tst-mqueue8x.c1
-rw-r--r--REORG.TODO/sysdeps/nptl/unwind-forcedunwind.c148
31 files changed, 3997 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/nptl/Implies b/REORG.TODO/sysdeps/nptl/Implies
new file mode 100644
index 0000000000..f1b3e8939c
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/Implies
@@ -0,0 +1 @@
+pthread
diff --git a/REORG.TODO/sysdeps/nptl/Makeconfig b/REORG.TODO/sysdeps/nptl/Makeconfig
new file mode 100644
index 0000000000..d31b77680f
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/Makeconfig
@@ -0,0 +1,28 @@
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# Makeconfig fragment for NPTL add-on.
+# This gets included at the end of the main glibc Makeconfig.
+
+have-thread-library = yes
+
+shared-thread-library = $(common-objpfx)nptl/libpthread_nonshared.a \
+ $(common-objpfx)nptl/libpthread.so
+static-thread-library = $(common-objpfx)nptl/libpthread.a
+
+rpath-dirs += nptl
diff --git a/REORG.TODO/sysdeps/nptl/Makefile b/REORG.TODO/sysdeps/nptl/Makefile
new file mode 100644
index 0000000000..4f4f4ffe69
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/Makefile
@@ -0,0 +1,33 @@
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+ifeq ($(subdir),nptl)
+libpthread-sysdep_routines += errno-loc
+endif
+
+ifeq ($(subdir),rt)
+librt-sysdep_routines += timer_routines librt-cancellation
+CFLAGS-librt-cancellation.c += -fexceptions -fasynchronous-unwind-tables
+
+tests += tst-mqueue8x
+CFLAGS-tst-mqueue8x.c += -fexceptions
+endif
+
+ifeq ($(subdir),posix)
+CFLAGS-confstr.c += -DLIBPTHREAD_VERSION='"NPTL $(version)"'
+endif
diff --git a/REORG.TODO/sysdeps/nptl/Subdirs b/REORG.TODO/sysdeps/nptl/Subdirs
new file mode 100644
index 0000000000..36266c1e69
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/Subdirs
@@ -0,0 +1,2 @@
+nptl
+nptl_db
diff --git a/REORG.TODO/sysdeps/nptl/aio_misc.h b/REORG.TODO/sysdeps/nptl/aio_misc.h
new file mode 100644
index 0000000000..47b1a36479
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/aio_misc.h
@@ -0,0 +1,74 @@
+/* Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the 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/>. */
+
+/* We define a special synchronization primitive for AIO. POSIX
+ conditional variables would be ideal but the pthread_cond_*wait
+ operations do not return on EINTR. This is a requirement for
+ correct aio_suspend and lio_listio implementations. */
+
+#include <assert.h>
+#include <nptl/pthreadP.h>
+#include <futex-internal.h>
+
+#define DONT_NEED_AIO_MISC_COND 1
+
+#define AIO_MISC_NOTIFY(waitlist) \
+ do { \
+ if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \
+ futex_wake ((unsigned int *) waitlist->counterp, 1, FUTEX_PRIVATE); \
+ } while (0)
+
+#define AIO_MISC_WAIT(result, futex, timeout, cancel) \
+ do { \
+ volatile unsigned int *futexaddr = &futex; \
+ unsigned int oldval = futex; \
+ \
+ if (oldval != 0) \
+ { \
+ pthread_mutex_unlock (&__aio_requests_mutex); \
+ \
+ int oldtype; \
+ if (cancel) \
+ oldtype = LIBC_CANCEL_ASYNC (); \
+ \
+ int status; \
+ do \
+ { \
+ status = futex_reltimed_wait ((unsigned int *) futexaddr, oldval, \
+ timeout, FUTEX_PRIVATE); \
+ if (status != EAGAIN) \
+ break; \
+ \
+ oldval = *futexaddr; \
+ } \
+ while (oldval != 0); \
+ \
+ if (cancel) \
+ LIBC_CANCEL_RESET (oldtype); \
+ \
+ if (status == EINTR) \
+ result = EINTR; \
+ else if (status == ETIMEDOUT) \
+ result = EAGAIN; \
+ else \
+ assert (status == 0 || status == EAGAIN); \
+ \
+ pthread_mutex_lock (&__aio_requests_mutex); \
+ } \
+ } while (0)
+
+#include_next <aio_misc.h>
diff --git a/REORG.TODO/sysdeps/nptl/allocrtsig.c b/REORG.TODO/sysdeps/nptl/allocrtsig.c
new file mode 100644
index 0000000000..fed4e7e527
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/allocrtsig.c
@@ -0,0 +1,50 @@
+/* Handle real-time signal allocation. NPTL version.
+ Copyright (C) 2015-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <signal.h>
+#include <nptl/pthreadP.h>
+
+/* Up to three special signals might be used privately by libpthread.
+ Figure out how many unique ones are actually used. */
+
+#ifdef SIGCANCEL
+# define SIGCANCEL_CONSUMES 1
+#else
+# define SIGCANCEL_CONSUMES 0
+#endif
+
+#if defined SIGTIMER && (!defined SIGCANCEL || SIGTIMER != SIGCANCEL)
+# define SIGTIMER_CONSUMES 1
+#else
+# define SIGTIMER_CONSUMES 0
+#endif
+
+#if (defined SIGSETXID \
+ && (!defined SIGCANCEL || SIGSETXID != SIGCANCEL) \
+ && (!defined SIGTIMER || SIGSETXID != SIGTIMER))
+# define SIGSETXID_CONSUMES 1
+#else
+# define SIGSETXID_CONSUMES 0
+#endif
+
+/* This tells the generic code (included below) how many signal
+ numbers need to be reserved for libpthread's private uses. */
+#define RESERVED_SIGRT \
+ (SIGCANCEL_CONSUMES + SIGTIMER_CONSUMES + SIGSETXID_CONSUMES)
+
+#include <signal/allocrtsig.c>
diff --git a/REORG.TODO/sysdeps/nptl/bits/pthreadtypes.h b/REORG.TODO/sysdeps/nptl/bits/pthreadtypes.h
new file mode 100644
index 0000000000..8839559f5a
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/bits/pthreadtypes.h
@@ -0,0 +1,121 @@
+/* Declaration of common pthread types for all architectures.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_PTHREADTYPES_COMMON_H
+# define _BITS_PTHREADTYPES_COMMON_H 1
+
+/* For internal mutex and condition variable definitions. */
+#include <bits/thread-shared-types.h>
+
+/* Thread identifiers. The structure of the attribute type is not
+ exposed on purpose. */
+typedef unsigned long int pthread_t;
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is not exposed on purpose. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for condition variable handling. The structure of
+ the attribute type is not exposed on purpose. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int __ONCE_ALIGNMENT pthread_once_t;
+
+
+union pthread_attr_t
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+};
+#ifndef __have_pthread_attr_t
+typedef union pthread_attr_t pthread_attr_t;
+# define __have_pthread_attr_t1
+#endif
+
+
+typedef union
+{
+ struct __pthread_mutex_s __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+
+typedef union
+{
+ struct __pthread_cond_s __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for reader-writer lock variable handling. The
+ structure of the attribute type is deliberately not exposed. */
+typedef union
+{
+ struct __pthread_rwlock_arch_t __data;
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+#endif
diff --git a/REORG.TODO/sysdeps/nptl/bits/thread-shared-types.h b/REORG.TODO/sysdeps/nptl/bits/thread-shared-types.h
new file mode 100644
index 0000000000..d95ac9ac13
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/bits/thread-shared-types.h
@@ -0,0 +1,156 @@
+/* Common threading primitives definitions for both POSIX and C11.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _THREAD_SHARED_TYPES_H
+#define _THREAD_SHARED_TYPES_H 1
+
+/* Arch-specific definitions. Each architecture must define the following
+ macros to define the expected sizes of pthread data types:
+
+ __SIZEOF_PTHREAD_ATTR_T - size of pthread_attr_t.
+ __SIZEOF_PTHREAD_MUTEX_T - size of pthread_mutex_t.
+ __SIZEOF_PTHREAD_MUTEXATTR_T - size of pthread_mutexattr_t.
+ __SIZEOF_PTHREAD_COND_T - size of pthread_cond_t.
+ __SIZEOF_PTHREAD_CONDATTR_T - size of pthread_condattr_t.
+ __SIZEOF_PTHREAD_RWLOCK_T - size of pthread_rwlock_t.
+ __SIZEOF_PTHREAD_RWLOCKATTR_T - size of pthread_rwlockattr_t.
+ __SIZEOF_PTHREAD_BARRIER_T - size of pthread_barrier_t.
+ __SIZEOF_PTHREAD_BARRIERATTR_T - size of pthread_barrierattr_t.
+
+ Also, the following macros must be define for internal pthread_mutex_t
+ struct definitions (struct __pthread_mutex_s):
+
+ __PTHREAD_COMPAT_PADDING_MID - any additional members after 'kind'
+ and before '__spin' (for 64 bits) or
+ '__nusers' (for 32 bits).
+ __PTHREAD_COMPAT_PADDING_END - any additional members at the end of
+ the internal structure.
+ __PTHREAD_MUTEX_LOCK_ELISION - 1 if the architecture supports lock
+ elision or 0 otherwise.
+
+ The additional macro defines any constraint for the lock alignment
+ inside the thread structures:
+
+ __LOCK_ALIGNMENT - for internal lock/futex usage.
+
+ Same idea but for the once locking primitive:
+
+ __ONCE_ALIGNMENT - for pthread_once_t/once_flag definition.
+
+ And finally the internal pthread_rwlock_t (struct __pthread_rwlock_arch_t)
+ must be defined.
+ */
+#include <bits/pthreadtypes-arch.h>
+
+/* Common definition of pthread_mutex_t. */
+
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+ struct __pthread_internal_list *__prev;
+ struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+/* Lock elision support. */
+#if __PTHREAD_MUTEX_LOCK_ELISION
+# if __WORDSIZE == 64
+# define __PTHREAD_SPINS_DATA \
+ short __spins; \
+ short __elision;
+# define __PTHREAD_SPINS 0, 0
+# else
+# define __PTHREAD_SPINS_DATA \
+ struct \
+ { \
+ short __espins; \
+ short __eelision; \
+ } __elision_data
+# define __PTHREAD_SPINS { 0, 0 }
+# define __spins __elision_data.__espins
+# define __elision __elision_data.__eelision
+# endif
+#else
+# define __PTHREAD_SPINS_DATA int __spins
+/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
+# define __PTHREAD_SPINS 0
+#endif
+
+struct __pthread_mutex_s
+{
+ int __lock __LOCK_ALIGNMENT;
+ unsigned int __count;
+ int __owner;
+#if __WORDSIZE == 64
+ unsigned int __nusers;
+#endif
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility with static initializers. */
+ int __kind;
+ __PTHREAD_COMPAT_PADDING_MID;
+#if __WORDSIZE == 64
+ __PTHREAD_SPINS_DATA;
+ __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+#else
+ unsigned int __nusers;
+ __extension__ union
+ {
+ __PTHREAD_SPINS_DATA;
+ __pthread_slist_t __list;
+ }
+#endif
+ __PTHREAD_COMPAT_PADDING_END;
+};
+
+
+/* Common definition of pthread_cond_t. */
+
+struct __pthread_cond_s
+{
+ __extension__ union
+ {
+ __extension__ unsigned long long int __wseq;
+ struct
+ {
+ unsigned int __low;
+ unsigned int __high;
+ } __wseq32;
+ };
+ __extension__ union
+ {
+ __extension__ unsigned long long int __g1_start;
+ struct
+ {
+ unsigned int __low;
+ unsigned int __high;
+ } __g1_start32;
+ };
+ unsigned int __g_refs[2] __LOCK_ALIGNMENT;
+ unsigned int __g_size[2];
+ unsigned int __g1_orig_size;
+ unsigned int __wrefs;
+ unsigned int __g_signals[2];
+};
+
+#endif /* _THREAD_SHARED_TYPES_H */
diff --git a/REORG.TODO/sysdeps/nptl/fork.c b/REORG.TODO/sysdeps/nptl/fork.c
new file mode 100644
index 0000000000..4bb87e2331
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/fork.c
@@ -0,0 +1,255 @@
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <libio/libioP.h>
+#include <tls.h>
+#include <hp-timing.h>
+#include <ldsodefs.h>
+#include <stdio-lock.h>
+#include <atomic.h>
+#include <nptl/pthreadP.h>
+#include <fork.h>
+#include <arch-fork.h>
+#include <futex-internal.h>
+#include <malloc/malloc-internal.h>
+
+static void
+fresetlockfiles (void)
+{
+ _IO_ITER i;
+
+ for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i))
+ if ((_IO_iter_file (i)->_flags & _IO_USER_LOCK) == 0)
+ _IO_lock_init (*((_IO_lock_t *) _IO_iter_file(i)->_lock));
+}
+
+
+pid_t
+__libc_fork (void)
+{
+ pid_t pid;
+ struct used_handler
+ {
+ struct fork_handler *handler;
+ struct used_handler *next;
+ } *allp = NULL;
+
+ /* Determine if we are running multiple threads. We skip some fork
+ handlers in the single-thread case, to make fork safer to use in
+ signal handlers. POSIX requires that fork is async-signal-safe,
+ but our current fork implementation is not. */
+ bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads);
+
+ /* Run all the registered preparation handlers. In reverse order.
+ While doing this we build up a list of all the entries. */
+ struct fork_handler *runp;
+ while ((runp = __fork_handlers) != NULL)
+ {
+ /* Make sure we read from the current RUNP pointer. */
+ atomic_full_barrier ();
+
+ unsigned int oldval = runp->refcntr;
+
+ if (oldval == 0)
+ /* This means some other thread removed the list just after
+ the pointer has been loaded. Try again. Either the list
+ is empty or we can retry it. */
+ continue;
+
+ /* Bump the reference counter. */
+ if (atomic_compare_and_exchange_bool_acq (&__fork_handlers->refcntr,
+ oldval + 1, oldval))
+ /* The value changed, try again. */
+ continue;
+
+ /* We bumped the reference counter for the first entry in the
+ list. That means that none of the following entries will
+ just go away. The unloading code works in the order of the
+ list.
+
+ While executing the registered handlers we are building a
+ list of all the entries so that we can go backward later on. */
+ while (1)
+ {
+ /* Execute the handler if there is one. */
+ if (runp->prepare_handler != NULL)
+ runp->prepare_handler ();
+
+ /* Create a new element for the list. */
+ struct used_handler *newp
+ = (struct used_handler *) alloca (sizeof (*newp));
+ newp->handler = runp;
+ newp->next = allp;
+ allp = newp;
+
+ /* Advance to the next handler. */
+ runp = runp->next;
+ if (runp == NULL)
+ break;
+
+ /* Bump the reference counter for the next entry. */
+ atomic_increment (&runp->refcntr);
+ }
+
+ /* We are done. */
+ break;
+ }
+
+ /* If we are not running multiple threads, we do not have to
+ preserve lock state. If fork runs from a signal handler, only
+ async-signal-safe functions can be used in the child. These data
+ structures are only used by unsafe functions, so their state does
+ not matter if fork was called from a signal handler. */
+ if (multiple_threads)
+ {
+ _IO_list_lock ();
+
+ /* Acquire malloc locks. This needs to come last because fork
+ handlers may use malloc, and the libio list lock has an
+ indirect malloc dependency as well (via the getdelim
+ function). */
+ call_function_static_weak (__malloc_fork_lock_parent);
+ }
+
+#ifdef ARCH_FORK
+ pid = ARCH_FORK ();
+#else
+# error "ARCH_FORK must be defined so that the CLONE_SETTID flag is used"
+ pid = INLINE_SYSCALL (fork, 0);
+#endif
+
+
+ if (pid == 0)
+ {
+ struct pthread *self = THREAD_SELF;
+
+ /* See __pthread_once. */
+ if (__fork_generation_pointer != NULL)
+ *__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
+
+#if HP_TIMING_AVAIL
+ /* The CPU clock of the thread and process have to be set to zero. */
+ hp_timing_t now;
+ HP_TIMING_NOW (now);
+ THREAD_SETMEM (self, cpuclock_offset, now);
+ GL(dl_cpuclock_offset) = now;
+#endif
+
+#ifdef __NR_set_robust_list
+ /* Initialize the robust mutex list setting in the kernel which has
+ been reset during the fork. We do not check for errors because if
+ it fails here, it must have failed at process startup as well and
+ nobody could have used robust mutexes.
+ Before we do that, we have to clear the list of robust mutexes
+ because we do not inherit ownership of mutexes from the parent.
+ We do not have to set self->robust_head.futex_offset since we do
+ inherit the correct value from the parent. We do not need to clear
+ the pending operation because it must have been zero when fork was
+ called. */
+# ifdef __PTHREAD_MUTEX_HAVE_PREV
+ self->robust_prev = &self->robust_head;
+# endif
+ self->robust_head.list = &self->robust_head;
+# ifdef SHARED
+ if (__builtin_expect (__libc_pthread_functions_init, 0))
+ PTHFCT_CALL (ptr_set_robust, (self));
+# else
+ extern __typeof (__nptl_set_robust) __nptl_set_robust
+ __attribute__((weak));
+ if (__builtin_expect (__nptl_set_robust != NULL, 0))
+ __nptl_set_robust (self);
+# endif
+#endif
+
+ /* Reset the lock state in the multi-threaded case. */
+ if (multiple_threads)
+ {
+ /* Release malloc locks. */
+ call_function_static_weak (__malloc_fork_unlock_child);
+
+ /* Reset the file list. These are recursive mutexes. */
+ fresetlockfiles ();
+
+ /* Reset locks in the I/O code. */
+ _IO_list_resetlock ();
+ }
+
+ /* Reset the lock the dynamic loader uses to protect its data. */
+ __rtld_lock_initialize (GL(dl_load_lock));
+
+ /* Run the handlers registered for the child. */
+ while (allp != NULL)
+ {
+ if (allp->handler->child_handler != NULL)
+ allp->handler->child_handler ();
+
+ /* Note that we do not have to wake any possible waiter.
+ This is the only thread in the new process. The count
+ may have been bumped up by other threads doing a fork.
+ We reset it to 1, to avoid waiting for non-existing
+ thread(s) to release the count. */
+ allp->handler->refcntr = 1;
+
+ /* XXX We could at this point look through the object pool
+ and mark all objects not on the __fork_handlers list as
+ unused. This is necessary in case the fork() happened
+ while another thread called dlclose() and that call had
+ to create a new list. */
+
+ allp = allp->next;
+ }
+
+ /* Initialize the fork lock. */
+ __fork_lock = LLL_LOCK_INITIALIZER;
+ }
+ else
+ {
+ /* Release acquired locks in the multi-threaded case. */
+ if (multiple_threads)
+ {
+ /* Release malloc locks, parent process variant. */
+ call_function_static_weak (__malloc_fork_unlock_parent);
+
+ /* We execute this even if the 'fork' call failed. */
+ _IO_list_unlock ();
+ }
+
+ /* Run the handlers registered for the parent. */
+ while (allp != NULL)
+ {
+ if (allp->handler->parent_handler != NULL)
+ allp->handler->parent_handler ();
+
+ if (atomic_decrement_and_test (&allp->handler->refcntr)
+ && allp->handler->need_signal)
+ futex_wake (&allp->handler->refcntr, 1, FUTEX_PRIVATE);
+
+ allp = allp->next;
+ }
+ }
+
+ return pid;
+}
+weak_alias (__libc_fork, __fork)
+libc_hidden_def (__fork)
+weak_alias (__libc_fork, fork)
diff --git a/REORG.TODO/sysdeps/nptl/fork.h b/REORG.TODO/sysdeps/nptl/fork.h
new file mode 100644
index 0000000000..e94b027140
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/fork.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <lowlevellock.h>
+
+/* The fork generation counter, defined in libpthread. */
+extern unsigned long int __fork_generation attribute_hidden;
+
+/* Pointer to the fork generation counter in the thread library. */
+extern unsigned long int *__fork_generation_pointer attribute_hidden;
+
+/* Lock to protect allocation and deallocation of fork handlers. */
+extern int __fork_lock attribute_hidden;
+
+/* Elements of the fork handler lists. */
+struct fork_handler
+{
+ struct fork_handler *next;
+ void (*prepare_handler) (void);
+ void (*parent_handler) (void);
+ void (*child_handler) (void);
+ void *dso_handle;
+ unsigned int refcntr;
+ int need_signal;
+};
+
+/* The single linked list of all currently registered for handlers. */
+extern struct fork_handler *__fork_handlers attribute_hidden;
+
+
+/* Function to call to unregister fork handlers. */
+extern void __unregister_atfork (void *dso_handle) attribute_hidden;
+#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
+
+
+/* C library side function to register new fork handlers. */
+extern int __register_atfork (void (*__prepare) (void),
+ void (*__parent) (void),
+ void (*__child) (void),
+ void *dso_handle);
+libc_hidden_proto (__register_atfork)
+
+/* Add a new element to the fork list. */
+extern void __linkin_atfork (struct fork_handler *newp) attribute_hidden;
diff --git a/REORG.TODO/sysdeps/nptl/futex-internal.h b/REORG.TODO/sysdeps/nptl/futex-internal.h
new file mode 100644
index 0000000000..be7a33f460
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/futex-internal.h
@@ -0,0 +1,203 @@
+/* futex operations for glibc-internal use. Stub version; do not include
+ this file directly.
+ Copyright (C) 2014-2017 Free Software Foundation, Inc.
+ This file is part of the 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 STUB_FUTEX_INTERNAL_H
+#define STUB_FUTEX_INTERNAL_H
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <libc-diag.h>
+
+/* This file defines futex operations used internally in glibc. A futex
+ consists of the so-called futex word in userspace, which is of type
+ unsigned int and represents an application-specific condition, and kernel
+ state associated with this particular futex word (e.g., wait queues). The
+ futex operations we provide are wrappers for the futex syscalls and add
+ glibc-specific error checking of the syscall return value. We abort on
+ error codes that are caused by bugs in glibc or in the calling application,
+ or when an error code is not known. We return error codes that can arise
+ in correct executions to the caller. Each operation calls out exactly the
+ return values that callers need to handle.
+
+ The private flag must be either FUTEX_PRIVATE or FUTEX_SHARED.
+ FUTEX_PRIVATE is always supported, and the implementation can internally
+ use FUTEX_SHARED when FUTEX_PRIVATE is requested. FUTEX_SHARED is not
+ necessarily supported (use futex_supports_pshared to detect this).
+
+ We expect callers to only use these operations if futexes and the
+ specific futex operations being used are supported (e.g., FUTEX_SHARED).
+
+ Given that waking other threads waiting on a futex involves concurrent
+ accesses to the futex word, you must use atomic operations to access the
+ futex word.
+
+ Both absolute and relative timeouts can be used. An absolute timeout
+ expires when the given specific point in time on the CLOCK_REALTIME clock
+ passes, or when it already has passed. A relative timeout expires when
+ the given duration of time on the CLOCK_MONOTONIC clock passes. Relative
+ timeouts may be imprecise (see futex_supports_exact_relative_timeouts).
+
+ Due to POSIX requirements on when synchronization data structures such
+ as mutexes or semaphores can be destroyed and due to the futex design
+ having separate fast/slow paths for wake-ups, we need to consider that
+ futex_wake calls might effectively target a data structure that has been
+ destroyed and reused for another object, or unmapped; thus, some
+ errors or spurious wake-ups can happen in correct executions that would
+ not be possible in a program using just a single futex whose lifetime
+ does not end before the program terminates. For background, see:
+ https://sourceware.org/ml/libc-alpha/2014-04/msg00075.html
+ https://lkml.org/lkml/2014/11/27/472 */
+
+/* Defined this way for interoperability with lowlevellock.
+ FUTEX_PRIVATE must be zero because the initializers for pthread_mutex_t,
+ pthread_rwlock_t, and pthread_cond_t initialize the respective field of
+ those structures to zero, and we want FUTEX_PRIVATE to be the default. */
+#define FUTEX_PRIVATE LLL_PRIVATE
+#define FUTEX_SHARED LLL_SHARED
+#if FUTEX_PRIVATE != 0
+# error FUTEX_PRIVATE must be equal to 0
+#endif
+
+/* Returns EINVAL if PSHARED is neither PTHREAD_PROCESS_PRIVATE nor
+ PTHREAD_PROCESS_SHARED; otherwise, returns 0 if PSHARED is supported, and
+ ENOTSUP if not. */
+static __always_inline int
+futex_supports_pshared (int pshared);
+
+/* Returns true if relative timeouts are robust to concurrent changes to the
+ system clock. If this returns false, relative timeouts can still be used
+ but might be effectively longer or shorter than requested. */
+static __always_inline bool
+futex_supports_exact_relative_timeouts (void);
+
+/* Atomically wrt other futex operations on the same futex, this blocks iff
+ the value *FUTEX_WORD matches the expected value. This is
+ semantically equivalent to:
+ l = <get lock associated with futex> (FUTEX_WORD);
+ wait_flag = <get wait_flag associated with futex> (FUTEX_WORD);
+ lock (l);
+ val = atomic_load_relaxed (FUTEX_WORD);
+ if (val != expected) { unlock (l); return EAGAIN; }
+ atomic_store_relaxed (wait_flag, true);
+ unlock (l);
+ // Now block; can time out in futex_time_wait (see below)
+ while (atomic_load_relaxed(wait_flag) && !<spurious wake-up>);
+
+ Note that no guarantee of a happens-before relation between a woken
+ futex_wait and a futex_wake is documented; however, this does not matter
+ in practice because we have to consider spurious wake-ups (see below),
+ and thus would not be able to reliably reason about which futex_wake woke
+ us.
+
+ Returns 0 if woken by a futex operation or spuriously. (Note that due to
+ the POSIX requirements mentioned above, we need to conservatively assume
+ that unrelated futex_wake operations could wake this futex; it is easiest
+ to just be prepared for spurious wake-ups.)
+ Returns EAGAIN if the futex word did not match the expected value.
+ Returns EINTR if waiting was interrupted by a signal.
+
+ Note that some previous code in glibc assumed the underlying futex
+ operation (e.g., syscall) to start with or include the equivalent of a
+ seq_cst fence; this allows one to avoid an explicit seq_cst fence before
+ a futex_wait call when synchronizing similar to Dekker synchronization.
+ However, we make no such guarantee here. */
+static __always_inline int
+futex_wait (unsigned int *futex_word, unsigned int expected, int private);
+
+/* Like futex_wait but does not provide any indication why we stopped waiting.
+ Thus, when this function returns, you have to always check FUTEX_WORD to
+ determine whether you need to continue waiting, and you cannot detect
+ whether the waiting was interrupted by a signal. Example use:
+ while (atomic_load_relaxed (&futex_word) == 23)
+ futex_wait_simple (&futex_word, 23, FUTEX_PRIVATE);
+ This is common enough to make providing this wrapper worthwhile. */
+static __always_inline void
+futex_wait_simple (unsigned int *futex_word, unsigned int expected,
+ int private)
+{
+ ignore_value (futex_wait (futex_word, expected, private));
+}
+
+
+/* Like futex_wait but is a POSIX cancellation point. */
+static __always_inline int
+futex_wait_cancelable (unsigned int *futex_word, unsigned int expected,
+ int private);
+
+/* Like futex_wait, but will eventually time out (i.e., stop being
+ blocked) after the duration of time provided (i.e., RELTIME) has
+ passed. The caller must provide a normalized RELTIME. RELTIME can also
+ equal NULL, in which case this function behaves equivalent to futex_wait.
+
+ Returns the same values as futex_wait under those same conditions;
+ additionally, returns ETIMEDOUT if the timeout expired.
+ */
+static __always_inline int
+futex_reltimed_wait (unsigned int* futex_word, unsigned int expected,
+ const struct timespec* reltime, int private);
+
+/* Like futex_reltimed_wait but is a POSIX cancellation point. */
+static __always_inline int
+futex_reltimed_wait_cancelable (unsigned int* futex_word,
+ unsigned int expected,
+ const struct timespec* reltime, int private);
+
+/* Like futex_reltimed_wait, but the provided timeout (ABSTIME) is an
+ absolute point in time; a call will time out after this point in time. */
+static __always_inline int
+futex_abstimed_wait (unsigned int* futex_word, unsigned int expected,
+ const struct timespec* abstime, int private);
+
+/* Like futex_reltimed_wait but is a POSIX cancellation point. */
+static __always_inline int
+futex_abstimed_wait_cancelable (unsigned int* futex_word,
+ unsigned int expected,
+ const struct timespec* abstime, int private);
+
+/* Atomically wrt other futex operations on the same futex, this unblocks the
+ specified number of processes, or all processes blocked on this futex if
+ there are fewer than the specified number. Semantically, this is
+ equivalent to:
+ l = <get lock associated with futex> (FUTEX_WORD);
+ lock (l);
+ for (res = 0; PROCESSES_TO_WAKE > 0; PROCESSES_TO_WAKE--, res++) {
+ if (<no process blocked on futex>) break;
+ wf = <get wait_flag of a process blocked on futex> (FUTEX_WORD);
+ // No happens-before guarantee with woken futex_wait (see above)
+ atomic_store_relaxed (wf, 0);
+ }
+ return res;
+
+ Note that we need to support futex_wake calls to past futexes whose memory
+ has potentially been reused due to POSIX' requirements on synchronization
+ object destruction (see above); therefore, we must not report or abort
+ on most errors. */
+static __always_inline void
+futex_wake (unsigned int* futex_word, int processes_to_wake, int private);
+
+/* Calls __libc_fatal with an error message. Convenience function for
+ concrete implementations of the futex interface. */
+static __always_inline __attribute__ ((__noreturn__)) void
+futex_fatal_error (void)
+{
+ __libc_fatal ("The futex facility returned an unexpected error code.");
+}
+
+#endif /* futex-internal.h */
diff --git a/REORG.TODO/sysdeps/nptl/gai_misc.h b/REORG.TODO/sysdeps/nptl/gai_misc.h
new file mode 100644
index 0000000000..8b2a2c1d78
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/gai_misc.h
@@ -0,0 +1,123 @@
+/* Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the 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/>. */
+
+/* We define a special synchronization primitive for AIO. POSIX
+ conditional variables would be ideal but the pthread_cond_*wait
+ operations do not return on EINTR. This is a requirement for
+ correct aio_suspend and lio_listio implementations. */
+
+#include <assert.h>
+#include <signal.h>
+#include <nptl/pthreadP.h>
+#include <futex-internal.h>
+
+#define DONT_NEED_GAI_MISC_COND 1
+
+#define GAI_MISC_NOTIFY(waitlist) \
+ do { \
+ if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \
+ futex_wake ((unsigned int *) waitlist->counterp, 1, FUTEX_PRIVATE); \
+ } while (0)
+
+#define GAI_MISC_WAIT(result, futex, timeout, cancel) \
+ do { \
+ volatile unsigned int *futexaddr = &futex; \
+ unsigned int oldval = futex; \
+ \
+ if (oldval != 0) \
+ { \
+ pthread_mutex_unlock (&__gai_requests_mutex); \
+ \
+ int oldtype; \
+ if (cancel) \
+ oldtype = LIBC_CANCEL_ASYNC (); \
+ \
+ int status; \
+ do \
+ { \
+ status = futex_reltimed_wait ((unsigned int *) futexaddr, oldval, \
+ timeout, FUTEX_PRIVATE); \
+ if (status != EAGAIN) \
+ break; \
+ \
+ oldval = *futexaddr; \
+ } \
+ while (oldval != 0); \
+ \
+ if (cancel) \
+ LIBC_CANCEL_RESET (oldtype); \
+ \
+ if (status == EINTR) \
+ result = EINTR; \
+ else if (status == ETIMEDOUT) \
+ result = EAGAIN; \
+ else \
+ assert (status == 0 || status == EAGAIN); \
+ \
+ pthread_mutex_lock (&__gai_requests_mutex); \
+ } \
+ } while (0)
+
+
+#define gai_start_notify_thread __gai_start_notify_thread
+#define gai_create_helper_thread __gai_create_helper_thread
+
+extern inline void
+__gai_start_notify_thread (void)
+{
+ sigset_t ss;
+ sigemptyset (&ss);
+ int sigerr __attribute__ ((unused));
+ sigerr = pthread_sigmask (SIG_SETMASK, &ss, NULL);
+ assert_perror (sigerr);
+}
+
+extern inline int
+__gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
+ void *arg)
+{
+ pthread_attr_t attr;
+
+ /* Make sure the thread is created detached. */
+ pthread_attr_init (&attr);
+ pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+ /* The helper thread needs only very little resources. */
+ (void) pthread_attr_setstacksize (&attr,
+ __pthread_get_minstack (&attr)
+ + 4 * PTHREAD_STACK_MIN);
+
+ /* Block all signals in the helper thread. To do this thoroughly we
+ temporarily have to block all signals here. */
+ sigset_t ss;
+ sigset_t oss;
+ sigfillset (&ss);
+ int sigerr __attribute__ ((unused));
+ sigerr = pthread_sigmask (SIG_SETMASK, &ss, &oss);
+ assert_perror (sigerr);
+
+ int ret = pthread_create (threadp, &attr, tf, arg);
+
+ /* Restore the signal mask. */
+ sigerr = pthread_sigmask (SIG_SETMASK, &oss, NULL);
+ assert_perror (sigerr);
+
+ (void) pthread_attr_destroy (&attr);
+ return ret;
+}
+
+#include_next <gai_misc.h>
diff --git a/REORG.TODO/sysdeps/nptl/internaltypes.h b/REORG.TODO/sysdeps/nptl/internaltypes.h
new file mode 100644
index 0000000000..5be9d983ab
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/internaltypes.h
@@ -0,0 +1,179 @@
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _INTERNALTYPES_H
+#define _INTERNALTYPES_H 1
+
+#include <stdint.h>
+#include <atomic.h>
+#include <endian.h>
+
+
+struct pthread_attr
+{
+ /* Scheduler parameters and priority. */
+ struct sched_param schedparam;
+ int schedpolicy;
+ /* Various flags like detachstate, scope, etc. */
+ int flags;
+ /* Size of guard area. */
+ size_t guardsize;
+ /* Stack handling. */
+ void *stackaddr;
+ size_t stacksize;
+ /* Affinity map. */
+ cpu_set_t *cpuset;
+ size_t cpusetsize;
+};
+
+#define ATTR_FLAG_DETACHSTATE 0x0001
+#define ATTR_FLAG_NOTINHERITSCHED 0x0002
+#define ATTR_FLAG_SCOPEPROCESS 0x0004
+#define ATTR_FLAG_STACKADDR 0x0008
+#define ATTR_FLAG_OLDATTR 0x0010
+#define ATTR_FLAG_SCHED_SET 0x0020
+#define ATTR_FLAG_POLICY_SET 0x0040
+
+
+/* Mutex attribute data structure. */
+struct pthread_mutexattr
+{
+ /* Identifier for the kind of mutex.
+
+ Bit 31 is set if the mutex is to be shared between processes.
+
+ Bit 0 to 30 contain one of the PTHREAD_MUTEX_ values to identify
+ the type of the mutex. */
+ int mutexkind;
+};
+
+
+/* Conditional variable attribute data structure. */
+struct pthread_condattr
+{
+ /* Combination of values:
+
+ Bit 0 : flag whether conditional variable will be
+ sharable between processes.
+ Bit 1-COND_CLOCK_BITS: Clock ID. COND_CLOCK_BITS is the number of bits
+ needed to represent the ID of the clock. */
+ int value;
+};
+#define COND_CLOCK_BITS 1
+
+
+/* Read-write lock variable attribute data structure. */
+struct pthread_rwlockattr
+{
+ int lockkind;
+ int pshared;
+};
+
+
+/* Barrier data structure. See pthread_barrier_wait for a description
+ of how these fields are used. */
+struct pthread_barrier
+{
+ unsigned int in;
+ unsigned int current_round;
+ unsigned int count;
+ int shared;
+ unsigned int out;
+};
+/* See pthread_barrier_wait for a description. */
+#define BARRIER_IN_THRESHOLD (UINT_MAX/2)
+
+
+/* Barrier variable attribute data structure. */
+struct pthread_barrierattr
+{
+ int pshared;
+};
+
+
+/* Thread-local data handling. */
+struct pthread_key_struct
+{
+ /* Sequence numbers. Even numbers indicated vacant entries. Note
+ that zero is even. We use uintptr_t to not require padding on
+ 32- and 64-bit machines. On 64-bit machines it helps to avoid
+ wrapping, too. */
+ uintptr_t seq;
+
+ /* Destructor for the data. */
+ void (*destr) (void *);
+};
+
+/* Check whether an entry is unused. */
+#define KEY_UNUSED(p) (((p) & 1) == 0)
+/* Check whether a key is usable. We cannot reuse an allocated key if
+ the sequence counter would overflow after the next destroy call.
+ This would mean that we potentially free memory for a key with the
+ same sequence. This is *very* unlikely to happen, A program would
+ have to create and destroy a key 2^31 times (on 32-bit platforms,
+ on 64-bit platforms that would be 2^63). If it should happen we
+ simply don't use this specific key anymore. */
+#define KEY_USABLE(p) (((uintptr_t) (p)) < ((uintptr_t) ((p) + 2)))
+
+
+/* Handling of read-write lock data. */
+// XXX For now there is only one flag. Maybe more in future.
+#define RWLOCK_RECURSIVE(rwlock) ((rwlock)->__data.__flags != 0)
+
+
+/* Semaphore variable structure. */
+struct new_sem
+{
+#if __HAVE_64B_ATOMICS
+ /* The data field holds both value (in the least-significant 32 bytes) and
+ nwaiters. */
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define SEM_VALUE_OFFSET 0
+# elif __BYTE_ORDER == __BIG_ENDIAN
+# define SEM_VALUE_OFFSET 1
+# else
+# error Unsupported byte order.
+# endif
+# define SEM_NWAITERS_SHIFT 32
+# define SEM_VALUE_MASK (~(unsigned int)0)
+ uint64_t data;
+ int private;
+ int pad;
+#else
+# define SEM_VALUE_SHIFT 1
+# define SEM_NWAITERS_MASK ((unsigned int)1)
+ unsigned int value;
+ int private;
+ int pad;
+ unsigned int nwaiters;
+#endif
+};
+
+struct old_sem
+{
+ unsigned int value;
+};
+
+
+/* Compatibility type for old conditional variable interfaces. */
+typedef struct
+{
+ pthread_cond_t *cond;
+} pthread_cond_2_0_t;
+
+#endif /* internaltypes.h */
diff --git a/REORG.TODO/sysdeps/nptl/jmp-unwind.c b/REORG.TODO/sysdeps/nptl/jmp-unwind.c
new file mode 100644
index 0000000000..8a26064c7f
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/jmp-unwind.c
@@ -0,0 +1,32 @@
+/* Clean up stack frames unwound by longjmp. Linux version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <setjmp.h>
+#include <stddef.h>
+#include <libc-lock.h>
+
+extern void __pthread_cleanup_upto (__jmp_buf env, char *targetframe);
+#pragma weak __pthread_cleanup_upto
+
+
+void
+_longjmp_unwind (jmp_buf env, int val)
+{
+ __libc_ptf_call (__pthread_cleanup_upto, (env->__jmpbuf,
+ CURRENT_STACK_FRAME), 0);
+}
diff --git a/REORG.TODO/sysdeps/nptl/libc-lock.h b/REORG.TODO/sysdeps/nptl/libc-lock.h
new file mode 100644
index 0000000000..f1b5659d32
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/libc-lock.h
@@ -0,0 +1,187 @@
+/* libc-internal interface for mutex locks. NPTL version.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_LOCK_H
+#define _LIBC_LOCK_H 1
+
+#include <pthread.h>
+#define __need_NULL
+#include <stddef.h>
+
+
+/* Mutex type. */
+#if defined _LIBC || defined _IO_MTSAFE_IO
+# if (!IS_IN (libc) && !IS_IN (libpthread)) || !defined _LIBC
+typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t;
+# else
+typedef struct { int lock; int cnt; void *owner; } __libc_lock_recursive_t;
+# endif
+#else
+typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+#endif
+
+/* Define a lock variable NAME with storage class CLASS. The lock must be
+ initialized with __libc_lock_init before it can be used (or define it
+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
+ declare a lock defined in another module. In public structure
+ definitions you must use a pointer to the lock structure (i.e., NAME
+ begins with a `*'), because its storage size will not be known outside
+ of libc. */
+#define __libc_lock_define_recursive(CLASS,NAME) \
+ CLASS __libc_lock_recursive_t NAME;
+
+/* Define an initialized recursive lock variable NAME with storage
+ class CLASS. */
+#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
+# define __libc_lock_define_initialized_recursive(CLASS, NAME) \
+ CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+# define _LIBC_LOCK_RECURSIVE_INITIALIZER \
+ { LLL_LOCK_INITIALIZER, 0, NULL }
+#else
+# define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+ CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+# define _LIBC_LOCK_RECURSIVE_INITIALIZER \
+ {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
+#endif
+
+/* Initialize a recursive mutex. */
+#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
+# define __libc_lock_init_recursive(NAME) \
+ ((void) ((NAME) = (__libc_lock_recursive_t) _LIBC_LOCK_RECURSIVE_INITIALIZER))
+#else
+# define __libc_lock_init_recursive(NAME) \
+ do { \
+ if (__pthread_mutex_init != NULL) \
+ { \
+ pthread_mutexattr_t __attr; \
+ __pthread_mutexattr_init (&__attr); \
+ __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \
+ __pthread_mutex_init (&(NAME).mutex, &__attr); \
+ __pthread_mutexattr_destroy (&__attr); \
+ } \
+ } while (0)
+#endif
+
+/* Finalize recursive named lock. */
+#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
+# define __libc_lock_fini_recursive(NAME) ((void) 0)
+#else
+# define __libc_lock_fini_recursive(NAME) \
+ __libc_maybe_call (__pthread_mutex_destroy, (&(NAME).mutex), 0)
+#endif
+
+/* Lock the recursive named lock variable. */
+#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
+# define __libc_lock_lock_recursive(NAME) \
+ do { \
+ void *self = THREAD_SELF; \
+ if ((NAME).owner != self) \
+ { \
+ lll_lock ((NAME).lock, LLL_PRIVATE); \
+ (NAME).owner = self; \
+ } \
+ ++(NAME).cnt; \
+ } while (0)
+#else
+# define __libc_lock_lock_recursive(NAME) \
+ __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+#endif
+
+/* Try to lock the recursive named lock variable. */
+#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
+# define __libc_lock_trylock_recursive(NAME) \
+ ({ \
+ int result = 0; \
+ void *self = THREAD_SELF; \
+ if ((NAME).owner != self) \
+ { \
+ if (lll_trylock ((NAME).lock) == 0) \
+ { \
+ (NAME).owner = self; \
+ (NAME).cnt = 1; \
+ } \
+ else \
+ result = EBUSY; \
+ } \
+ else \
+ ++(NAME).cnt; \
+ result; \
+ })
+#else
+# define __libc_lock_trylock_recursive(NAME) \
+ __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
+#endif
+
+/* Unlock the recursive named lock variable. */
+#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
+/* We do no error checking here. */
+# define __libc_lock_unlock_recursive(NAME) \
+ do { \
+ if (--(NAME).cnt == 0) \
+ { \
+ (NAME).owner = NULL; \
+ lll_unlock ((NAME).lock, LLL_PRIVATE); \
+ } \
+ } while (0)
+#else
+# define __libc_lock_unlock_recursive(NAME) \
+ __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+#endif
+
+/* Note that for I/O cleanup handling we are using the old-style
+ cancel handling. It does not have to be integrated with C++ since
+ no C++ code is called in the middle. The old-style handling is
+ faster and the support is not going away. */
+extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
+ void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
+ int execute);
+
+/* Start critical region with cleanup. */
+#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
+ { struct _pthread_cleanup_buffer _buffer; \
+ int _avail; \
+ if (DOIT) { \
+ _avail = PTFAVAIL (_pthread_cleanup_push_defer); \
+ if (_avail) { \
+ __libc_ptf_call_always (_pthread_cleanup_push_defer, (&_buffer, FCT, \
+ ARG)); \
+ } else { \
+ _buffer.__routine = (FCT); \
+ _buffer.__arg = (ARG); \
+ } \
+ } else { \
+ _avail = 0; \
+ }
+
+/* End critical region with cleanup. */
+#define __libc_cleanup_region_end(DOIT) \
+ if (_avail) { \
+ __libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
+ } else if (DOIT) \
+ _buffer.__routine (_buffer.__arg); \
+ }
+
+
+/* Hide the definitions which are only supposed to be used inside libc in
+ a separate file. This file is not present in the installation! */
+#ifdef _LIBC
+# include "libc-lockP.h"
+#endif
+
+#endif /* libc-lock.h */
diff --git a/REORG.TODO/sysdeps/nptl/libc-lockP.h b/REORG.TODO/sysdeps/nptl/libc-lockP.h
new file mode 100644
index 0000000000..a43e62db4d
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/libc-lockP.h
@@ -0,0 +1,438 @@
+/* Private libc-internal interface for mutex locks. NPTL version.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_LOCKP_H
+#define _LIBC_LOCKP_H 1
+
+#include <pthread.h>
+#define __need_NULL
+#include <stddef.h>
+
+
+/* Fortunately Linux now has a mean to do locking which is realtime
+ safe without the aid of the thread library. We also need no fancy
+ options like error checking mutexes etc. We only need simple
+ locks, maybe recursive. This can be easily and cheaply implemented
+ using futexes. We will use them everywhere except in ld.so since
+ ld.so might be used on old kernels with a different libc.so. */
+#include <lowlevellock.h>
+#include <tls.h>
+#include <pthread-functions.h>
+
+#if IS_IN (libpthread)
+/* This gets us the declarations of the __pthread_* internal names,
+ and hidden_proto for them. */
+# include <nptl/pthreadP.h>
+#endif
+
+/* Mutex type. */
+#if !IS_IN (libc) && !IS_IN (libpthread)
+typedef pthread_mutex_t __libc_lock_t;
+#else
+typedef int __libc_lock_t;
+#endif
+typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t;
+typedef pthread_rwlock_t __libc_rwlock_t;
+
+/* Type for key to thread-specific data. */
+typedef pthread_key_t __libc_key_t;
+
+/* Define a lock variable NAME with storage class CLASS. The lock must be
+ initialized with __libc_lock_init before it can be used (or define it
+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
+ declare a lock defined in another module. In public structure
+ definitions you must use a pointer to the lock structure (i.e., NAME
+ begins with a `*'), because its storage size will not be known outside
+ of libc. */
+#define __libc_lock_define(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+#define __libc_rwlock_define(CLASS,NAME) \
+ CLASS __libc_rwlock_t NAME;
+#define __rtld_lock_define_recursive(CLASS,NAME) \
+ CLASS __rtld_lock_recursive_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS.
+
+ For the C library we take a deeper look at the initializer. For
+ this implementation all fields are initialized to zero. Therefore
+ we don't initialize the variable which allows putting it into the
+ BSS section. (Except on PA-RISC and other odd architectures, where
+ initialized locks must be set to one due to the lack of normal
+ atomic operations.) */
+
+#define _LIBC_LOCK_INITIALIZER LLL_LOCK_INITIALIZER
+#if IS_IN (libc) || IS_IN (libpthread)
+# if LLL_LOCK_INITIALIZER == 0
+# define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+# else
+# define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME = LLL_LOCK_INITIALIZER;
+# endif
+#else
+# define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+#endif
+
+#define __libc_rwlock_define_initialized(CLASS,NAME) \
+ CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER;
+
+#define __rtld_lock_define_initialized_recursive(CLASS,NAME) \
+ CLASS __rtld_lock_recursive_t NAME = _RTLD_LOCK_RECURSIVE_INITIALIZER;
+#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
+ {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
+
+#define __rtld_lock_initialize(NAME) \
+ (void) ((NAME) = (__rtld_lock_recursive_t) _RTLD_LOCK_RECURSIVE_INITIALIZER)
+
+/* If we check for a weakly referenced symbol and then perform a
+ normal jump to it te code generated for some platforms in case of
+ PIC is unnecessarily slow. What would happen is that the function
+ is first referenced as data and then it is called indirectly
+ through the PLT. We can make this a direct jump. */
+#ifdef __PIC__
+# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+ (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
+ _fn != NULL ? (*_fn) ARGS : ELSE; }))
+#else
+# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+ (FUNC != NULL ? FUNC ARGS : ELSE)
+#endif
+
+/* Call thread functions through the function pointer table. */
+#if defined SHARED && IS_IN (libc)
+# define PTFAVAIL(NAME) __libc_pthread_functions_init
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+ (__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+ PTHFCT_CALL (ptr_##FUNC, ARGS)
+#elif IS_IN (libpthread)
+# define PTFAVAIL(NAME) 1
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+ FUNC ARGS
+# define __libc_ptf_call_always(FUNC, ARGS) \
+ FUNC ARGS
+#else
+# define PTFAVAIL(NAME) (NAME != NULL)
+# define __libc_ptf_call(FUNC, ARGS, ELSE) \
+ __libc_maybe_call (FUNC, ARGS, ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+ FUNC ARGS
+#endif
+
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+ state. */
+#if IS_IN (libc) || IS_IN (libpthread)
+# define __libc_lock_init(NAME) \
+ ((void) ((NAME) = LLL_LOCK_INITIALIZER))
+#else
+# define __libc_lock_init(NAME) \
+ __libc_maybe_call (__pthread_mutex_init, (&(NAME), NULL), 0)
+#endif
+#if defined SHARED && IS_IN (libc)
+/* ((NAME) = (__libc_rwlock_t) PTHREAD_RWLOCK_INITIALIZER) is inefficient. */
+# define __libc_rwlock_init(NAME) \
+ ((void) __builtin_memset (&(NAME), '\0', sizeof (NAME)))
+#else
+# define __libc_rwlock_init(NAME) \
+ __libc_maybe_call (__pthread_rwlock_init, (&(NAME), NULL), 0)
+#endif
+
+/* Finalize the named lock variable, which must be locked. It cannot be
+ used again until __libc_lock_init is called again on it. This must be
+ called on a lock variable before the containing storage is reused. */
+#if IS_IN (libc) || IS_IN (libpthread)
+# define __libc_lock_fini(NAME) ((void) 0)
+#else
+# define __libc_lock_fini(NAME) \
+ __libc_maybe_call (__pthread_mutex_destroy, (&(NAME)), 0)
+#endif
+#if defined SHARED && IS_IN (libc)
+# define __libc_rwlock_fini(NAME) ((void) 0)
+#else
+# define __libc_rwlock_fini(NAME) \
+ __libc_maybe_call (__pthread_rwlock_destroy, (&(NAME)), 0)
+#endif
+
+/* Lock the named lock variable. */
+#if IS_IN (libc) || IS_IN (libpthread)
+# ifndef __libc_lock_lock
+# define __libc_lock_lock(NAME) \
+ ({ lll_lock (NAME, LLL_PRIVATE); 0; })
+# endif
+#else
+# undef __libc_lock_lock
+# define __libc_lock_lock(NAME) \
+ __libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0)
+#endif
+#define __libc_rwlock_rdlock(NAME) \
+ __libc_ptf_call (__pthread_rwlock_rdlock, (&(NAME)), 0)
+#define __libc_rwlock_wrlock(NAME) \
+ __libc_ptf_call (__pthread_rwlock_wrlock, (&(NAME)), 0)
+
+/* Try to lock the named lock variable. */
+#if IS_IN (libc) || IS_IN (libpthread)
+# ifndef __libc_lock_trylock
+# define __libc_lock_trylock(NAME) \
+ lll_trylock (NAME)
+# endif
+#else
+# undef __libc_lock_trylock
+# define __libc_lock_trylock(NAME) \
+ __libc_maybe_call (__pthread_mutex_trylock, (&(NAME)), 0)
+#endif
+#define __libc_rwlock_tryrdlock(NAME) \
+ __libc_maybe_call (__pthread_rwlock_tryrdlock, (&(NAME)), 0)
+#define __libc_rwlock_trywrlock(NAME) \
+ __libc_maybe_call (__pthread_rwlock_trywrlock, (&(NAME)), 0)
+
+#define __rtld_lock_trylock_recursive(NAME) \
+ __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
+
+/* Unlock the named lock variable. */
+#if IS_IN (libc) || IS_IN (libpthread)
+# define __libc_lock_unlock(NAME) \
+ lll_unlock (NAME, LLL_PRIVATE)
+#else
+# define __libc_lock_unlock(NAME) \
+ __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
+#endif
+#define __libc_rwlock_unlock(NAME) \
+ __libc_ptf_call (__pthread_rwlock_unlock, (&(NAME)), 0)
+
+#ifdef SHARED
+# define __rtld_lock_default_lock_recursive(lock) \
+ ++((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_default_unlock_recursive(lock) \
+ --((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_lock_recursive(NAME) \
+ GL(dl_rtld_lock_recursive) (&(NAME).mutex)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+ GL(dl_rtld_unlock_recursive) (&(NAME).mutex)
+#else
+# define __rtld_lock_lock_recursive(NAME) \
+ __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+ __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+#endif
+
+/* Define once control variable. */
+#if PTHREAD_ONCE_INIT == 0
+/* Special case for static variables where we can avoid the initialization
+ if it is zero. */
+# define __libc_once_define(CLASS, NAME) \
+ CLASS pthread_once_t NAME
+#else
+# define __libc_once_define(CLASS, NAME) \
+ CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT
+#endif
+
+/* Call handler iff the first call. */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+ do { \
+ if (PTFAVAIL (__pthread_once)) \
+ __libc_ptf_call_always (__pthread_once, (&(ONCE_CONTROL), \
+ INIT_FUNCTION)); \
+ else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \
+ INIT_FUNCTION (); \
+ (ONCE_CONTROL) |= 2; \
+ } \
+ } while (0)
+
+/* Get once control variable. */
+#define __libc_once_get(ONCE_CONTROL) ((ONCE_CONTROL) != PTHREAD_ONCE_INIT)
+
+/* Note that for I/O cleanup handling we are using the old-style
+ cancel handling. It does not have to be integrated with C++ snce
+ no C++ code is called in the middle. The old-style handling is
+ faster and the support is not going away. */
+extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
+ void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
+ int execute);
+extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
+ void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
+ int execute);
+
+/* Sometimes we have to exit the block in the middle. */
+#define __libc_cleanup_end(DOIT) \
+ if (_avail) { \
+ __libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
+ } else if (DOIT) \
+ _buffer.__routine (_buffer.__arg)
+
+
+/* Normal cleanup handling, based on C cleanup attribute. */
+__extern_inline void
+__libc_cleanup_routine (struct __pthread_cleanup_frame *f)
+{
+ if (f->__do_it)
+ f->__cancel_routine (f->__cancel_arg);
+}
+
+#define __libc_cleanup_push(fct, arg) \
+ do { \
+ struct __pthread_cleanup_frame __clframe \
+ __attribute__ ((__cleanup__ (__libc_cleanup_routine))) \
+ = { .__cancel_routine = (fct), .__cancel_arg = (arg), \
+ .__do_it = 1 };
+
+#define __libc_cleanup_pop(execute) \
+ __clframe.__do_it = (execute); \
+ } while (0)
+
+
+/* Create thread-specific key. */
+#define __libc_key_create(KEY, DESTRUCTOR) \
+ __libc_ptf_call (__pthread_key_create, (KEY, DESTRUCTOR), 1)
+
+/* Get thread-specific data. */
+#define __libc_getspecific(KEY) \
+ __libc_ptf_call (__pthread_getspecific, (KEY), NULL)
+
+/* Set thread-specific data. */
+#define __libc_setspecific(KEY, VALUE) \
+ __libc_ptf_call (__pthread_setspecific, (KEY, VALUE), 0)
+
+
+/* Register handlers to execute before and after `fork'. Note that the
+ last parameter is NULL. The handlers registered by the libc are
+ never removed so this is OK. */
+#define __libc_atfork(PREPARE, PARENT, CHILD) \
+ __register_atfork (PREPARE, PARENT, CHILD, NULL)
+extern int __register_atfork (void (*__prepare) (void),
+ void (*__parent) (void),
+ void (*__child) (void),
+ void *__dso_handle);
+
+/* Functions that are used by this file and are internal to the GNU C
+ library. */
+
+extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
+ const pthread_mutexattr_t *__mutex_attr);
+
+extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr,
+ int __kind);
+
+extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock,
+ const pthread_rwlockattr_t *__attr);
+
+extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_key_create (pthread_key_t *__key,
+ void (*__destr_function) (void *));
+
+extern int __pthread_setspecific (pthread_key_t __key,
+ const void *__pointer);
+
+extern void *__pthread_getspecific (pthread_key_t __key);
+
+extern int __pthread_once (pthread_once_t *__once_control,
+ void (*__init_routine) (void));
+
+extern int __pthread_atfork (void (*__prepare) (void),
+ void (*__parent) (void),
+ void (*__child) (void));
+
+extern int __pthread_setcancelstate (int state, int *oldstate);
+
+
+/* Make the pthread functions weak so that we can elide them from
+ single-threaded processes. */
+#ifndef __NO_WEAK_PTHREAD_ALIASES
+# ifdef weak_extern
+weak_extern (__pthread_mutex_init)
+weak_extern (__pthread_mutex_destroy)
+weak_extern (__pthread_mutex_lock)
+weak_extern (__pthread_mutex_trylock)
+weak_extern (__pthread_mutex_unlock)
+weak_extern (__pthread_mutexattr_init)
+weak_extern (__pthread_mutexattr_destroy)
+weak_extern (__pthread_mutexattr_settype)
+weak_extern (__pthread_rwlock_init)
+weak_extern (__pthread_rwlock_destroy)
+weak_extern (__pthread_rwlock_rdlock)
+weak_extern (__pthread_rwlock_tryrdlock)
+weak_extern (__pthread_rwlock_wrlock)
+weak_extern (__pthread_rwlock_trywrlock)
+weak_extern (__pthread_rwlock_unlock)
+weak_extern (__pthread_key_create)
+weak_extern (__pthread_setspecific)
+weak_extern (__pthread_getspecific)
+weak_extern (__pthread_once)
+weak_extern (__pthread_initialize)
+weak_extern (__pthread_atfork)
+weak_extern (__pthread_setcancelstate)
+weak_extern (_pthread_cleanup_push_defer)
+weak_extern (_pthread_cleanup_pop_restore)
+# else
+# pragma weak __pthread_mutex_init
+# pragma weak __pthread_mutex_destroy
+# pragma weak __pthread_mutex_lock
+# pragma weak __pthread_mutex_trylock
+# pragma weak __pthread_mutex_unlock
+# pragma weak __pthread_mutexattr_init
+# pragma weak __pthread_mutexattr_destroy
+# pragma weak __pthread_mutexattr_settype
+# pragma weak __pthread_rwlock_destroy
+# pragma weak __pthread_rwlock_rdlock
+# pragma weak __pthread_rwlock_tryrdlock
+# pragma weak __pthread_rwlock_wrlock
+# pragma weak __pthread_rwlock_trywrlock
+# pragma weak __pthread_rwlock_unlock
+# pragma weak __pthread_key_create
+# pragma weak __pthread_setspecific
+# pragma weak __pthread_getspecific
+# pragma weak __pthread_once
+# pragma weak __pthread_initialize
+# pragma weak __pthread_atfork
+# pragma weak __pthread_setcancelstate
+# pragma weak _pthread_cleanup_push_defer
+# pragma weak _pthread_cleanup_pop_restore
+# endif
+#endif
+
+#endif /* libc-lockP.h */
diff --git a/REORG.TODO/sysdeps/nptl/librt-cancellation.c b/REORG.TODO/sysdeps/nptl/librt-cancellation.c
new file mode 100644
index 0000000000..19322429e2
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/librt-cancellation.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <nptl/pthreadP.h>
+
+
+#define __pthread_enable_asynccancel __librt_enable_asynccancel
+#define __pthread_disable_asynccancel __librt_disable_asynccancel
+#include <nptl/cancellation.c>
diff --git a/REORG.TODO/sysdeps/nptl/lowlevellock-futex.h b/REORG.TODO/sysdeps/nptl/lowlevellock-futex.h
new file mode 100644
index 0000000000..155080ac70
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/lowlevellock-futex.h
@@ -0,0 +1,86 @@
+/* Low-level locking access to futex facilities. Stub version.
+ Copyright (C) 2014-2017 Free Software Foundation, Inc.
+ This file is part of the 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 _LOWLEVELLOCK_FUTEX_H
+#define _LOWLEVELLOCK_FUTEX_H 1
+
+#include <errno.h>
+
+
+/* Values for 'private' parameter of locking macros. Note pthreadP.h
+ optimizes for these exact values, though they are not required. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED 128
+
+
+/* For most of these macros, the return value is never really used.
+ Nevertheless, the protocol is that each one returns a negated errno
+ code for failure or zero for success. (Note that the corresponding
+ Linux system calls can sometimes return positive values for success
+ cases too. We never use those values.) */
+
+
+/* Wait while *FUTEXP == VAL for an lll_futex_wake call on FUTEXP. */
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait (futexp, val, NULL, private)
+
+/* Wait until a lll_futex_wake call on FUTEXP, or TIMEOUT elapses. */
+#define lll_futex_timed_wait(futexp, val, timeout, private) \
+ -ENOSYS
+
+/* This macro should be defined only if FUTEX_CLOCK_REALTIME is also defined.
+ If CLOCKBIT is zero, this is identical to lll_futex_timed_wait.
+ If CLOCKBIT has FUTEX_CLOCK_REALTIME set, then it's the same but
+ TIMEOUT is counted by CLOCK_REALTIME rather than CLOCK_MONOTONIC. */
+#define lll_futex_timed_wait_bitset(futexp, val, timeout, clockbit, private) \
+ -ENOSYS
+
+/* Wake up up to NR waiters on FUTEXP. */
+#define lll_futex_wake(futexp, nr, private) \
+ -ENOSYS
+
+/* Wake up up to NR_WAKE waiters on FUTEXP. Move up to NR_MOVE of the
+ rest from waiting on FUTEXP to waiting on MUTEX (a different futex). */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ -ENOSYS
+
+/* Wake up up to NR_WAKE waiters on FUTEXP and NR_WAKE2 on FUTEXP2. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ -ENOSYS
+
+
+/* Like lll_futex_wait (FUTEXP, VAL, PRIVATE) but with the expectation
+ that lll_futex_cmp_requeue_pi (FUTEXP, _, _, MUTEX, _, PRIVATE) will
+ be used to do the wakeup. Confers priority-inheritance behavior on
+ the waiter. */
+#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \
+ lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private)
+
+/* Like lll_futex_wait_requeue_pi, but with a timeout. */
+#define lll_futex_timed_wait_requeue_pi(futexp, val, timeout, clockbit, \
+ mutex, private) \
+ -ENOSYS
+
+/* Like lll_futex_requeue, but pairs with lll_futex_wait_requeue_pi
+ and inherits priority from the waiter. */
+#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, \
+ val, private) \
+ -ENOSYS
+
+
+#endif /* lowlevellock-futex.h */
diff --git a/REORG.TODO/sysdeps/nptl/lowlevellock.h b/REORG.TODO/sysdeps/nptl/lowlevellock.h
new file mode 100644
index 0000000000..54e3c28b0b
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/lowlevellock.h
@@ -0,0 +1,205 @@
+/* Low-level lock implementation. Generic futex-based version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the 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 _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <atomic.h>
+#include <lowlevellock-futex.h>
+
+/* Low-level locks use a combination of atomic operations (to acquire and
+ release lock ownership) and futex operations (to block until the state
+ of a lock changes). A lock can be in one of three states:
+ 0: not acquired,
+ 1: acquired with no waiters; no other threads are blocked or about to block
+ for changes to the lock state,
+ >1: acquired, possibly with waiters; there may be other threads blocked or
+ about to block for changes to the lock state.
+
+ We expect that the common case is an uncontended lock, so we just need
+ to transition the lock between states 0 and 1; releasing the lock does
+ not need to wake any other blocked threads. If the lock is contended
+ and a thread decides to block using a futex operation, then this thread
+ needs to first change the state to >1; if this state is observed during
+ lock release, the releasing thread will wake one of the potentially
+ blocked threads.
+
+ Much of this code takes a 'private' parameter. This may be:
+ LLL_PRIVATE: lock only shared within a process
+ LLL_SHARED: lock may be shared across processes.
+
+ Condition variables contain an optimization for broadcasts that requeues
+ waiting threads on a lock's futex. Therefore, there is a special
+ variant of the locks (whose name contains "cond") that makes sure to
+ always set the lock state to >1 and not just 1.
+
+ Robust locks set the lock to the id of the owner. This allows detection
+ of the case where the owner exits without releasing the lock. Flags are
+ OR'd with the owner id to record additional information about lock state.
+ Therefore the states of robust locks are:
+ 0: not acquired
+ id: acquired (by user identified by id & FUTEX_TID_MASK)
+
+ The following flags may be set in the robust lock value:
+ FUTEX_WAITERS - possibly has waiters
+ FUTEX_OWNER_DIED - owning user has exited without releasing the futex. */
+
+
+/* If LOCK is 0 (not acquired), set to 1 (acquired with no waiters) and return
+ 0. Otherwise leave lock unchanged and return non-zero to indicate that the
+ lock was not acquired. */
+#define lll_trylock(lock) \
+ __glibc_unlikely (atomic_compare_and_exchange_bool_acq (&(lock), 1, 0))
+
+/* If LOCK is 0 (not acquired), set to 2 (acquired, possibly with waiters) and
+ return 0. Otherwise leave lock unchanged and return non-zero to indicate
+ that the lock was not acquired. */
+#define lll_cond_trylock(lock) \
+ __glibc_unlikely (atomic_compare_and_exchange_bool_acq (&(lock), 2, 0))
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+
+/* This is an expression rather than a statement even though its value is
+ void, so that it can be used in a comma expression or as an expression
+ that's cast to void. */
+/* The inner conditional compiles to a call to __lll_lock_wait_private if
+ private is known at compile time to be LLL_PRIVATE, and to a call to
+ __lll_lock_wait otherwise. */
+/* If FUTEX is 0 (not acquired), set to 1 (acquired with no waiters) and
+ return. Otherwise, ensure that it is >1 (acquired, possibly with waiters)
+ and then block until we acquire the lock, at which point FUTEX will still be
+ >1. The lock is always acquired on return. */
+#define __lll_lock(futex, private) \
+ ((void) \
+ ({ \
+ int *__futex = (futex); \
+ if (__glibc_unlikely \
+ (atomic_compare_and_exchange_bool_acq (__futex, 1, 0))) \
+ { \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __lll_lock_wait_private (__futex); \
+ else \
+ __lll_lock_wait (__futex, private); \
+ } \
+ }))
+#define lll_lock(futex, private) \
+ __lll_lock (&(futex), private)
+
+
+/* This is an expression rather than a statement even though its value is
+ void, so that it can be used in a comma expression or as an expression
+ that's cast to void. */
+/* Unconditionally set FUTEX to 2 (acquired, possibly with waiters). If FUTEX
+ was 0 (not acquired) then return. Otherwise, block until the lock is
+ acquired, at which point FUTEX is 2 (acquired, possibly with waiters). The
+ lock is always acquired on return. */
+#define __lll_cond_lock(futex, private) \
+ ((void) \
+ ({ \
+ int *__futex = (futex); \
+ if (__glibc_unlikely (atomic_exchange_acq (__futex, 2) != 0)) \
+ __lll_lock_wait (__futex, private); \
+ }))
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+
+
+/* As __lll_lock, but with a timeout. If the timeout occurs then return
+ ETIMEDOUT. If ABSTIME is invalid, return EINVAL. */
+#define __lll_timedlock(futex, abstime, private) \
+ ({ \
+ int *__futex = (futex); \
+ int __val = 0; \
+ \
+ if (__glibc_unlikely \
+ (atomic_compare_and_exchange_bool_acq (__futex, 1, 0))) \
+ __val = __lll_timedlock_wait (__futex, abstime, private); \
+ __val; \
+ })
+#define lll_timedlock(futex, abstime, private) \
+ __lll_timedlock (&(futex), abstime, private)
+
+
+/* This is an expression rather than a statement even though its value is
+ void, so that it can be used in a comma expression or as an expression
+ that's cast to void. */
+/* Unconditionally set FUTEX to 0 (not acquired), releasing the lock. If FUTEX
+ was >1 (acquired, possibly with waiters), then wake any waiters. The waiter
+ that acquires the lock will set FUTEX to >1.
+ Evaluate PRIVATE before releasing the lock so that we do not violate the
+ mutex destruction requirements. Specifically, we need to ensure that
+ another thread can destroy the mutex (and reuse its memory) once it
+ acquires the lock and when there will be no further lock acquisitions;
+ thus, we must not access the lock after releasing it, or those accesses
+ could be concurrent with mutex destruction or reuse of the memory. */
+#define __lll_unlock(futex, private) \
+ ((void) \
+ ({ \
+ int *__futex = (futex); \
+ int __private = (private); \
+ int __oldval = atomic_exchange_rel (__futex, 0); \
+ if (__glibc_unlikely (__oldval > 1)) \
+ lll_futex_wake (__futex, 1, __private); \
+ }))
+#define lll_unlock(futex, private) \
+ __lll_unlock (&(futex), private)
+
+
+#define lll_islocked(futex) \
+ ((futex) != LLL_LOCK_INITIALIZER)
+
+
+/* Our internal lock implementation is identical to the binary-compatible
+ mutex implementation. */
+
+/* Initializers for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
+ wake-up when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero by the kernel
+ afterwards. The kernel up to version 3.16.3 does not use the private futex
+ operations for futex wake-up when the clone terminates. */
+#define lll_wait_tid(tid) \
+ do { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED);\
+ } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+
+/* As lll_wait_tid, but with a timeout. If the timeout occurs then return
+ ETIMEDOUT. If ABSTIME is invalid, return EINVAL. */
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ if ((tid) != 0) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ __res; \
+ })
+
+
+#endif /* lowlevellock.h */
diff --git a/REORG.TODO/sysdeps/nptl/malloc-machine.h b/REORG.TODO/sysdeps/nptl/malloc-machine.h
new file mode 100644
index 0000000000..7dae506a92
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/malloc-machine.h
@@ -0,0 +1,27 @@
+/* Basic platform-independent macro definitions for mutexes,
+ thread-specific data and parameters for malloc.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the 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 _MALLOC_MACHINE_H
+#define _MALLOC_MACHINE_H
+
+#include <atomic.h>
+#include <libc-lock.h>
+#include <sysdeps/generic/malloc-machine.h>
+
+#endif /* !defined(_MALLOC_MACHINE_H) */
diff --git a/REORG.TODO/sysdeps/nptl/nptl-signals.h b/REORG.TODO/sysdeps/nptl/nptl-signals.h
new file mode 100644
index 0000000000..298acf28a6
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/nptl-signals.h
@@ -0,0 +1,22 @@
+/* Special use of signals in NPTL internals. Stub version.
+ Copyright (C) 2014-2017 Free Software Foundation, Inc.
+ This file is part of the 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/>. */
+
+/* This file can define the macros SIGCANCEL, SIGTIMER, and SIGSETXID to
+ signal numbers reserved by libpthread for those internal purposes.
+
+ Note that some code presumes SIGTIMER is the same as SIGCANCEL. */
diff --git a/REORG.TODO/sysdeps/nptl/pthread-functions.h b/REORG.TODO/sysdeps/nptl/pthread-functions.h
new file mode 100644
index 0000000000..4006fc6c25
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/pthread-functions.h
@@ -0,0 +1,117 @@
+/* Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _PTHREAD_FUNCTIONS_H
+#define _PTHREAD_FUNCTIONS_H 1
+
+#include <pthread.h>
+#include <setjmp.h>
+#include <internaltypes.h>
+#include <sysdep.h>
+
+struct xid_command;
+
+/* Data type shared with libc. The libc uses it to pass on calls to
+ the thread functions. */
+struct pthread_functions
+{
+ int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
+ int (*ptr___pthread_attr_init_2_0) (pthread_attr_t *);
+ int (*ptr___pthread_attr_init_2_1) (pthread_attr_t *);
+ int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);
+ int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);
+ int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,
+ struct sched_param *);
+ int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,
+ const struct sched_param *);
+ int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);
+ int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);
+ int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);
+ int (*ptr_pthread_condattr_init) (pthread_condattr_t *);
+ int (*ptr___pthread_cond_broadcast) (pthread_cond_t *);
+ int (*ptr___pthread_cond_destroy) (pthread_cond_t *);
+ int (*ptr___pthread_cond_init) (pthread_cond_t *,
+ const pthread_condattr_t *);
+ int (*ptr___pthread_cond_signal) (pthread_cond_t *);
+ int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
+ int (*ptr___pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
+ const struct timespec *);
+ int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_2_0_t *);
+ int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_2_0_t *);
+ int (*ptr___pthread_cond_init_2_0) (pthread_cond_2_0_t *,
+ const pthread_condattr_t *);
+ int (*ptr___pthread_cond_signal_2_0) (pthread_cond_2_0_t *);
+ int (*ptr___pthread_cond_wait_2_0) (pthread_cond_2_0_t *, pthread_mutex_t *);
+ int (*ptr___pthread_cond_timedwait_2_0) (pthread_cond_2_0_t *,
+ pthread_mutex_t *,
+ const struct timespec *);
+ int (*ptr_pthread_equal) (pthread_t, pthread_t);
+ void (*ptr___pthread_exit) (void *) __attribute__ ((__noreturn__));
+ int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
+ int (*ptr_pthread_setschedparam) (pthread_t, int,
+ const struct sched_param *);
+ int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
+ int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
+ const pthread_mutexattr_t *);
+ int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
+ int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
+ pthread_t (*ptr_pthread_self) (void);
+ int (*ptr___pthread_setcancelstate) (int, int *);
+ int (*ptr_pthread_setcanceltype) (int, int *);
+ void (*ptr___pthread_cleanup_upto) (__jmp_buf, char *);
+ int (*ptr___pthread_once) (pthread_once_t *, void (*) (void));
+ int (*ptr___pthread_rwlock_rdlock) (pthread_rwlock_t *);
+ int (*ptr___pthread_rwlock_wrlock) (pthread_rwlock_t *);
+ int (*ptr___pthread_rwlock_unlock) (pthread_rwlock_t *);
+ int (*ptr___pthread_key_create) (pthread_key_t *, void (*) (void *));
+ void *(*ptr___pthread_getspecific) (pthread_key_t);
+ int (*ptr___pthread_setspecific) (pthread_key_t, const void *);
+ void (*ptr__pthread_cleanup_push_defer) (struct _pthread_cleanup_buffer *,
+ void (*) (void *), void *);
+ void (*ptr__pthread_cleanup_pop_restore) (struct _pthread_cleanup_buffer *,
+ int);
+#define HAVE_PTR_NTHREADS
+ unsigned int *ptr_nthreads;
+ void (*ptr___pthread_unwind) (__pthread_unwind_buf_t *)
+ __attribute ((noreturn)) __cleanup_fct_attribute;
+ void (*ptr__nptl_deallocate_tsd) (void);
+ int (*ptr__nptl_setxid) (struct xid_command *);
+ void (*ptr_freeres) (void);
+ void (*ptr_set_robust) (struct pthread *);
+};
+
+/* Variable in libc.so. */
+extern struct pthread_functions __libc_pthread_functions attribute_hidden;
+extern int __libc_pthread_functions_init attribute_hidden;
+
+#ifdef PTR_DEMANGLE
+# define PTHFCT_CALL(fct, params) \
+ ({ __typeof (__libc_pthread_functions.fct) __p; \
+ __p = __libc_pthread_functions.fct; \
+ PTR_DEMANGLE (__p); \
+ __p params; })
+#else
+# define PTHFCT_CALL(fct, params) \
+ __libc_pthread_functions.fct params
+#endif
+
+#endif /* pthread-functions.h */
diff --git a/REORG.TODO/sysdeps/nptl/pthread.h b/REORG.TODO/sysdeps/nptl/pthread.h
new file mode 100644
index 0000000000..632ea7bc36
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/pthread.h
@@ -0,0 +1,1162 @@
+/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _PTHREAD_H
+#define _PTHREAD_H 1
+
+#include <features.h>
+#include <endian.h>
+#include <sched.h>
+#include <time.h>
+
+#include <bits/pthreadtypes.h>
+#include <bits/setjmp.h>
+#include <bits/wordsize.h>
+#include <bits/types/struct_timespec.h>
+
+
+/* Detach state. */
+enum
+{
+ PTHREAD_CREATE_JOINABLE,
+#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
+ PTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
+};
+
+
+/* Mutex types. */
+enum
+{
+ PTHREAD_MUTEX_TIMED_NP,
+ PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_ADAPTIVE_NP
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
+ ,
+ PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
+ PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+#endif
+#ifdef __USE_GNU
+ /* For compatibility. */
+ , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
+#endif
+};
+
+
+#ifdef __USE_XOPEN2K
+/* Robust mutex or not flags. */
+enum
+{
+ PTHREAD_MUTEX_STALLED,
+ PTHREAD_MUTEX_STALLED_NP = PTHREAD_MUTEX_STALLED,
+ PTHREAD_MUTEX_ROBUST,
+ PTHREAD_MUTEX_ROBUST_NP = PTHREAD_MUTEX_ROBUST
+};
+#endif
+
+
+#if defined __USE_POSIX199506 || defined __USE_UNIX98
+/* Mutex protocols. */
+enum
+{
+ PTHREAD_PRIO_NONE,
+ PTHREAD_PRIO_INHERIT,
+ PTHREAD_PRIO_PROTECT
+};
+#endif
+
+
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+# define PTHREAD_MUTEX_INITIALIZER \
+ { { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } }
+# ifdef __USE_GNU
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, __PTHREAD_SPINS, { 0, 0 } } }
+# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
+
+# endif
+#else
+# define PTHREAD_MUTEX_INITIALIZER \
+ { { 0, 0, 0, 0, 0, { __PTHREAD_SPINS } } }
+# ifdef __USE_GNU
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { __PTHREAD_SPINS } } }
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { __PTHREAD_SPINS } } }
+# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { __PTHREAD_SPINS } } }
+
+# endif
+#endif
+
+
+/* Read-write lock types. */
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+enum
+{
+ PTHREAD_RWLOCK_PREFER_READER_NP,
+ PTHREAD_RWLOCK_PREFER_WRITER_NP,
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
+ PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP
+};
+
+/* Define __PTHREAD_RWLOCK_INT_FLAGS_SHARED to 1 if pthread_rwlock_t
+ has the shared field. All 64-bit architectures have the shared field
+ in pthread_rwlock_t. */
+#ifndef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
+# if __WORDSIZE == 64
+# define __PTHREAD_RWLOCK_INT_FLAGS_SHARED 1
+# endif
+#endif
+
+/* Read-write lock initializers. */
+# define PTHREAD_RWLOCK_INITIALIZER \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, 0 } }
+# ifdef __USE_GNU
+# ifdef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, \
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
+# else
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, \
+ 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, 0 } }
+# else
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
+ 0 } }
+# endif
+# endif
+# endif
+#endif /* Unix98 or XOpen2K */
+
+
+/* Scheduler inheritance. */
+enum
+{
+ PTHREAD_INHERIT_SCHED,
+#define PTHREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED
+ PTHREAD_EXPLICIT_SCHED
+#define PTHREAD_EXPLICIT_SCHED PTHREAD_EXPLICIT_SCHED
+};
+
+
+/* Scope handling. */
+enum
+{
+ PTHREAD_SCOPE_SYSTEM,
+#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM
+ PTHREAD_SCOPE_PROCESS
+#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS
+};
+
+
+/* Process shared or private flag. */
+enum
+{
+ PTHREAD_PROCESS_PRIVATE,
+#define PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
+ PTHREAD_PROCESS_SHARED
+#define PTHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
+};
+
+
+
+/* Conditional variable handling. */
+#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
+
+
+/* Cleanup buffers */
+struct _pthread_cleanup_buffer
+{
+ void (*__routine) (void *); /* Function to call. */
+ void *__arg; /* Its argument. */
+ int __canceltype; /* Saved cancellation type. */
+ struct _pthread_cleanup_buffer *__prev; /* Chaining of cleanup functions. */
+};
+
+/* Cancellation */
+enum
+{
+ PTHREAD_CANCEL_ENABLE,
+#define PTHREAD_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE
+ PTHREAD_CANCEL_DISABLE
+#define PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE
+};
+enum
+{
+ PTHREAD_CANCEL_DEFERRED,
+#define PTHREAD_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED
+ PTHREAD_CANCEL_ASYNCHRONOUS
+#define PTHREAD_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS
+};
+#define PTHREAD_CANCELED ((void *) -1)
+
+
+/* Single execution handling. */
+#define PTHREAD_ONCE_INIT 0
+
+
+#ifdef __USE_XOPEN2K
+/* Value returned by 'pthread_barrier_wait' for one of the threads after
+ the required number of threads have called this function.
+ -1 is distinct from 0 and all errno constants */
+# define PTHREAD_BARRIER_SERIAL_THREAD -1
+#endif
+
+
+__BEGIN_DECLS
+
+/* Create a new thread, starting with execution of START-ROUTINE
+ getting passed ARG. Creation attributed come from ATTR. The new
+ handle is stored in *NEWTHREAD. */
+extern int pthread_create (pthread_t *__restrict __newthread,
+ const pthread_attr_t *__restrict __attr,
+ void *(*__start_routine) (void *),
+ void *__restrict __arg) __THROWNL __nonnull ((1, 3));
+
+/* Terminate calling thread.
+
+ The registered cleanup handlers are called via exception handling
+ so we cannot mark this function with __THROW.*/
+extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__));
+
+/* Make calling thread wait for termination of the thread TH. The
+ exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN
+ is not NULL.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_join (pthread_t __th, void **__thread_return);
+
+#ifdef __USE_GNU
+/* Check whether thread TH has terminated. If yes return the status of
+ the thread in *THREAD_RETURN, if THREAD_RETURN is not NULL. */
+extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW;
+
+/* Make calling thread wait for termination of the thread TH, but only
+ until TIMEOUT. The exit status of the thread is stored in
+ *THREAD_RETURN, if THREAD_RETURN is not NULL.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return,
+ const struct timespec *__abstime);
+#endif
+
+/* Indicate that the thread TH is never to be joined with PTHREAD_JOIN.
+ The resources of TH will therefore be freed immediately when it
+ terminates, instead of waiting for another thread to perform PTHREAD_JOIN
+ on it. */
+extern int pthread_detach (pthread_t __th) __THROW;
+
+
+/* Obtain the identifier of the current thread. */
+extern pthread_t pthread_self (void) __THROW __attribute__ ((__const__));
+
+/* Compare two thread identifiers. */
+extern int pthread_equal (pthread_t __thread1, pthread_t __thread2)
+ __THROW __attribute__ ((__const__));
+
+
+/* Thread attribute handling. */
+
+/* Initialize thread attribute *ATTR with default attributes
+ (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER,
+ no user-provided stack). */
+extern int pthread_attr_init (pthread_attr_t *__attr) __THROW __nonnull ((1));
+
+/* Destroy thread attribute *ATTR. */
+extern int pthread_attr_destroy (pthread_attr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Get detach state attribute. */
+extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr,
+ int *__detachstate)
+ __THROW __nonnull ((1, 2));
+
+/* Set detach state attribute. */
+extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
+ int __detachstate)
+ __THROW __nonnull ((1));
+
+
+/* Get the size of the guard area created for stack overflow protection. */
+extern int pthread_attr_getguardsize (const pthread_attr_t *__attr,
+ size_t *__guardsize)
+ __THROW __nonnull ((1, 2));
+
+/* Set the size of the guard area created for stack overflow protection. */
+extern int pthread_attr_setguardsize (pthread_attr_t *__attr,
+ size_t __guardsize)
+ __THROW __nonnull ((1));
+
+
+/* Return in *PARAM the scheduling parameters of *ATTR. */
+extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr,
+ struct sched_param *__restrict __param)
+ __THROW __nonnull ((1, 2));
+
+/* Set scheduling parameters (priority, etc) in *ATTR according to PARAM. */
+extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
+ const struct sched_param *__restrict
+ __param) __THROW __nonnull ((1, 2));
+
+/* Return in *POLICY the scheduling policy of *ATTR. */
+extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict
+ __attr, int *__restrict __policy)
+ __THROW __nonnull ((1, 2));
+
+/* Set scheduling policy in *ATTR according to POLICY. */
+extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy)
+ __THROW __nonnull ((1));
+
+/* Return in *INHERIT the scheduling inheritance mode of *ATTR. */
+extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict
+ __attr, int *__restrict __inherit)
+ __THROW __nonnull ((1, 2));
+
+/* Set scheduling inheritance mode in *ATTR according to INHERIT. */
+extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
+ int __inherit)
+ __THROW __nonnull ((1));
+
+
+/* Return in *SCOPE the scheduling contention scope of *ATTR. */
+extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr,
+ int *__restrict __scope)
+ __THROW __nonnull ((1, 2));
+
+/* Set scheduling contention scope in *ATTR according to SCOPE. */
+extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope)
+ __THROW __nonnull ((1));
+
+/* Return the previously set address for the stack. */
+extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict
+ __attr, void **__restrict __stackaddr)
+ __THROW __nonnull ((1, 2)) __attribute_deprecated__;
+
+/* Set the starting address of the stack of the thread to be created.
+ Depending on whether the stack grows up or down the value must either
+ be higher or lower than all the address in the memory block. The
+ minimal size of the block must be PTHREAD_STACK_MIN. */
+extern int pthread_attr_setstackaddr (pthread_attr_t *__attr,
+ void *__stackaddr)
+ __THROW __nonnull ((1)) __attribute_deprecated__;
+
+/* Return the currently used minimal stack size. */
+extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict
+ __attr, size_t *__restrict __stacksize)
+ __THROW __nonnull ((1, 2));
+
+/* Add information about the minimum stack size needed for the thread
+ to be started. This size must never be less than PTHREAD_STACK_MIN
+ and must also not exceed the system limits. */
+extern int pthread_attr_setstacksize (pthread_attr_t *__attr,
+ size_t __stacksize)
+ __THROW __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* Return the previously set address for the stack. */
+extern int pthread_attr_getstack (const pthread_attr_t *__restrict __attr,
+ void **__restrict __stackaddr,
+ size_t *__restrict __stacksize)
+ __THROW __nonnull ((1, 2, 3));
+
+/* The following two interfaces are intended to replace the last two. They
+ require setting the address as well as the size since only setting the
+ address will make the implementation on some architectures impossible. */
+extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
+ size_t __stacksize) __THROW __nonnull ((1));
+#endif
+
+#ifdef __USE_GNU
+/* Thread created with attribute ATTR will be limited to run only on
+ the processors represented in CPUSET. */
+extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr,
+ size_t __cpusetsize,
+ const cpu_set_t *__cpuset)
+ __THROW __nonnull ((1, 3));
+
+/* Get bit set in CPUSET representing the processors threads created with
+ ATTR can run on. */
+extern int pthread_attr_getaffinity_np (const pthread_attr_t *__attr,
+ size_t __cpusetsize,
+ cpu_set_t *__cpuset)
+ __THROW __nonnull ((1, 3));
+
+/* Get the default attributes used by pthread_create in this process. */
+extern int pthread_getattr_default_np (pthread_attr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Set the default attributes to be used by pthread_create in this
+ process. */
+extern int pthread_setattr_default_np (const pthread_attr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Initialize thread attribute *ATTR with attributes corresponding to the
+ already running thread TH. It shall be called on uninitialized ATTR
+ and destroyed with pthread_attr_destroy when no longer needed. */
+extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr)
+ __THROW __nonnull ((2));
+#endif
+
+
+/* Functions for scheduling control. */
+
+/* Set the scheduling parameters for TARGET_THREAD according to POLICY
+ and *PARAM. */
+extern int pthread_setschedparam (pthread_t __target_thread, int __policy,
+ const struct sched_param *__param)
+ __THROW __nonnull ((3));
+
+/* Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. */
+extern int pthread_getschedparam (pthread_t __target_thread,
+ int *__restrict __policy,
+ struct sched_param *__restrict __param)
+ __THROW __nonnull ((2, 3));
+
+/* Set the scheduling priority for TARGET_THREAD. */
+extern int pthread_setschedprio (pthread_t __target_thread, int __prio)
+ __THROW;
+
+
+#ifdef __USE_GNU
+/* Get thread name visible in the kernel and its interfaces. */
+extern int pthread_getname_np (pthread_t __target_thread, char *__buf,
+ size_t __buflen)
+ __THROW __nonnull ((2));
+
+/* Set thread name visible in the kernel and its interfaces. */
+extern int pthread_setname_np (pthread_t __target_thread, const char *__name)
+ __THROW __nonnull ((2));
+#endif
+
+
+#ifdef __USE_UNIX98
+/* Determine level of concurrency. */
+extern int pthread_getconcurrency (void) __THROW;
+
+/* Set new concurrency level to LEVEL. */
+extern int pthread_setconcurrency (int __level) __THROW;
+#endif
+
+#ifdef __USE_GNU
+/* Yield the processor to another thread or process.
+ This function is similar to the POSIX `sched_yield' function but
+ might be differently implemented in the case of a m-on-n thread
+ implementation. */
+extern int pthread_yield (void) __THROW;
+
+
+/* Limit specified thread TH to run only on the processors represented
+ in CPUSET. */
+extern int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize,
+ const cpu_set_t *__cpuset)
+ __THROW __nonnull ((3));
+
+/* Get bit set in CPUSET representing the processors TH can run on. */
+extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize,
+ cpu_set_t *__cpuset)
+ __THROW __nonnull ((3));
+#endif
+
+
+/* Functions for handling initialization. */
+
+/* Guarantee that the initialization function INIT_ROUTINE will be called
+ only once, even if pthread_once is executed several times with the
+ same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or
+ extern variable initialized to PTHREAD_ONCE_INIT.
+
+ The initialization functions might throw exception which is why
+ this function is not marked with __THROW. */
+extern int pthread_once (pthread_once_t *__once_control,
+ void (*__init_routine) (void)) __nonnull ((1, 2));
+
+
+/* Functions for handling cancellation.
+
+ Note that these functions are explicitly not marked to not throw an
+ exception in C++ code. If cancellation is implemented by unwinding
+ this is necessary to have the compiler generate the unwind information. */
+
+/* Set cancelability state of current thread to STATE, returning old
+ state in *OLDSTATE if OLDSTATE is not NULL. */
+extern int pthread_setcancelstate (int __state, int *__oldstate);
+
+/* Set cancellation state of current thread to TYPE, returning the old
+ type in *OLDTYPE if OLDTYPE is not NULL. */
+extern int pthread_setcanceltype (int __type, int *__oldtype);
+
+/* Cancel THREAD immediately or at the next possibility. */
+extern int pthread_cancel (pthread_t __th);
+
+/* Test for pending cancellation for the current thread and terminate
+ the thread as per pthread_exit(PTHREAD_CANCELED) if it has been
+ cancelled. */
+extern void pthread_testcancel (void);
+
+
+/* Cancellation handling with integration into exception handling. */
+
+typedef struct
+{
+ struct
+ {
+ __jmp_buf __cancel_jmp_buf;
+ int __mask_was_saved;
+ } __cancel_jmp_buf[1];
+ void *__pad[4];
+} __pthread_unwind_buf_t __attribute__ ((__aligned__));
+
+/* No special attributes by default. */
+#ifndef __cleanup_fct_attribute
+# define __cleanup_fct_attribute
+#endif
+
+
+/* Structure to hold the cleanup handler information. */
+struct __pthread_cleanup_frame
+{
+ void (*__cancel_routine) (void *);
+ void *__cancel_arg;
+ int __do_it;
+ int __cancel_type;
+};
+
+#if defined __GNUC__ && defined __EXCEPTIONS
+# ifdef __cplusplus
+/* Class to handle cancellation handler invocation. */
+class __pthread_cleanup_class
+{
+ void (*__cancel_routine) (void *);
+ void *__cancel_arg;
+ int __do_it;
+ int __cancel_type;
+
+ public:
+ __pthread_cleanup_class (void (*__fct) (void *), void *__arg)
+ : __cancel_routine (__fct), __cancel_arg (__arg), __do_it (1) { }
+ ~__pthread_cleanup_class () { if (__do_it) __cancel_routine (__cancel_arg); }
+ void __setdoit (int __newval) { __do_it = __newval; }
+ void __defer () { pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED,
+ &__cancel_type); }
+ void __restore () const { pthread_setcanceltype (__cancel_type, 0); }
+};
+
+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
+ when the thread is canceled or calls pthread_exit. ROUTINE will also
+ be called with arguments ARG when the matching pthread_cleanup_pop
+ is executed with non-zero EXECUTE argument.
+
+ pthread_cleanup_push and pthread_cleanup_pop are macros and must always
+ be used in matching pairs at the same nesting level of braces. */
+# define pthread_cleanup_push(routine, arg) \
+ do { \
+ __pthread_cleanup_class __clframe (routine, arg)
+
+/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
+ If EXECUTE is non-zero, the handler function is called. */
+# define pthread_cleanup_pop(execute) \
+ __clframe.__setdoit (execute); \
+ } while (0)
+
+# ifdef __USE_GNU
+/* Install a cleanup handler as pthread_cleanup_push does, but also
+ saves the current cancellation type and sets it to deferred
+ cancellation. */
+# define pthread_cleanup_push_defer_np(routine, arg) \
+ do { \
+ __pthread_cleanup_class __clframe (routine, arg); \
+ __clframe.__defer ()
+
+/* Remove a cleanup handler as pthread_cleanup_pop does, but also
+ restores the cancellation type that was in effect when the matching
+ pthread_cleanup_push_defer was called. */
+# define pthread_cleanup_pop_restore_np(execute) \
+ __clframe.__restore (); \
+ __clframe.__setdoit (execute); \
+ } while (0)
+# endif
+# else
+/* Function called to call the cleanup handler. As an extern inline
+ function the compiler is free to decide inlining the change when
+ needed or fall back on the copy which must exist somewhere
+ else. */
+__extern_inline void
+__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
+{
+ if (__frame->__do_it)
+ __frame->__cancel_routine (__frame->__cancel_arg);
+}
+
+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
+ when the thread is canceled or calls pthread_exit. ROUTINE will also
+ be called with arguments ARG when the matching pthread_cleanup_pop
+ is executed with non-zero EXECUTE argument.
+
+ pthread_cleanup_push and pthread_cleanup_pop are macros and must always
+ be used in matching pairs at the same nesting level of braces. */
+# define pthread_cleanup_push(routine, arg) \
+ do { \
+ struct __pthread_cleanup_frame __clframe \
+ __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) \
+ = { .__cancel_routine = (routine), .__cancel_arg = (arg), \
+ .__do_it = 1 };
+
+/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
+ If EXECUTE is non-zero, the handler function is called. */
+# define pthread_cleanup_pop(execute) \
+ __clframe.__do_it = (execute); \
+ } while (0)
+
+# ifdef __USE_GNU
+/* Install a cleanup handler as pthread_cleanup_push does, but also
+ saves the current cancellation type and sets it to deferred
+ cancellation. */
+# define pthread_cleanup_push_defer_np(routine, arg) \
+ do { \
+ struct __pthread_cleanup_frame __clframe \
+ __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) \
+ = { .__cancel_routine = (routine), .__cancel_arg = (arg), \
+ .__do_it = 1 }; \
+ (void) pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, \
+ &__clframe.__cancel_type)
+
+/* Remove a cleanup handler as pthread_cleanup_pop does, but also
+ restores the cancellation type that was in effect when the matching
+ pthread_cleanup_push_defer was called. */
+# define pthread_cleanup_pop_restore_np(execute) \
+ (void) pthread_setcanceltype (__clframe.__cancel_type, NULL); \
+ __clframe.__do_it = (execute); \
+ } while (0)
+# endif
+# endif
+#else
+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
+ when the thread is canceled or calls pthread_exit. ROUTINE will also
+ be called with arguments ARG when the matching pthread_cleanup_pop
+ is executed with non-zero EXECUTE argument.
+
+ pthread_cleanup_push and pthread_cleanup_pop are macros and must always
+ be used in matching pairs at the same nesting level of braces. */
+# define pthread_cleanup_push(routine, arg) \
+ do { \
+ __pthread_unwind_buf_t __cancel_buf; \
+ void (*__cancel_routine) (void *) = (routine); \
+ void *__cancel_arg = (arg); \
+ int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
+ __cancel_buf.__cancel_jmp_buf, 0); \
+ if (__glibc_unlikely (__not_first_call)) \
+ { \
+ __cancel_routine (__cancel_arg); \
+ __pthread_unwind_next (&__cancel_buf); \
+ /* NOTREACHED */ \
+ } \
+ \
+ __pthread_register_cancel (&__cancel_buf); \
+ do {
+extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+
+/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
+ If EXECUTE is non-zero, the handler function is called. */
+# define pthread_cleanup_pop(execute) \
+ do { } while (0);/* Empty to allow label before pthread_cleanup_pop. */\
+ } while (0); \
+ __pthread_unregister_cancel (&__cancel_buf); \
+ if (execute) \
+ __cancel_routine (__cancel_arg); \
+ } while (0)
+extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+
+# ifdef __USE_GNU
+/* Install a cleanup handler as pthread_cleanup_push does, but also
+ saves the current cancellation type and sets it to deferred
+ cancellation. */
+# define pthread_cleanup_push_defer_np(routine, arg) \
+ do { \
+ __pthread_unwind_buf_t __cancel_buf; \
+ void (*__cancel_routine) (void *) = (routine); \
+ void *__cancel_arg = (arg); \
+ int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
+ __cancel_buf.__cancel_jmp_buf, 0); \
+ if (__glibc_unlikely (__not_first_call)) \
+ { \
+ __cancel_routine (__cancel_arg); \
+ __pthread_unwind_next (&__cancel_buf); \
+ /* NOTREACHED */ \
+ } \
+ \
+ __pthread_register_cancel_defer (&__cancel_buf); \
+ do {
+extern void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+
+/* Remove a cleanup handler as pthread_cleanup_pop does, but also
+ restores the cancellation type that was in effect when the matching
+ pthread_cleanup_push_defer was called. */
+# define pthread_cleanup_pop_restore_np(execute) \
+ do { } while (0);/* Empty to allow label before pthread_cleanup_pop. */\
+ } while (0); \
+ __pthread_unregister_cancel_restore (&__cancel_buf); \
+ if (execute) \
+ __cancel_routine (__cancel_arg); \
+ } while (0)
+extern void __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+# endif
+
+/* Internal interface to initiate cleanup. */
+extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute __attribute__ ((__noreturn__))
+# ifndef SHARED
+ __attribute__ ((__weak__))
+# endif
+ ;
+#endif
+
+/* Function used in the macros. */
+struct __jmp_buf_tag;
+extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROWNL;
+
+
+/* Mutex handling. */
+
+/* Initialize a mutex. */
+extern int pthread_mutex_init (pthread_mutex_t *__mutex,
+ const pthread_mutexattr_t *__mutexattr)
+ __THROW __nonnull ((1));
+
+/* Destroy a mutex. */
+extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
+ __THROW __nonnull ((1));
+
+/* Try locking a mutex. */
+extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
+ __THROWNL __nonnull ((1));
+
+/* Lock a mutex. */
+extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
+ __THROWNL __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* Wait until lock becomes available, or specified time passes. */
+extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
+ const struct timespec *__restrict
+ __abstime) __THROWNL __nonnull ((1, 2));
+#endif
+
+/* Unlock a mutex. */
+extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
+ __THROWNL __nonnull ((1));
+
+
+/* Get the priority ceiling of MUTEX. */
+extern int pthread_mutex_getprioceiling (const pthread_mutex_t *
+ __restrict __mutex,
+ int *__restrict __prioceiling)
+ __THROW __nonnull ((1, 2));
+
+/* Set the priority ceiling of MUTEX to PRIOCEILING, return old
+ priority ceiling value in *OLD_CEILING. */
+extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex,
+ int __prioceiling,
+ int *__restrict __old_ceiling)
+ __THROW __nonnull ((1, 3));
+
+
+#ifdef __USE_XOPEN2K8
+/* Declare the state protected by MUTEX as consistent. */
+extern int pthread_mutex_consistent (pthread_mutex_t *__mutex)
+ __THROW __nonnull ((1));
+# ifdef __USE_GNU
+extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex)
+ __THROW __nonnull ((1));
+# endif
+#endif
+
+
+/* Functions for handling mutex attributes. */
+
+/* Initialize mutex attribute object ATTR with default attributes
+ (kind is PTHREAD_MUTEX_TIMED_NP). */
+extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Destroy mutex attribute object ATTR. */
+extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Get the process-shared flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getpshared (const pthread_mutexattr_t *
+ __restrict __attr,
+ int *__restrict __pshared)
+ __THROW __nonnull ((1, 2));
+
+/* Set the process-shared flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
+ int __pshared)
+ __THROW __nonnull ((1));
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
+/* Return in *KIND the mutex kind attribute in *ATTR. */
+extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict
+ __attr, int *__restrict __kind)
+ __THROW __nonnull ((1, 2));
+
+/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
+ PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
+ PTHREAD_MUTEX_DEFAULT). */
+extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
+ __THROW __nonnull ((1));
+#endif
+
+/* Return in *PROTOCOL the mutex protocol attribute in *ATTR. */
+extern int pthread_mutexattr_getprotocol (const pthread_mutexattr_t *
+ __restrict __attr,
+ int *__restrict __protocol)
+ __THROW __nonnull ((1, 2));
+
+/* Set the mutex protocol attribute in *ATTR to PROTOCOL (either
+ PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, or PTHREAD_PRIO_PROTECT). */
+extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
+ int __protocol)
+ __THROW __nonnull ((1));
+
+/* Return in *PRIOCEILING the mutex prioceiling attribute in *ATTR. */
+extern int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *
+ __restrict __attr,
+ int *__restrict __prioceiling)
+ __THROW __nonnull ((1, 2));
+
+/* Set the mutex prioceiling attribute in *ATTR to PRIOCEILING. */
+extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr,
+ int __prioceiling)
+ __THROW __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* Get the robustness flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr,
+ int *__robustness)
+ __THROW __nonnull ((1, 2));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr,
+ int *__robustness)
+ __THROW __nonnull ((1, 2));
+# endif
+
+/* Set the robustness flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
+ int __robustness)
+ __THROW __nonnull ((1));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+ int __robustness)
+ __THROW __nonnull ((1));
+# endif
+#endif
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Functions for handling read-write locks. */
+
+/* Initialize read-write lock RWLOCK using attributes ATTR, or use
+ the default values if later is NULL. */
+extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
+ const pthread_rwlockattr_t *__restrict
+ __attr) __THROW __nonnull ((1));
+
+/* Destroy read-write lock RWLOCK. */
+extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
+ __THROW __nonnull ((1));
+
+/* Acquire read lock for RWLOCK. */
+extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+/* Try to acquire read lock for RWLOCK. */
+extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+# ifdef __USE_XOPEN2K
+/* Try to acquire read lock for RWLOCK or return after specfied time. */
+extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
+ const struct timespec *__restrict
+ __abstime) __THROWNL __nonnull ((1, 2));
+# endif
+
+/* Acquire write lock for RWLOCK. */
+extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+/* Try to acquire write lock for RWLOCK. */
+extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+# ifdef __USE_XOPEN2K
+/* Try to acquire write lock for RWLOCK or return after specfied time. */
+extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
+ const struct timespec *__restrict
+ __abstime) __THROWNL __nonnull ((1, 2));
+# endif
+
+/* Unlock RWLOCK. */
+extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+
+/* Functions for handling read-write lock attributes. */
+
+/* Initialize attribute object ATTR with default values. */
+extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Destroy attribute object ATTR. */
+extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Return current setting of process-shared attribute of ATTR in PSHARED. */
+extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *
+ __restrict __attr,
+ int *__restrict __pshared)
+ __THROW __nonnull ((1, 2));
+
+/* Set process-shared attribute of ATTR to PSHARED. */
+extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr,
+ int __pshared)
+ __THROW __nonnull ((1));
+
+/* Return current setting of reader/writer preference. */
+extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *
+ __restrict __attr,
+ int *__restrict __pref)
+ __THROW __nonnull ((1, 2));
+
+/* Set reader/write preference. */
+extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
+ int __pref) __THROW __nonnull ((1));
+#endif
+
+
+/* Functions for handling conditional variables. */
+
+/* Initialize condition variable COND using attributes ATTR, or use
+ the default values if later is NULL. */
+extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
+ const pthread_condattr_t *__restrict __cond_attr)
+ __THROW __nonnull ((1));
+
+/* Destroy condition variable COND. */
+extern int pthread_cond_destroy (pthread_cond_t *__cond)
+ __THROW __nonnull ((1));
+
+/* Wake up one thread waiting for condition variable COND. */
+extern int pthread_cond_signal (pthread_cond_t *__cond)
+ __THROWNL __nonnull ((1));
+
+/* Wake up all threads waiting for condition variables COND. */
+extern int pthread_cond_broadcast (pthread_cond_t *__cond)
+ __THROWNL __nonnull ((1));
+
+/* Wait for condition variable COND to be signaled or broadcast.
+ MUTEX is assumed to be locked before.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex)
+ __nonnull ((1, 2));
+
+/* Wait for condition variable COND to be signaled or broadcast until
+ ABSTIME. MUTEX is assumed to be locked before. ABSTIME is an
+ absolute time specification; zero is the beginning of the epoch
+ (00:00:00 GMT, January 1, 1970).
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex,
+ const struct timespec *__restrict __abstime)
+ __nonnull ((1, 2, 3));
+
+/* Functions for handling condition variable attributes. */
+
+/* Initialize condition variable attribute ATTR. */
+extern int pthread_condattr_init (pthread_condattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Destroy condition variable attribute ATTR. */
+extern int pthread_condattr_destroy (pthread_condattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Get the process-shared flag of the condition variable attribute ATTR. */
+extern int pthread_condattr_getpshared (const pthread_condattr_t *
+ __restrict __attr,
+ int *__restrict __pshared)
+ __THROW __nonnull ((1, 2));
+
+/* Set the process-shared flag of the condition variable attribute ATTR. */
+extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
+ int __pshared) __THROW __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* Get the clock selected for the condition variable attribute ATTR. */
+extern int pthread_condattr_getclock (const pthread_condattr_t *
+ __restrict __attr,
+ __clockid_t *__restrict __clock_id)
+ __THROW __nonnull ((1, 2));
+
+/* Set the clock selected for the condition variable attribute ATTR. */
+extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
+ __clockid_t __clock_id)
+ __THROW __nonnull ((1));
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* Functions to handle spinlocks. */
+
+/* Initialize the spinlock LOCK. If PSHARED is nonzero the spinlock can
+ be shared between different processes. */
+extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
+ __THROW __nonnull ((1));
+
+/* Destroy the spinlock LOCK. */
+extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
+ __THROW __nonnull ((1));
+
+/* Wait until spinlock LOCK is retrieved. */
+extern int pthread_spin_lock (pthread_spinlock_t *__lock)
+ __THROWNL __nonnull ((1));
+
+/* Try to lock spinlock LOCK. */
+extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
+ __THROWNL __nonnull ((1));
+
+/* Release spinlock LOCK. */
+extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
+ __THROWNL __nonnull ((1));
+
+
+/* Functions to handle barriers. */
+
+/* Initialize BARRIER with the attributes in ATTR. The barrier is
+ opened when COUNT waiters arrived. */
+extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier,
+ const pthread_barrierattr_t *__restrict
+ __attr, unsigned int __count)
+ __THROW __nonnull ((1));
+
+/* Destroy a previously dynamically initialized barrier BARRIER. */
+extern int pthread_barrier_destroy (pthread_barrier_t *__barrier)
+ __THROW __nonnull ((1));
+
+/* Wait on barrier BARRIER. */
+extern int pthread_barrier_wait (pthread_barrier_t *__barrier)
+ __THROWNL __nonnull ((1));
+
+
+/* Initialize barrier attribute ATTR. */
+extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Destroy previously dynamically initialized barrier attribute ATTR. */
+extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Get the process-shared flag of the barrier attribute ATTR. */
+extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *
+ __restrict __attr,
+ int *__restrict __pshared)
+ __THROW __nonnull ((1, 2));
+
+/* Set the process-shared flag of the barrier attribute ATTR. */
+extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
+ int __pshared)
+ __THROW __nonnull ((1));
+#endif
+
+
+/* Functions for handling thread-specific data. */
+
+/* Create a key value identifying a location in the thread-specific
+ data area. Each thread maintains a distinct thread-specific data
+ area. DESTR_FUNCTION, if non-NULL, is called with the value
+ associated to that key when the key is destroyed.
+ DESTR_FUNCTION is not called if the value associated is NULL when
+ the key is destroyed. */
+extern int pthread_key_create (pthread_key_t *__key,
+ void (*__destr_function) (void *))
+ __THROW __nonnull ((1));
+
+/* Destroy KEY. */
+extern int pthread_key_delete (pthread_key_t __key) __THROW;
+
+/* Return current value of the thread-specific data slot identified by KEY. */
+extern void *pthread_getspecific (pthread_key_t __key) __THROW;
+
+/* Store POINTER in the thread-specific data slot identified by KEY. */
+extern int pthread_setspecific (pthread_key_t __key,
+ const void *__pointer) __THROW ;
+
+
+#ifdef __USE_XOPEN2K
+/* Get ID of CPU-time clock for thread THREAD_ID. */
+extern int pthread_getcpuclockid (pthread_t __thread_id,
+ __clockid_t *__clock_id)
+ __THROW __nonnull ((2));
+#endif
+
+
+/* Install handlers to be called when a new process is created with FORK.
+ The PREPARE handler is called in the parent process just before performing
+ FORK. The PARENT handler is called in the parent process just after FORK.
+ The CHILD handler is called in the child process. Each of the three
+ handlers can be NULL, meaning that no handler needs to be called at that
+ point.
+ PTHREAD_ATFORK can be called several times, in which case the PREPARE
+ handlers are called in LIFO order (last added with PTHREAD_ATFORK,
+ first called before FORK), and the PARENT and CHILD handlers are called
+ in FIFO (first added, first called). */
+
+extern int pthread_atfork (void (*__prepare) (void),
+ void (*__parent) (void),
+ void (*__child) (void)) __THROW;
+
+
+#ifdef __USE_EXTERN_INLINES
+/* Optimizations. */
+__extern_inline int
+__NTH (pthread_equal (pthread_t __thread1, pthread_t __thread2))
+{
+ return __thread1 == __thread2;
+}
+#endif
+
+__END_DECLS
+
+#endif /* pthread.h */
diff --git a/REORG.TODO/sysdeps/nptl/setxid.h b/REORG.TODO/sysdeps/nptl/setxid.h
new file mode 100644
index 0000000000..7db1687439
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/setxid.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <nptl/pthreadP.h>
+#include <sysdep.h>
+
+#define __SETXID_1(cmd, arg1) \
+ cmd.id[0] = (long int) arg1
+#define __SETXID_2(cmd, arg1, arg2) \
+ __SETXID_1 (cmd, arg1); cmd.id[1] = (long int) arg2
+#define __SETXID_3(cmd, arg1, arg2, arg3) \
+ __SETXID_2 (cmd, arg1, arg2); cmd.id[2] = (long int) arg3
+
+#ifdef SINGLE_THREAD
+# define INLINE_SETXID_SYSCALL(name, nr, args...) \
+ INLINE_SYSCALL (name, nr, args)
+#elif defined SHARED
+# define INLINE_SETXID_SYSCALL(name, nr, args...) \
+ ({ \
+ int __result; \
+ if (__builtin_expect (__libc_pthread_functions_init, 0)) \
+ { \
+ struct xid_command __cmd; \
+ __cmd.syscall_no = __NR_##name; \
+ __SETXID_##nr (__cmd, args); \
+ __result = PTHFCT_CALL (ptr__nptl_setxid, (&__cmd)); \
+ } \
+ else \
+ __result = INLINE_SYSCALL (name, nr, args); \
+ __result; \
+ })
+#else
+# define INLINE_SETXID_SYSCALL(name, nr, args...) \
+ ({ \
+ extern __typeof (__nptl_setxid) __nptl_setxid __attribute__((weak));\
+ int __result; \
+ if (__glibc_unlikely (__nptl_setxid != NULL)) \
+ { \
+ struct xid_command __cmd; \
+ __cmd.syscall_no = __NR_##name; \
+ __SETXID_##nr (__cmd, args); \
+ __result =__nptl_setxid (&__cmd); \
+ } \
+ else \
+ __result = INLINE_SYSCALL (name, nr, args); \
+ __result; \
+ })
+#endif
diff --git a/REORG.TODO/sysdeps/nptl/shm-directory.h b/REORG.TODO/sysdeps/nptl/shm-directory.h
new file mode 100644
index 0000000000..a7f09f51ea
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/shm-directory.h
@@ -0,0 +1,31 @@
+/* Header for directory for shm/sem files. NPTL version.
+ Copyright (C) 2014-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SHM_DIRECTORY_H
+
+#include <sysdeps/posix/shm-directory.h>
+
+/* For NPTL the __shm_directory function lives in libpthread.
+ We don't want PLT calls from there. But it's also used from
+ librt, so it cannot just be declared hidden. */
+
+#if IS_IN (libpthread)
+hidden_proto (__shm_directory)
+#endif
+
+#endif /* shm-directory.h */
diff --git a/REORG.TODO/sysdeps/nptl/sigfillset.c b/REORG.TODO/sysdeps/nptl/sigfillset.c
new file mode 100644
index 0000000000..50e8512de0
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/sigfillset.c
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <nptl/pthreadP.h>
+
+#include <signal/sigfillset.c>
diff --git a/REORG.TODO/sysdeps/nptl/stdio-lock.h b/REORG.TODO/sysdeps/nptl/stdio-lock.h
new file mode 100644
index 0000000000..df749062ea
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/stdio-lock.h
@@ -0,0 +1,111 @@
+/* Thread package specific definitions of stream lock type. NPTL version.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the 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 _STDIO_LOCK_H
+#define _STDIO_LOCK_H 1
+
+#include <libc-lock.h>
+#include <lowlevellock.h>
+
+
+/* The locking here is very inexpensive, even for inlining. */
+#define _IO_lock_inexpensive 1
+
+typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
+#define _IO_lock_t_defined 1
+
+#define _IO_lock_initializer { LLL_LOCK_INITIALIZER, 0, NULL }
+
+#define _IO_lock_init(_name) \
+ ((void) ((_name) = (_IO_lock_t) _IO_lock_initializer))
+
+#define _IO_lock_fini(_name) \
+ ((void) 0)
+
+#define _IO_lock_lock(_name) \
+ do { \
+ void *__self = THREAD_SELF; \
+ if ((_name).owner != __self) \
+ { \
+ lll_lock ((_name).lock, LLL_PRIVATE); \
+ (_name).owner = __self; \
+ } \
+ ++(_name).cnt; \
+ } while (0)
+
+#define _IO_lock_trylock(_name) \
+ ({ \
+ int __result = 0; \
+ void *__self = THREAD_SELF; \
+ if ((_name).owner != __self) \
+ { \
+ if (lll_trylock ((_name).lock) == 0) \
+ { \
+ (_name).owner = __self; \
+ (_name).cnt = 1; \
+ } \
+ else \
+ __result = EBUSY; \
+ } \
+ else \
+ ++(_name).cnt; \
+ __result; \
+ })
+
+#define _IO_lock_unlock(_name) \
+ do { \
+ if (--(_name).cnt == 0) \
+ { \
+ (_name).owner = NULL; \
+ lll_unlock ((_name).lock, LLL_PRIVATE); \
+ } \
+ } while (0)
+
+
+
+#define _IO_cleanup_region_start(_fct, _fp) \
+ __libc_cleanup_region_start (((_fp)->_flags & _IO_USER_LOCK) == 0, _fct, _fp)
+#define _IO_cleanup_region_start_noarg(_fct) \
+ __libc_cleanup_region_start (1, _fct, NULL)
+#define _IO_cleanup_region_end(_doit) \
+ __libc_cleanup_region_end (_doit)
+
+#if defined _LIBC && IS_IN (libc)
+
+# ifdef __EXCEPTIONS
+# define _IO_acquire_lock(_fp) \
+ do { \
+ _IO_FILE *_IO_acquire_lock_file \
+ __attribute__((cleanup (_IO_acquire_lock_fct))) \
+ = (_fp); \
+ _IO_flockfile (_IO_acquire_lock_file);
+# define _IO_acquire_lock_clear_flags2(_fp) \
+ do { \
+ _IO_FILE *_IO_acquire_lock_file \
+ __attribute__((cleanup (_IO_acquire_lock_clear_flags2_fct))) \
+ = (_fp); \
+ _IO_flockfile (_IO_acquire_lock_file);
+# else
+# define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled
+# define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp)
+# endif
+# define _IO_release_lock(_fp) ; } while (0)
+
+#endif
+
+#endif /* stdio-lock.h */
diff --git a/REORG.TODO/sysdeps/nptl/sys/procfs.h b/REORG.TODO/sysdeps/nptl/sys/procfs.h
new file mode 100644
index 0000000000..785953835e
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/sys/procfs.h
@@ -0,0 +1,39 @@
+/* Types used by thread_db callback interface. Stub version.
+ Copyright (C) 2015-2017 Free Software Foundation, Inc.
+ This file is part of the 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 _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+#include <sys/types.h>
+
+/* The rest of this file provides the types for emulation of the
+ Solaris <proc_service.h> interfaces that should be implemented by
+ users of libthread_db. */
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register set types used in thread_db interface. */
+typedef struct prregset prgregset_t;
+typedef struct prfpregset prfpregset_t;
+
+/* Type used for lightweight-process (i.e. thread) IDs. */
+typedef __pid_t lwpid_t;
+
+
+#endif /* sys/procfs.h */
diff --git a/REORG.TODO/sysdeps/nptl/tcb-offsets.h b/REORG.TODO/sysdeps/nptl/tcb-offsets.h
new file mode 100644
index 0000000000..3fe13702ea
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/tcb-offsets.h
@@ -0,0 +1 @@
+/* This is overridden by generated tcb-offsets.h on arches which need it. */
diff --git a/REORG.TODO/sysdeps/nptl/tst-mqueue8x.c b/REORG.TODO/sysdeps/nptl/tst-mqueue8x.c
new file mode 100644
index 0000000000..ca280394f7
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/tst-mqueue8x.c
@@ -0,0 +1 @@
+#include <rt/tst-mqueue8.c>
diff --git a/REORG.TODO/sysdeps/nptl/unwind-forcedunwind.c b/REORG.TODO/sysdeps/nptl/unwind-forcedunwind.c
new file mode 100644
index 0000000000..33a1975f5e
--- /dev/null
+++ b/REORG.TODO/sysdeps/nptl/unwind-forcedunwind.c
@@ -0,0 +1,148 @@
+/* Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unwind.h>
+#include <pthreadP.h>
+#include <sysdep.h>
+#include <gnu/lib-names.h>
+#include <unwind-resume.h>
+
+static void *libgcc_s_handle;
+void (*__libgcc_s_resume) (struct _Unwind_Exception *exc)
+ attribute_hidden __attribute__ ((noreturn));
+static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO;
+static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
+ (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
+
+void
+__attribute_noinline__
+pthread_cancel_init (void)
+{
+ void *resume;
+ void *personality;
+ void *forcedunwind;
+ void *getcfa;
+ void *handle;
+
+ if (__glibc_likely (libgcc_s_handle != NULL))
+ {
+ /* Force gcc to reload all values. */
+ asm volatile ("" ::: "memory");
+ return;
+ }
+
+ handle = __libc_dlopen (LIBGCC_S_SO);
+
+ if (handle == NULL
+ || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
+ || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
+ || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
+ == NULL
+ || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
+#ifdef ARCH_CANCEL_INIT
+ || ARCH_CANCEL_INIT (handle)
+#endif
+ )
+ __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
+
+ PTR_MANGLE (resume);
+ __libgcc_s_resume = resume;
+ PTR_MANGLE (personality);
+ libgcc_s_personality = personality;
+ PTR_MANGLE (forcedunwind);
+ libgcc_s_forcedunwind = forcedunwind;
+ PTR_MANGLE (getcfa);
+ libgcc_s_getcfa = getcfa;
+ /* Make sure libgcc_s_handle is written last. Otherwise,
+ pthread_cancel_init might return early even when the pointer the
+ caller is interested in is not initialized yet. */
+ atomic_write_barrier ();
+ libgcc_s_handle = handle;
+}
+
+void
+__libc_freeres_fn_section
+__unwind_freeres (void)
+{
+ void *handle = libgcc_s_handle;
+ if (handle != NULL)
+ {
+ libgcc_s_handle = NULL;
+ __libc_dlclose (handle);
+ }
+}
+
+#if !HAVE_ARCH_UNWIND_RESUME
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+ if (__glibc_unlikely (libgcc_s_handle == NULL))
+ pthread_cancel_init ();
+ else
+ atomic_read_barrier ();
+
+ void (*resume) (struct _Unwind_Exception *exc) = __libgcc_s_resume;
+ PTR_DEMANGLE (resume);
+ resume (exc);
+}
+#endif
+
+_Unwind_Reason_Code
+__gcc_personality_v0 PERSONALITY_PROTO
+{
+ if (__glibc_unlikely (libgcc_s_handle == NULL))
+ pthread_cancel_init ();
+ else
+ atomic_read_barrier ();
+
+ __typeof (libgcc_s_personality) personality = libgcc_s_personality;
+ PTR_DEMANGLE (personality);
+ return (*personality) PERSONALITY_ARGS;
+}
+
+_Unwind_Reason_Code
+_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
+ void *stop_argument)
+{
+ if (__glibc_unlikely (libgcc_s_handle == NULL))
+ pthread_cancel_init ();
+ else
+ atomic_read_barrier ();
+
+ _Unwind_Reason_Code (*forcedunwind)
+ (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *)
+ = libgcc_s_forcedunwind;
+ PTR_DEMANGLE (forcedunwind);
+ return forcedunwind (exc, stop, stop_argument);
+}
+
+_Unwind_Word
+_Unwind_GetCFA (struct _Unwind_Context *context)
+{
+ if (__glibc_unlikely (libgcc_s_handle == NULL))
+ pthread_cancel_init ();
+ else
+ atomic_read_barrier ();
+
+ _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa;
+ PTR_DEMANGLE (getcfa);
+ return getcfa (context);
+}