]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - nptl/pthread_create.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / nptl / pthread_create.c
index b1253b2243fdc4cd243d8d495ceea6e2ffafbdc7..2bd2b10727812f277e51fa0b681a7b802f18516f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    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, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
+#include <ctype.h>
 #include <errno.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 #include "pthreadP.h"
 #include <hp-timing.h>
 #include <ldsodefs.h>
 #include <atomic.h>
 #include <libc-internal.h>
 #include <resolv.h>
+#include <kernel-features.h>
+#include <exit-thread.h>
+#include <default-sched.h>
+#include <futex-internal.h>
+#include <tls-setup.h>
+#include "libioP.h"
 
 #include <shlib-compat.h>
 
-
-/* Local function to start thread and handle cleanup.  */
-static int start_thread (void *arg);
+#include <stap-probe.h>
 
 
 /* Nozero if debugging mode is enabled.  */
 int __pthread_debug;
 
 /* Globally enabled events.  */
-static td_thr_events_t __nptl_threads_events;
+static td_thr_events_t __nptl_threads_events __attribute_used__;
 
 /* Pointer to descriptor with the last event.  */
-static struct pthread *__nptl_last_event;
+static struct pthread *__nptl_last_event __attribute_used__;
 
 /* Number of threads running.  */
 unsigned int __nptl_nthreads = 1;
@@ -51,19 +56,162 @@ unsigned int __nptl_nthreads = 1;
 /* Code to allocate and deallocate a stack.  */
 #include "allocatestack.c"
 
-/* Code to create the thread.  */
+/* CONCURRENCY NOTES:
+
+   Understanding who is the owner of the 'struct pthread' or 'PD'
+   (refers to the value of the 'struct pthread *pd' function argument)
+   is critically important in determining exactly which operations are
+   allowed and which are not and when, particularly when it comes to the
+   implementation of pthread_create, pthread_join, pthread_detach, and
+   other functions which all operate on PD.
+
+   The owner of PD is responsible for freeing the final resources
+   associated with PD, and may examine the memory underlying PD at any
+   point in time until it frees it back to the OS or to reuse by the
+   runtime.
+
+   The thread which calls pthread_create is called the creating thread.
+   The creating thread begins as the owner of PD.
+
+   During startup the new thread may examine PD in coordination with the
+   owner thread (which may be itself).
+
+   The four cases of ownership transfer are:
+
+   (1) Ownership of PD is released to the process (all threads may use it)
+       after the new thread starts in a joinable state
+       i.e. pthread_create returns a usable pthread_t.
+
+   (2) Ownership of PD is released to the new thread starting in a detached
+       state.
+
+   (3) Ownership of PD is dynamically released to a running thread via
+       pthread_detach.
+
+   (4) Ownership of PD is acquired by the thread which calls pthread_join.
+
+   Implementation notes:
+
+   The PD->stopped_start and thread_ran variables are used to determine
+   exactly which of the four ownership states we are in and therefore
+   what actions can be taken.  For example after (2) we cannot read or
+   write from PD anymore since the thread may no longer exist and the
+   memory may be unmapped.
+
+   It is important to point out that PD->lock is being used both
+   similar to a one-shot semaphore and subsequently as a mutex.  The
+   lock is taken in the parent to force the child to wait, and then the
+   child releases the lock.  However, this semaphore-like effect is used
+   only for synchronizing the parent and child.  After startup the lock
+   is used like a mutex to create a critical section during which a
+   single owner modifies the thread parameters.
+
+   The most complicated cases happen during thread startup:
+
+   (a) If the created thread is in a detached (PTHREAD_CREATE_DETACHED),
+       or joinable (default PTHREAD_CREATE_JOINABLE) state and
+       STOPPED_START is true, then the creating thread has ownership of
+       PD until the PD->lock is released by pthread_create.  If any
+       errors occur we are in states (c), (d), or (e) below.
+
+   (b) If the created thread is in a detached state
+       (PTHREAD_CREATED_DETACHED), and STOPPED_START is false, then the
+       creating thread has ownership of PD until it invokes the OS
+       kernel's thread creation routine.  If this routine returns
+       without error, then the created thread owns PD; otherwise, see
+       (c) and (e) below.
+
+   (c) If the detached thread setup failed and THREAD_RAN is true, then
+       the creating thread releases ownership to the new thread by
+       sending a cancellation signal.  All threads set THREAD_RAN to
+       true as quickly as possible after returning from the OS kernel's
+       thread creation routine.
+
+   (d) If the joinable thread setup failed and THREAD_RAN is true, then
+       then the creating thread retains ownership of PD and must cleanup
+       state.  Ownership cannot be released to the process via the
+       return of pthread_create since a non-zero result entails PD is
+       undefined and therefore cannot be joined to free the resources.
+       We privately call pthread_join on the thread to finish handling
+       the resource shutdown (Or at least we should, see bug 19511).
+
+   (e) If the thread creation failed and THREAD_RAN is false, then the
+       creating thread retains ownership of PD and must cleanup state.
+       No waiting for the new thread is required because it never
+       started.
+
+   The nptl_db interface:
+
+   The interface with nptl_db requires that we enqueue PD into a linked
+   list and then call a function which the debugger will trap.  The PD
+   will then be dequeued and control returned to the thread.  The caller
+   at the time must have ownership of PD and such ownership remains
+   after control returns to thread. The enqueued PD is removed from the
+   linked list by the nptl_db callback td_thr_event_getmsg.  The debugger
+   must ensure that the thread does not resume execution, otherwise
+   ownership of PD may be lost and examining PD will not be possible.
+
+   Note that the GNU Debugger as of (December 10th 2015) commit
+   c2c2a31fdb228d41ce3db62b268efea04bd39c18 no longer uses
+   td_thr_event_getmsg and several other related nptl_db interfaces. The
+   principal reason for this is that nptl_db does not support non-stop
+   mode where other threads can run concurrently and modify runtime
+   structures currently in use by the debugger and the nptl_db
+   interface.
+
+   Axioms:
+
+   * The create_thread function can never set stopped_start to false.
+   * The created thread can read stopped_start but never write to it.
+   * The variable thread_ran is set some time after the OS thread
+     creation routine returns, how much time after the thread is created
+     is unspecified, but it should be as quickly as possible.
+
+*/
+
+/* CREATE THREAD NOTES:
+
+   createthread.c defines the create_thread function, and two macros:
+   START_THREAD_DEFN and START_THREAD_SELF (see below).
+
+   create_thread must initialize PD->stopped_start.  It should be true
+   if the STOPPED_START parameter is true, or if create_thread needs the
+   new thread to synchronize at startup for some other implementation
+   reason.  If STOPPED_START will be true, then create_thread is obliged
+   to lock PD->lock before starting the thread.  Then pthread_create
+   unlocks PD->lock which synchronizes-with START_THREAD_DEFN in the
+   child thread which does an acquire/release of PD->lock as the last
+   action before calling the user entry point.  The goal of all of this
+   is to ensure that the required initial thread attributes are applied
+   (by the creating thread) before the new thread runs user code.  Note
+   that the the functions pthread_getschedparam, pthread_setschedparam,
+   pthread_setschedprio, __pthread_tpp_change_priority, and
+   __pthread_current_priority reuse the same lock, PD->lock, for a
+   similar purpose e.g. synchronizing the setting of similar thread
+   attributes.  These functions are never called before the thread is
+   created, so don't participate in startup syncronization, but given
+   that the lock is present already and in the unlocked state, reusing
+   it saves space.
+
+   The return value is zero for success or an errno code for failure.
+   If the return value is ENOMEM, that will be translated to EAGAIN,
+   so create_thread need not do that.  On failure, *THREAD_RAN should
+   be set to true iff the thread actually started up and then got
+   canceled before calling user code (*PD->start_routine).  */
+static int create_thread (struct pthread *pd, const struct pthread_attr *attr,
+                         bool *stopped_start, STACK_VARIABLES_PARMS,
+                         bool *thread_ran);
+
 #include <createthread.c>
 
 
 struct pthread *
-internal_function
-__find_in_stack_list (pd)
-     struct pthread *pd;
+__find_in_stack_list (struct pthread *pd)
 {
   list_t *entry;
   struct pthread *result = NULL;
 
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   list_for_each (entry, &stack_used)
     {
@@ -90,7 +238,7 @@ __find_in_stack_list (pd)
          }
       }
 
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
   return result;
 }
@@ -193,7 +341,6 @@ __nptl_deallocate_tsd (void)
 /* Deallocate a thread's stack after optionally making sure the thread
    descriptor is still valid.  */
 void
-internal_function
 __free_tcb (struct pthread *pd)
 {
   /* The thread is exiting now.  */
@@ -206,6 +353,15 @@ __free_tcb (struct pthread *pd)
           running thread is gone.  */
        abort ();
 
+      /* Free TPP data.  */
+      if (__glibc_unlikely (pd->tpp != NULL))
+       {
+         struct priority_protection_data *tpp = pd->tpp;
+
+         pd->tpp = NULL;
+         free (tpp);
+       }
+
       /* Queue the stack memory block for reuse and exit the process.  The
         kernel will signal via writing to the address returned by
         QUEUE-STACK when the stack is available.  */
@@ -214,10 +370,14 @@ __free_tcb (struct pthread *pd)
 }
 
 
-static int
-start_thread (void *arg)
+/* Local function to start thread and handle cleanup.
+   createthread.c defines the macro START_THREAD_DEFN to the
+   declaration that its create_thread function will refer to, and
+   START_THREAD_SELF to the expression to optimally deliver the new
+   thread's THREAD_SELF value.  */
+START_THREAD_DEFN
 {
-  struct pthread *pd = (struct pthread *) arg;
+  struct pthread *pd = START_THREAD_SELF;
 
 #if HP_TIMING_AVAIL
   /* Remember the time when the thread was started.  */
@@ -229,41 +389,110 @@ start_thread (void *arg)
   /* Initialize resolver state pointer.  */
   __resp = &pd->res;
 
+  /* Initialize pointers to locale data.  */
+  __ctype_init ();
+
+  /* Allow setxid from now onwards.  */
+  if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0) == -2))
+    futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE);
+
+#ifdef __NR_set_robust_list
+# ifndef __ASSUME_SET_ROBUST_LIST
+  if (__set_robust_list_avail >= 0)
+# endif
+    {
+      INTERNAL_SYSCALL_DECL (err);
+      /* This call should never fail because the initial call in init.c
+        succeeded.  */
+      INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+                       sizeof (struct robust_list_head));
+    }
+#endif
+
+#ifdef SIGCANCEL
+  /* If the parent was running cancellation handlers while creating
+     the thread the new thread inherited the signal mask.  Reset the
+     cancellation signal mask.  */
+  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELING_BITMASK))
+    {
+      INTERNAL_SYSCALL_DECL (err);
+      sigset_t mask;
+      __sigemptyset (&mask);
+      __sigaddset (&mask, SIGCANCEL);
+      (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &mask,
+                              NULL, _NSIG / 8);
+    }
+#endif
+
   /* This is where the try/finally block should be created.  For
      compilers without that support we do use setjmp.  */
   struct pthread_unwind_buf unwind_buf;
 
-  /* No previous handlers.  */
+  int not_first_call;
+  not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+
+  /* No previous handlers.  NB: This must be done after setjmp since the
+     private space in the unwind jump buffer may overlap space used by
+     setjmp to store extra architecture-specific information which is
+     never used by the cancellation-specific __libc_unwind_longjmp.
+
+     The private space is allowed to overlap because the unwinder never
+     has to return through any of the jumped-to call frames, and thus
+     only a minimum amount of saved data need be stored, and for example,
+     need not include the process signal mask information. This is all
+     an optimization to reduce stack usage when pushing cancellation
+     handlers.  */
   unwind_buf.priv.data.prev = NULL;
   unwind_buf.priv.data.cleanup = NULL;
 
-  int not_first_call;
-  not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
-  if (__builtin_expect (! not_first_call, 1))
+  if (__glibc_likely (! not_first_call))
     {
       /* Store the new cleanup handler info.  */
       THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf);
 
-      if (__builtin_expect (pd->stopped_start, 0))
+      /* We are either in (a) or (b), and in either case we either own
+         PD already (2) or are about to own PD (1), and so our only
+        restriction would be that we can't free PD until we know we
+        have ownership (see CONCURRENCY NOTES above).  */
+      if (__glibc_unlikely (pd->stopped_start))
        {
          int oldtype = CANCEL_ASYNC ();
 
          /* Get the lock the parent locked to force synchronization.  */
-         lll_lock (pd->lock);
+         lll_lock (pd->lock, LLL_PRIVATE);
+
+         /* We have ownership of PD now.  */
+
          /* And give it up right away.  */
-         lll_unlock (pd->lock);
+         lll_unlock (pd->lock, LLL_PRIVATE);
 
          CANCEL_RESET (oldtype);
        }
 
+      LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);
+
       /* Run the code the user provided.  */
-#ifdef CALL_THREAD_FCT
-      THREAD_SETMEM (pd, result, CALL_THREAD_FCT (pd));
-#else
-      THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));
-#endif
+      void *ret;
+      if (pd->c11)
+       {
+         /* The function pointer of the c11 thread start is cast to an incorrect
+            type on __pthread_create_2_1 call, however it is casted back to correct
+            one so the call behavior is well-defined (it is assumed that pointers
+            to void are able to represent all values of int.  */
+         int (*start)(void*) = (int (*) (void*)) pd->start_routine;
+         ret = (void*) (uintptr_t) start (pd->arg);
+       }
+      else
+       ret = pd->start_routine (pd->arg);
+      THREAD_SETMEM (pd, result, ret);
     }
 
+  /* Call destructors for the thread_local TLS variables.  */
+#ifndef SHARED
+  if (&__call_tls_dtors != NULL)
+#endif
+    __call_tls_dtors ();
+
   /* Run the destructor for the thread-local data.  */
   __nptl_deallocate_tsd ();
 
@@ -273,12 +502,12 @@ start_thread (void *arg)
   /* If this is the last thread we terminate the process now.  We
      do not notify the debugger, it might just irritate it if there
      is no thread left.  */
-  if (__builtin_expect (atomic_decrement_and_test (&__nptl_nthreads), 0))
+  if (__glibc_unlikely (atomic_decrement_and_test (&__nptl_nthreads)))
     /* This was the last thread.  */
     exit (0);
 
   /* Report the death of the thread if this is wanted.  */
-  if (__builtin_expect (pd->report_events, 0))
+  if (__glibc_unlikely (pd->report_events))
     {
       /* See whether TD_DEATH is in any of the mask.  */
       const int idx = __td_eventword (TD_DEATH);
@@ -300,7 +529,8 @@ start_thread (void *arg)
                                                           pd, pd->nextevent));
            }
 
-         /* Now call the function to signal the event.  */
+         /* Now call the function which signals the event.  See
+            CONCURRENCY NOTES for the nptl_db interface comments.  */
          __nptl_death_event ();
        }
     }
@@ -310,51 +540,56 @@ start_thread (void *arg)
      the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE.  */
   atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
 
+#ifndef __ASSUME_SET_ROBUST_LIST
   /* If this thread has any robust mutexes locked, handle them now.  */
-#if __WORDSIZE == 64
-  __pthread_list_t *robust = pd->robust_list.__next;
-#else
+# if __PTHREAD_MUTEX_HAVE_PREV
+  void *robust = pd->robust_head.list;
+# else
   __pthread_slist_t *robust = pd->robust_list.__next;
-#endif
-  if (__builtin_expect (robust != &pd->robust_list, 0))
+# endif
+  /* We let the kernel do the notification if it is able to do so.
+     If we have to do it here there for sure are no PI mutexes involved
+     since the kernel support for them is even more recent.  */
+  if (__set_robust_list_avail < 0
+      && __builtin_expect (robust != (void *) &pd->robust_head, 0))
     {
       do
        {
          struct __pthread_mutex_s *this = (struct __pthread_mutex_s *)
-           ((char *) robust - offsetof (struct __pthread_mutex_s, __list));
-         robust = robust->__next;
-
-         assert (lll_mutex_islocked (this->__lock));
-         this->__count = 0;
-         --this->__nusers;
-         assert (this->__owner != PTHREAD_MUTEX_NOTRECOVERABLE);
-         this->__owner = PTHREAD_MUTEX_OWNERDEAD;
-         this->__list.__next = NULL;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+           ((char *) robust - offsetof (struct __pthread_mutex_s,
+                                        __list.__next));
+         robust = *((void **) robust);
+
+# if __PTHREAD_MUTEX_HAVE_PREV
          this->__list.__prev = NULL;
-#endif
+# endif
+         this->__list.__next = NULL;
 
-         lll_mutex_unlock (this->__lock);
+         atomic_or (&this->__lock, FUTEX_OWNER_DIED);
+         futex_wake ((unsigned int *) &this->__lock, 1,
+                     /* XYZ */ FUTEX_SHARED);
        }
-      while (robust != &pd->robust_list);
-
-      /* Clean up so that the thread descriptor can be reused.  */
-      pd->robust_list.__next = &pd->robust_list;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
-      pd->robust_list.__prev = &pd->robust_list;
-#endif
+      while (robust != (void *) &pd->robust_head);
     }
+#endif
+
+  advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
+                     pd->guardsize);
 
   /* If the thread is detached free the TCB.  */
   if (IS_DETACHED (pd))
     /* Free the TCB.  */
     __free_tcb (pd);
-  else if (__builtin_expect (pd->cancelhandling & SETXID_BITMASK, 0))
+  else if (__glibc_unlikely (pd->cancelhandling & SETXID_BITMASK))
     {
       /* Some other thread might call any of the setXid functions and expect
         us to reply.  In this case wait until we did that.  */
       do
-       lll_futex_wait (&pd->setxid_futex, 0);
+       /* XXX This differs from the typical futex_wait_simple pattern in that
+          the futex_wait condition (setxid_futex) is different from the
+          condition used in the surrounding loop (cancelhandling).  We need
+          to check and document why this is correct.  */
+       futex_wait_simple (&pd->setxid_futex, 0, FUTEX_PRIVATE);
       while (pd->cancelhandling & SETXID_BITMASK);
 
       /* Reset the value so that the stack can be reused.  */
@@ -364,55 +599,91 @@ start_thread (void *arg)
   /* We cannot call '_exit' here.  '_exit' will terminate the process.
 
      The 'exit' implementation in the kernel will signal when the
-     process is really dead since 'clone' got passed the CLONE_CLEARTID
+     process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID
      flag.  The 'tid' field in the TCB will be set to zero.
 
      The exit code is zero since in case all threads exit by calling
      'pthread_exit' the exit status must be 0 (zero).  */
-  __exit_thread_inline (0);
+  __exit_thread ();
 
   /* NOTREACHED */
-  return 0;
 }
 
 
-/* Default thread attributes for the case when the user does not
-   provide any.  */
-static const struct pthread_attr default_attr =
-  {
-    /* Just some value > 0 which gets rounded to the nearest page size.  */
-    .guardsize = 1,
-  };
+/* Return true iff obliged to report TD_CREATE events.  */
+static bool
+report_thread_creation (struct pthread *pd)
+{
+  if (__glibc_unlikely (THREAD_GETMEM (THREAD_SELF, report_events)))
+    {
+      /* The parent thread is supposed to report events.
+        Check whether the TD_CREATE event is needed, too.  */
+      const size_t idx = __td_eventword (TD_CREATE);
+      const uint32_t mask = __td_eventmask (TD_CREATE);
+
+      return ((mask & (__nptl_threads_events.event_bits[idx]
+                      | pd->eventbuf.eventmask.event_bits[idx])) != 0);
+    }
+  return false;
+}
 
 
 int
-__pthread_create_2_1 (newthread, attr, start_routine, arg)
-     pthread_t *newthread;
-     const pthread_attr_t *attr;
-     void *(*start_routine) (void *);
-     void *arg;
+__pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
+                     void *(*start_routine) (void *), void *arg)
 {
   STACK_VARIABLES;
 
   const struct pthread_attr *iattr = (struct pthread_attr *) attr;
-  if (iattr == NULL)
-    /* Is this the best idea?  On NUMA machines this could mean
-       accessing far-away memory.  */
-    iattr = &default_attr;
+  struct pthread_attr default_attr;
+  bool free_cpuset = false;
+  bool c11 = (attr == ATTR_C11_THREAD);
+  if (iattr == NULL || c11)
+    {
+      lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
+      default_attr = __default_pthread_attr;
+      size_t cpusetsize = default_attr.cpusetsize;
+      if (cpusetsize > 0)
+       {
+         cpu_set_t *cpuset;
+         if (__glibc_likely (__libc_use_alloca (cpusetsize)))
+           cpuset = __alloca (cpusetsize);
+         else
+           {
+             cpuset = malloc (cpusetsize);
+             if (cpuset == NULL)
+               {
+                 lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
+                 return ENOMEM;
+               }
+             free_cpuset = true;
+           }
+         memcpy (cpuset, default_attr.cpuset, cpusetsize);
+         default_attr.cpuset = cpuset;
+       }
+      lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
+      iattr = &default_attr;
+    }
 
   struct pthread *pd = NULL;
   int err = ALLOCATE_STACK (iattr, &pd);
-  if (__builtin_expect (err != 0, 0))
+  int retval = 0;
+
+  if (__glibc_unlikely (err != 0))
     /* Something went wrong.  Maybe a parameter of the attributes is
-       invalid or we could not allocate memory.  */
-    return err;
+       invalid or we could not allocate memory.  Note we have to
+       translate error codes.  */
+    {
+      retval = err == ENOMEM ? EAGAIN : err;
+      goto out;
+    }
 
 
   /* Initialize the TCB.  All initializations with zero should be
      performed in 'get_cached_stack'.  This way we avoid doing this if
      the stack freshly allocated with 'mmap'.  */
 
-#ifdef TLS_TCB_AT_TP
+#if TLS_TCB_AT_TP
   /* Reference to the TCB itself.  */
   pd->header.self = pd;
 
@@ -425,6 +696,7 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
      get the information from its thread descriptor.  */
   pd->start_routine = start_routine;
   pd->arg = arg;
+  pd->c11 = c11;
 
   /* Copy the thread attribute flags.  */
   struct pthread *self = THREAD_SELF;
@@ -455,77 +727,168 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
   THREAD_COPY_POINTER_GUARD (pd);
 #endif
 
+  /* Setup tcbhead.  */
+  tls_setup_tcbhead (pd);
+
+  /* Verify the sysinfo bits were copied in allocate_stack if needed.  */
+#ifdef NEED_DL_SYSINFO
+  CHECK_THREAD_SYSINFO (pd);
+#endif
+
+  /* Inform start_thread (above) about cancellation state that might
+     translate into inherited signal state.  */
+  pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
+
   /* Determine scheduling parameters for the thread.  */
-  if (attr != NULL
-      && __builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
+  if (__builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
       && (iattr->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) != 0)
     {
-      INTERNAL_SYSCALL_DECL (scerr);
-
       /* Use the scheduling parameters the user provided.  */
       if (iattr->flags & ATTR_FLAG_POLICY_SET)
-       pd->schedpolicy = iattr->schedpolicy;
-      else if ((pd->flags & ATTR_FLAG_POLICY_SET) == 0)
-       {
-         pd->schedpolicy = INTERNAL_SYSCALL (sched_getscheduler, scerr, 1, 0);
-         pd->flags |= ATTR_FLAG_POLICY_SET;
-       }
-
+        {
+          pd->schedpolicy = iattr->schedpolicy;
+          pd->flags |= ATTR_FLAG_POLICY_SET;
+        }
       if (iattr->flags & ATTR_FLAG_SCHED_SET)
-       memcpy (&pd->schedparam, &iattr->schedparam,
-               sizeof (struct sched_param));
-      else if ((pd->flags & ATTR_FLAG_SCHED_SET) == 0)
-       {
-         INTERNAL_SYSCALL (sched_getparam, scerr, 2, 0, &pd->schedparam);
-         pd->flags |= ATTR_FLAG_SCHED_SET;
-       }
-
-      /* Check for valid priorities.  */
-      int minprio = INTERNAL_SYSCALL (sched_get_priority_min, scerr, 1,
-                                     iattr->schedpolicy);
-      int maxprio = INTERNAL_SYSCALL (sched_get_priority_max, scerr, 1,
-                                     iattr->schedpolicy);
-      if (pd->schedparam.sched_priority < minprio
-         || pd->schedparam.sched_priority > maxprio)
-       {
-         err = EINVAL;
-         goto errout;
-       }
+        {
+          /* The values were validated in pthread_attr_setschedparam.  */
+          pd->schedparam = iattr->schedparam;
+          pd->flags |= ATTR_FLAG_SCHED_SET;
+        }
+
+      if ((pd->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
+          != (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
+        collect_default_sched (pd);
     }
 
+  if (__glibc_unlikely (__nptl_nthreads == 1))
+    _IO_enable_locks ();
+
   /* Pass the descriptor to the caller.  */
   *newthread = (pthread_t) pd;
 
-  /* Remember whether the thread is detached or not.  In case of an
-     error we have to free the stacks of non-detached stillborn
-     threads.  */
-  bool is_detached = IS_DETACHED (pd);
+  LIBC_PROBE (pthread_create, 4, newthread, attr, start_routine, arg);
+
+  /* One more thread.  We cannot have the thread do this itself, since it
+     might exist but not have been scheduled yet by the time we've returned
+     and need to check the value to behave correctly.  We must do it before
+     creating the thread, in case it does get scheduled first and then
+     might mistakenly think it was the only thread.  In the failure case,
+     we momentarily store a false value; this doesn't matter because there
+     is no kosher thing a signal handler interrupting us right here can do
+     that cares whether the thread count is correct.  */
+  atomic_increment (&__nptl_nthreads);
+
+  /* Our local value of stopped_start and thread_ran can be accessed at
+     any time. The PD->stopped_start may only be accessed if we have
+     ownership of PD (see CONCURRENCY NOTES above).  */
+  bool stopped_start = false; bool thread_ran = false;
 
   /* Start the thread.  */
-  err = create_thread (pd, iattr, STACK_VARIABLES_ARGS);
-  if (err != 0)
+  if (__glibc_unlikely (report_thread_creation (pd)))
+    {
+      stopped_start = true;
+
+      /* We always create the thread stopped at startup so we can
+        notify the debugger.  */
+      retval = create_thread (pd, iattr, &stopped_start,
+                             STACK_VARIABLES_ARGS, &thread_ran);
+      if (retval == 0)
+       {
+         /* We retain ownership of PD until (a) (see CONCURRENCY NOTES
+            above).  */
+
+         /* Assert stopped_start is true in both our local copy and the
+            PD copy.  */
+         assert (stopped_start);
+         assert (pd->stopped_start);
+
+         /* Now fill in the information about the new thread in
+            the newly created thread's data structure.  We cannot let
+            the new thread do this since we don't know whether it was
+            already scheduled when we send the event.  */
+         pd->eventbuf.eventnum = TD_CREATE;
+         pd->eventbuf.eventdata = pd;
+
+         /* Enqueue the descriptor.  */
+         do
+           pd->nextevent = __nptl_last_event;
+         while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
+                                                      pd, pd->nextevent)
+                != 0);
+
+         /* Now call the function which signals the event.  See
+            CONCURRENCY NOTES for the nptl_db interface comments.  */
+         __nptl_create_event ();
+       }
+    }
+  else
+    retval = create_thread (pd, iattr, &stopped_start,
+                           STACK_VARIABLES_ARGS, &thread_ran);
+
+  if (__glibc_unlikely (retval != 0))
     {
-      /* Something went wrong.  Free the resources.  */
-      if (!is_detached)
+      if (thread_ran)
+       /* State (c) or (d) and we may not have PD ownership (see
+          CONCURRENCY NOTES above).  We can assert that STOPPED_START
+          must have been true because thread creation didn't fail, but
+          thread attribute setting did.  */
+       /* See bug 19511 which explains why doing nothing here is a
+          resource leak for a joinable thread.  */
+       assert (stopped_start);
+      else
        {
-       errout:
+         /* State (e) and we have ownership of PD (see CONCURRENCY
+            NOTES above).  */
+
+         /* Oops, we lied for a second.  */
+         atomic_decrement (&__nptl_nthreads);
+
+         /* Perhaps a thread wants to change the IDs and is waiting for this
+            stillborn thread.  */
+         if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0)
+                               == -2))
+           futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE);
+
+         /* Free the resources.  */
          __deallocate_stack (pd);
        }
-      return err;
+
+      /* We have to translate error codes.  */
+      if (retval == ENOMEM)
+       retval = EAGAIN;
     }
+  else
+    {
+      /* We don't know if we have PD ownership.  Once we check the local
+         stopped_start we'll know if we're in state (a) or (b) (see
+        CONCURRENCY NOTES above).  */
+      if (stopped_start)
+       /* State (a), we own PD. The thread blocked on this lock either
+          because we're doing TD_CREATE event reporting, or for some
+          other reason that create_thread chose.  Now let it run
+          free.  */
+       lll_unlock (pd->lock, LLL_PRIVATE);
+
+      /* We now have for sure more than one thread.  The main thread might
+        not yet have the flag set.  No need to set the global variable
+        again if this is what we use.  */
+      THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
+    }
+
+ out:
+  if (__glibc_unlikely (free_cpuset))
+    free (default_attr.cpuset);
 
-  return 0;
+  return retval;
 }
 versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1);
 
 
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
 int
-__pthread_create_2_0 (newthread, attr, start_routine, arg)
-     pthread_t *newthread;
-     const pthread_attr_t *attr;
-     void *(*start_routine) (void *);
-     void *arg;
+__pthread_create_2_0 (pthread_t *newthread, const pthread_attr_t *attr,
+                     void *(*start_routine) (void *), void *arg)
 {
   /* The ATTR attribute is not really of type `pthread_attr_t *'.  It has
      the old size and access to the new members might crash the program.
@@ -565,12 +928,14 @@ compat_symbol (libpthread, __pthread_create_2_0, pthread_create,
 \f
 /* If pthread_create is present, libgcc_eh.a and libsupc++.a expects some other POSIX thread
    functions to be present as well.  */
-PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_lock)
-PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_unlock)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_mutex_lock)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_mutex_trylock)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_mutex_unlock)
 
-PTHREAD_STATIC_FN_REQUIRE (pthread_once)
-PTHREAD_STATIC_FN_REQUIRE (pthread_cancel)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_once)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_cancel)
 
-PTHREAD_STATIC_FN_REQUIRE (pthread_key_create)
-PTHREAD_STATIC_FN_REQUIRE (pthread_setspecific)
-PTHREAD_STATIC_FN_REQUIRE (pthread_getspecific)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_key_create)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_key_delete)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_setspecific)
+PTHREAD_STATIC_FN_REQUIRE (__pthread_getspecific)