Blame nptl/pthread_create.c

Packit Service 82fcde
/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include "pthreadP.h"
Packit Service 82fcde
#include <hp-timing.h>
Packit Service 82fcde
#include <ldsodefs.h>
Packit Service 82fcde
#include <atomic.h>
Packit Service 82fcde
#include <libc-internal.h>
Packit Service 82fcde
#include <resolv.h>
Packit Service 82fcde
#include <kernel-features.h>
Packit Service 82fcde
#include <exit-thread.h>
Packit Service 82fcde
#include <default-sched.h>
Packit Service 82fcde
#include <futex-internal.h>
Packit Service 82fcde
#include <tls-setup.h>
Packit Service 82fcde
#include "libioP.h"
Packit Service 82fcde
Packit Service 82fcde
#include <shlib-compat.h>
Packit Service 82fcde
Packit Service 82fcde
#include <stap-probe.h>
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Nozero if debugging mode is enabled.  */
Packit Service 82fcde
int __pthread_debug;
Packit Service 82fcde
Packit Service 82fcde
/* Globally enabled events.  */
Packit Service 82fcde
static td_thr_events_t __nptl_threads_events __attribute_used__;
Packit Service 82fcde
Packit Service 82fcde
/* Pointer to descriptor with the last event.  */
Packit Service 82fcde
static struct pthread *__nptl_last_event __attribute_used__;
Packit Service 82fcde
Packit Service 82fcde
/* Number of threads running.  */
Packit Service 82fcde
unsigned int __nptl_nthreads = 1;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Code to allocate and deallocate a stack.  */
Packit Service 82fcde
#include "allocatestack.c"
Packit Service 82fcde
Packit Service 82fcde
/* CONCURRENCY NOTES:
Packit Service 82fcde
Packit Service 82fcde
   Understanding who is the owner of the 'struct pthread' or 'PD'
Packit Service 82fcde
   (refers to the value of the 'struct pthread *pd' function argument)
Packit Service 82fcde
   is critically important in determining exactly which operations are
Packit Service 82fcde
   allowed and which are not and when, particularly when it comes to the
Packit Service 82fcde
   implementation of pthread_create, pthread_join, pthread_detach, and
Packit Service 82fcde
   other functions which all operate on PD.
Packit Service 82fcde
Packit Service 82fcde
   The owner of PD is responsible for freeing the final resources
Packit Service 82fcde
   associated with PD, and may examine the memory underlying PD at any
Packit Service 82fcde
   point in time until it frees it back to the OS or to reuse by the
Packit Service 82fcde
   runtime.
Packit Service 82fcde
Packit Service 82fcde
   The thread which calls pthread_create is called the creating thread.
Packit Service 82fcde
   The creating thread begins as the owner of PD.
Packit Service 82fcde
Packit Service 82fcde
   During startup the new thread may examine PD in coordination with the
Packit Service 82fcde
   owner thread (which may be itself).
Packit Service 82fcde
Packit Service 82fcde
   The four cases of ownership transfer are:
Packit Service 82fcde
Packit Service 82fcde
   (1) Ownership of PD is released to the process (all threads may use it)
Packit Service 82fcde
       after the new thread starts in a joinable state
Packit Service 82fcde
       i.e. pthread_create returns a usable pthread_t.
Packit Service 82fcde
Packit Service 82fcde
   (2) Ownership of PD is released to the new thread starting in a detached
Packit Service 82fcde
       state.
Packit Service 82fcde
Packit Service 82fcde
   (3) Ownership of PD is dynamically released to a running thread via
Packit Service 82fcde
       pthread_detach.
Packit Service 82fcde
Packit Service 82fcde
   (4) Ownership of PD is acquired by the thread which calls pthread_join.
Packit Service 82fcde
Packit Service 82fcde
   Implementation notes:
Packit Service 82fcde
Packit Service 82fcde
   The PD->stopped_start and thread_ran variables are used to determine
Packit Service 82fcde
   exactly which of the four ownership states we are in and therefore
Packit Service 82fcde
   what actions can be taken.  For example after (2) we cannot read or
Packit Service 82fcde
   write from PD anymore since the thread may no longer exist and the
Packit Service 82fcde
   memory may be unmapped.
Packit Service 82fcde
Packit Service 82fcde
   It is important to point out that PD->lock is being used both
Packit Service 82fcde
   similar to a one-shot semaphore and subsequently as a mutex.  The
Packit Service 82fcde
   lock is taken in the parent to force the child to wait, and then the
Packit Service 82fcde
   child releases the lock.  However, this semaphore-like effect is used
Packit Service 82fcde
   only for synchronizing the parent and child.  After startup the lock
Packit Service 82fcde
   is used like a mutex to create a critical section during which a
Packit Service 82fcde
   single owner modifies the thread parameters.
Packit Service 82fcde
Packit Service 82fcde
   The most complicated cases happen during thread startup:
Packit Service 82fcde
Packit Service 82fcde
   (a) If the created thread is in a detached (PTHREAD_CREATE_DETACHED),
Packit Service 82fcde
       or joinable (default PTHREAD_CREATE_JOINABLE) state and
Packit Service 82fcde
       STOPPED_START is true, then the creating thread has ownership of
Packit Service 82fcde
       PD until the PD->lock is released by pthread_create.  If any
Packit Service 82fcde
       errors occur we are in states (c), (d), or (e) below.
Packit Service 82fcde
Packit Service 82fcde
   (b) If the created thread is in a detached state
Packit Service 82fcde
       (PTHREAD_CREATED_DETACHED), and STOPPED_START is false, then the
Packit Service 82fcde
       creating thread has ownership of PD until it invokes the OS
Packit Service 82fcde
       kernel's thread creation routine.  If this routine returns
Packit Service 82fcde
       without error, then the created thread owns PD; otherwise, see
Packit Service 82fcde
       (c) and (e) below.
Packit Service 82fcde
Packit Service 82fcde
   (c) If the detached thread setup failed and THREAD_RAN is true, then
Packit Service 82fcde
       the creating thread releases ownership to the new thread by
Packit Service 82fcde
       sending a cancellation signal.  All threads set THREAD_RAN to
Packit Service 82fcde
       true as quickly as possible after returning from the OS kernel's
Packit Service 82fcde
       thread creation routine.
Packit Service 82fcde
Packit Service 82fcde
   (d) If the joinable thread setup failed and THREAD_RAN is true, then
Packit Service 82fcde
       then the creating thread retains ownership of PD and must cleanup
Packit Service 82fcde
       state.  Ownership cannot be released to the process via the
Packit Service 82fcde
       return of pthread_create since a non-zero result entails PD is
Packit Service 82fcde
       undefined and therefore cannot be joined to free the resources.
Packit Service 82fcde
       We privately call pthread_join on the thread to finish handling
Packit Service 82fcde
       the resource shutdown (Or at least we should, see bug 19511).
Packit Service 82fcde
Packit Service 82fcde
   (e) If the thread creation failed and THREAD_RAN is false, then the
Packit Service 82fcde
       creating thread retains ownership of PD and must cleanup state.
Packit Service 82fcde
       No waiting for the new thread is required because it never
Packit Service 82fcde
       started.
Packit Service 82fcde
Packit Service 82fcde
   The nptl_db interface:
Packit Service 82fcde
Packit Service 82fcde
   The interface with nptl_db requires that we enqueue PD into a linked
Packit Service 82fcde
   list and then call a function which the debugger will trap.  The PD
Packit Service 82fcde
   will then be dequeued and control returned to the thread.  The caller
Packit Service 82fcde
   at the time must have ownership of PD and such ownership remains
Packit Service 82fcde
   after control returns to thread. The enqueued PD is removed from the
Packit Service 82fcde
   linked list by the nptl_db callback td_thr_event_getmsg.  The debugger
Packit Service 82fcde
   must ensure that the thread does not resume execution, otherwise
Packit Service 82fcde
   ownership of PD may be lost and examining PD will not be possible.
Packit Service 82fcde
Packit Service 82fcde
   Note that the GNU Debugger as of (December 10th 2015) commit
Packit Service 82fcde
   c2c2a31fdb228d41ce3db62b268efea04bd39c18 no longer uses
Packit Service 82fcde
   td_thr_event_getmsg and several other related nptl_db interfaces. The
Packit Service 82fcde
   principal reason for this is that nptl_db does not support non-stop
Packit Service 82fcde
   mode where other threads can run concurrently and modify runtime
Packit Service 82fcde
   structures currently in use by the debugger and the nptl_db
Packit Service 82fcde
   interface.
Packit Service 82fcde
Packit Service 82fcde
   Axioms:
Packit Service 82fcde
Packit Service 82fcde
   * The create_thread function can never set stopped_start to false.
Packit Service 82fcde
   * The created thread can read stopped_start but never write to it.
Packit Service 82fcde
   * The variable thread_ran is set some time after the OS thread
Packit Service 82fcde
     creation routine returns, how much time after the thread is created
Packit Service 82fcde
     is unspecified, but it should be as quickly as possible.
Packit Service 82fcde
Packit Service 82fcde
*/
Packit Service 82fcde
Packit Service 82fcde
/* CREATE THREAD NOTES:
Packit Service 82fcde
Packit Service 82fcde
   createthread.c defines the create_thread function, and two macros:
Packit Service 82fcde
   START_THREAD_DEFN and START_THREAD_SELF (see below).
Packit Service 82fcde
Packit Service 82fcde
   create_thread must initialize PD->stopped_start.  It should be true
Packit Service 82fcde
   if the STOPPED_START parameter is true, or if create_thread needs the
Packit Service 82fcde
   new thread to synchronize at startup for some other implementation
Packit Service 82fcde
   reason.  If STOPPED_START will be true, then create_thread is obliged
Packit Service 82fcde
   to lock PD->lock before starting the thread.  Then pthread_create
Packit Service 82fcde
   unlocks PD->lock which synchronizes-with START_THREAD_DEFN in the
Packit Service 82fcde
   child thread which does an acquire/release of PD->lock as the last
Packit Service 82fcde
   action before calling the user entry point.  The goal of all of this
Packit Service 82fcde
   is to ensure that the required initial thread attributes are applied
Packit Service 82fcde
   (by the creating thread) before the new thread runs user code.  Note
Packit Service 82fcde
   that the the functions pthread_getschedparam, pthread_setschedparam,
Packit Service 82fcde
   pthread_setschedprio, __pthread_tpp_change_priority, and
Packit Service 82fcde
   __pthread_current_priority reuse the same lock, PD->lock, for a
Packit Service 82fcde
   similar purpose e.g. synchronizing the setting of similar thread
Packit Service 82fcde
   attributes.  These functions are never called before the thread is
Packit Service 82fcde
   created, so don't participate in startup syncronization, but given
Packit Service 82fcde
   that the lock is present already and in the unlocked state, reusing
Packit Service 82fcde
   it saves space.
Packit Service 82fcde
Packit Service 82fcde
   The return value is zero for success or an errno code for failure.
Packit Service 82fcde
   If the return value is ENOMEM, that will be translated to EAGAIN,
Packit Service 82fcde
   so create_thread need not do that.  On failure, *THREAD_RAN should
Packit Service 82fcde
   be set to true iff the thread actually started up and then got
Packit Service 82fcde
   canceled before calling user code (*PD->start_routine).  */
Packit Service 82fcde
static int create_thread (struct pthread *pd, const struct pthread_attr *attr,
Packit Service 82fcde
			  bool *stopped_start, STACK_VARIABLES_PARMS,
Packit Service 82fcde
			  bool *thread_ran);
Packit Service 82fcde
Packit Service 82fcde
#include <createthread.c>
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
struct pthread *
Packit Service 82fcde
__find_in_stack_list (struct pthread *pd)
Packit Service 82fcde
{
Packit Service 82fcde
  list_t *entry;
Packit Service 82fcde
  struct pthread *result = NULL;
Packit Service 82fcde
Packit Service 82fcde
  lll_lock (stack_cache_lock, LLL_PRIVATE);
Packit Service 82fcde
Packit Service 82fcde
  list_for_each (entry, &stack_used)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct pthread *curp;
Packit Service 82fcde
Packit Service 82fcde
      curp = list_entry (entry, struct pthread, list);
Packit Service 82fcde
      if (curp == pd)
Packit Service 82fcde
	{
Packit Service 82fcde
	  result = curp;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (result == NULL)
Packit Service 82fcde
    list_for_each (entry, &__stack_user)
Packit Service 82fcde
      {
Packit Service 82fcde
	struct pthread *curp;
Packit Service 82fcde
Packit Service 82fcde
	curp = list_entry (entry, struct pthread, list);
Packit Service 82fcde
	if (curp == pd)
Packit Service 82fcde
	  {
Packit Service 82fcde
	    result = curp;
Packit Service 82fcde
	    break;
Packit Service 82fcde
	  }
Packit Service 82fcde
      }
Packit Service 82fcde
Packit Service 82fcde
  lll_unlock (stack_cache_lock, LLL_PRIVATE);
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Deallocate POSIX thread-local-storage.  */
Packit Service 82fcde
void
Packit Service 82fcde
attribute_hidden
Packit Service 82fcde
__nptl_deallocate_tsd (void)
Packit Service 82fcde
{
Packit Service 82fcde
  struct pthread *self = THREAD_SELF;
Packit Service 82fcde
Packit Service 82fcde
  /* Maybe no data was ever allocated.  This happens often so we have
Packit Service 82fcde
     a flag for this.  */
Packit Service 82fcde
  if (THREAD_GETMEM (self, specific_used))
Packit Service 82fcde
    {
Packit Service 82fcde
      size_t round;
Packit Service 82fcde
      size_t cnt;
Packit Service 82fcde
Packit Service 82fcde
      round = 0;
Packit Service 82fcde
      do
Packit Service 82fcde
	{
Packit Service 82fcde
	  size_t idx;
Packit Service 82fcde
Packit Service 82fcde
	  /* So far no new nonzero data entry.  */
Packit Service 82fcde
	  THREAD_SETMEM (self, specific_used, false);
Packit Service 82fcde
Packit Service 82fcde
	  for (cnt = idx = 0; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      struct pthread_key_data *level2;
Packit Service 82fcde
Packit Service 82fcde
	      level2 = THREAD_GETMEM_NC (self, specific, cnt);
Packit Service 82fcde
Packit Service 82fcde
	      if (level2 != NULL)
Packit Service 82fcde
		{
Packit Service 82fcde
		  size_t inner;
Packit Service 82fcde
Packit Service 82fcde
		  for (inner = 0; inner < PTHREAD_KEY_2NDLEVEL_SIZE;
Packit Service 82fcde
		       ++inner, ++idx)
Packit Service 82fcde
		    {
Packit Service 82fcde
		      void *data = level2[inner].data;
Packit Service 82fcde
Packit Service 82fcde
		      if (data != NULL)
Packit Service 82fcde
			{
Packit Service 82fcde
			  /* Always clear the data.  */
Packit Service 82fcde
			  level2[inner].data = NULL;
Packit Service 82fcde
Packit Service 82fcde
			  /* Make sure the data corresponds to a valid
Packit Service 82fcde
			     key.  This test fails if the key was
Packit Service 82fcde
			     deallocated and also if it was
Packit Service 82fcde
			     re-allocated.  It is the user's
Packit Service 82fcde
			     responsibility to free the memory in this
Packit Service 82fcde
			     case.  */
Packit Service 82fcde
			  if (level2[inner].seq
Packit Service 82fcde
			      == __pthread_keys[idx].seq
Packit Service 82fcde
			      /* It is not necessary to register a destructor
Packit Service 82fcde
				 function.  */
Packit Service 82fcde
			      && __pthread_keys[idx].destr != NULL)
Packit Service 82fcde
			    /* Call the user-provided destructor.  */
Packit Service 82fcde
			    __pthread_keys[idx].destr (data);
Packit Service 82fcde
			}
Packit Service 82fcde
		    }
Packit Service 82fcde
		}
Packit Service 82fcde
	      else
Packit Service 82fcde
		idx += PTHREAD_KEY_1STLEVEL_SIZE;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  if (THREAD_GETMEM (self, specific_used) == 0)
Packit Service 82fcde
	    /* No data has been modified.  */
Packit Service 82fcde
	    goto just_free;
Packit Service 82fcde
	}
Packit Service 82fcde
      /* We only repeat the process a fixed number of times.  */
Packit Service 82fcde
      while (__builtin_expect (++round < PTHREAD_DESTRUCTOR_ITERATIONS, 0));
Packit Service 82fcde
Packit Service 82fcde
      /* Just clear the memory of the first block for reuse.  */
Packit Service 82fcde
      memset (&THREAD_SELF->specific_1stblock, '\0',
Packit Service 82fcde
	      sizeof (self->specific_1stblock));
Packit Service 82fcde
Packit Service 82fcde
    just_free:
Packit Service 82fcde
      /* Free the memory for the other blocks.  */
Packit Service 82fcde
      for (cnt = 1; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
Packit Service 82fcde
	{
Packit Service 82fcde
	  struct pthread_key_data *level2;
Packit Service 82fcde
Packit Service 82fcde
	  level2 = THREAD_GETMEM_NC (self, specific, cnt);
Packit Service 82fcde
	  if (level2 != NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* The first block is allocated as part of the thread
Packit Service 82fcde
		 descriptor.  */
Packit Service 82fcde
	      free (level2);
Packit Service 82fcde
	      THREAD_SETMEM_NC (self, specific, cnt, NULL);
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      THREAD_SETMEM (self, specific_used, false);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Deallocate a thread's stack after optionally making sure the thread
Packit Service 82fcde
   descriptor is still valid.  */
Packit Service 82fcde
void
Packit Service 82fcde
__free_tcb (struct pthread *pd)
Packit Service 82fcde
{
Packit Service 82fcde
  /* The thread is exiting now.  */
Packit Service 82fcde
  if (__builtin_expect (atomic_bit_test_set (&pd->cancelhandling,
Packit Service 82fcde
					     TERMINATED_BIT) == 0, 1))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Remove the descriptor from the list.  */
Packit Service 82fcde
      if (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
Packit Service 82fcde
	/* Something is really wrong.  The descriptor for a still
Packit Service 82fcde
	   running thread is gone.  */
Packit Service 82fcde
	abort ();
Packit Service 82fcde
Packit Service 82fcde
      /* Free TPP data.  */
Packit Service 82fcde
      if (__glibc_unlikely (pd->tpp != NULL))
Packit Service 82fcde
	{
Packit Service 82fcde
	  struct priority_protection_data *tpp = pd->tpp;
Packit Service 82fcde
Packit Service 82fcde
	  pd->tpp = NULL;
Packit Service 82fcde
	  free (tpp);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Queue the stack memory block for reuse and exit the process.  The
Packit Service 82fcde
	 kernel will signal via writing to the address returned by
Packit Service 82fcde
	 QUEUE-STACK when the stack is available.  */
Packit Service 82fcde
      __deallocate_stack (pd);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Local function to start thread and handle cleanup.
Packit Service 82fcde
   createthread.c defines the macro START_THREAD_DEFN to the
Packit Service 82fcde
   declaration that its create_thread function will refer to, and
Packit Service 82fcde
   START_THREAD_SELF to the expression to optimally deliver the new
Packit Service 82fcde
   thread's THREAD_SELF value.  */
Packit Service 82fcde
START_THREAD_DEFN
Packit Service 82fcde
{
Packit Service 82fcde
  struct pthread *pd = START_THREAD_SELF;
Packit Service 82fcde
Packit Service 82fcde
#if HP_TIMING_AVAIL
Packit Service 82fcde
  /* Remember the time when the thread was started.  */
Packit Service 82fcde
  hp_timing_t now;
Packit Service 82fcde
  HP_TIMING_NOW (now);
Packit Service 82fcde
  THREAD_SETMEM (pd, cpuclock_offset, now);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Initialize resolver state pointer.  */
Packit Service 82fcde
  __resp = &pd->res;
Packit Service 82fcde
Packit Service 82fcde
  /* Initialize pointers to locale data.  */
Packit Service 82fcde
  __ctype_init ();
Packit Service 82fcde
Packit Service 82fcde
  /* Allow setxid from now onwards.  */
Packit Service 82fcde
  if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0) == -2))
Packit Service 82fcde
    futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE);
Packit Service 82fcde
Packit Service 82fcde
#ifdef __NR_set_robust_list
Packit Service 82fcde
# ifndef __ASSUME_SET_ROBUST_LIST
Packit Service 82fcde
  if (__set_robust_list_avail >= 0)
Packit Service 82fcde
# endif
Packit Service 82fcde
    {
Packit Service 82fcde
      INTERNAL_SYSCALL_DECL (err);
Packit Service 82fcde
      /* This call should never fail because the initial call in init.c
Packit Service 82fcde
	 succeeded.  */
Packit Service 82fcde
      INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
Packit Service 82fcde
			sizeof (struct robust_list_head));
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef SIGCANCEL
Packit Service 82fcde
  /* If the parent was running cancellation handlers while creating
Packit Service 82fcde
     the thread the new thread inherited the signal mask.  Reset the
Packit Service 82fcde
     cancellation signal mask.  */
Packit Service 82fcde
  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELING_BITMASK))
Packit Service 82fcde
    {
Packit Service 82fcde
      INTERNAL_SYSCALL_DECL (err);
Packit Service 82fcde
      sigset_t mask;
Packit Service 82fcde
      __sigemptyset (&mask);
Packit Service 82fcde
      __sigaddset (&mask, SIGCANCEL);
Packit Service 82fcde
      (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &mask,
Packit Service 82fcde
			       NULL, _NSIG / 8);
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* This is where the try/finally block should be created.  For
Packit Service 82fcde
     compilers without that support we do use setjmp.  */
Packit Service 82fcde
  struct pthread_unwind_buf unwind_buf;
Packit Service 82fcde
Packit Service 82fcde
  int not_first_call;
Packit Service 82fcde
  not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
Packit Service 82fcde
Packit Service 82fcde
  /* No previous handlers.  NB: This must be done after setjmp since the
Packit Service 82fcde
     private space in the unwind jump buffer may overlap space used by
Packit Service 82fcde
     setjmp to store extra architecture-specific information which is
Packit Service 82fcde
     never used by the cancellation-specific __libc_unwind_longjmp.
Packit Service 82fcde
Packit Service 82fcde
     The private space is allowed to overlap because the unwinder never
Packit Service 82fcde
     has to return through any of the jumped-to call frames, and thus
Packit Service 82fcde
     only a minimum amount of saved data need be stored, and for example,
Packit Service 82fcde
     need not include the process signal mask information. This is all
Packit Service 82fcde
     an optimization to reduce stack usage when pushing cancellation
Packit Service 82fcde
     handlers.  */
Packit Service 82fcde
  unwind_buf.priv.data.prev = NULL;
Packit Service 82fcde
  unwind_buf.priv.data.cleanup = NULL;
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_likely (! not_first_call))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Store the new cleanup handler info.  */
Packit Service 82fcde
      THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf);
Packit Service 82fcde
Packit Service 82fcde
      /* We are either in (a) or (b), and in either case we either own
Packit Service 82fcde
         PD already (2) or are about to own PD (1), and so our only
Packit Service 82fcde
	 restriction would be that we can't free PD until we know we
Packit Service 82fcde
	 have ownership (see CONCURRENCY NOTES above).  */
Packit Service 82fcde
      if (__glibc_unlikely (pd->stopped_start))
Packit Service 82fcde
	{
Packit Service 82fcde
	  int oldtype = CANCEL_ASYNC ();
Packit Service 82fcde
Packit Service 82fcde
	  /* Get the lock the parent locked to force synchronization.  */
Packit Service 82fcde
	  lll_lock (pd->lock, LLL_PRIVATE);
Packit Service 82fcde
Packit Service 82fcde
	  /* We have ownership of PD now.  */
Packit Service 82fcde
Packit Service 82fcde
	  /* And give it up right away.  */
Packit Service 82fcde
	  lll_unlock (pd->lock, LLL_PRIVATE);
Packit Service 82fcde
Packit Service 82fcde
	  CANCEL_RESET (oldtype);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);
Packit Service 82fcde
Packit Service 82fcde
      /* Run the code the user provided.  */
Packit Service 82fcde
      void *ret;
Packit Service 82fcde
      if (pd->c11)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* The function pointer of the c11 thread start is cast to an incorrect
Packit Service 82fcde
	     type on __pthread_create_2_1 call, however it is casted back to correct
Packit Service 82fcde
	     one so the call behavior is well-defined (it is assumed that pointers
Packit Service 82fcde
	     to void are able to represent all values of int.  */
Packit Service 82fcde
	  int (*start)(void*) = (int (*) (void*)) pd->start_routine;
Packit Service 82fcde
	  ret = (void*) (uintptr_t) start (pd->arg);
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	ret = pd->start_routine (pd->arg);
Packit Service 82fcde
      THREAD_SETMEM (pd, result, ret);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Call destructors for the thread_local TLS variables.  */
Packit Service 82fcde
#ifndef SHARED
Packit Service 82fcde
  if (&__call_tls_dtors != NULL)
Packit Service 82fcde
#endif
Packit Service 82fcde
    __call_tls_dtors ();
Packit Service 82fcde
Packit Service 82fcde
  /* Run the destructor for the thread-local data.  */
Packit Service 82fcde
  __nptl_deallocate_tsd ();
Packit Service 82fcde
Packit Service 82fcde
  /* Clean up any state libc stored in thread-local variables.  */
Packit Service 82fcde
  __libc_thread_freeres ();
Packit Service 82fcde
Packit Service 82fcde
  /* If this is the last thread we terminate the process now.  We
Packit Service 82fcde
     do not notify the debugger, it might just irritate it if there
Packit Service 82fcde
     is no thread left.  */
Packit Service 82fcde
  if (__glibc_unlikely (atomic_decrement_and_test (&__nptl_nthreads)))
Packit Service 82fcde
    /* This was the last thread.  */
Packit Service 82fcde
    exit (0);
Packit Service 82fcde
Packit Service 82fcde
  /* Report the death of the thread if this is wanted.  */
Packit Service 82fcde
  if (__glibc_unlikely (pd->report_events))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* See whether TD_DEATH is in any of the mask.  */
Packit Service 82fcde
      const int idx = __td_eventword (TD_DEATH);
Packit Service 82fcde
      const uint32_t mask = __td_eventmask (TD_DEATH);
Packit Service 82fcde
Packit Service 82fcde
      if ((mask & (__nptl_threads_events.event_bits[idx]
Packit Service 82fcde
		   | pd->eventbuf.eventmask.event_bits[idx])) != 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Yep, we have to signal the death.  Add the descriptor to
Packit Service 82fcde
	     the list but only if it is not already on it.  */
Packit Service 82fcde
	  if (pd->nextevent == NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      pd->eventbuf.eventnum = TD_DEATH;
Packit Service 82fcde
	      pd->eventbuf.eventdata = pd;
Packit Service 82fcde
Packit Service 82fcde
	      do
Packit Service 82fcde
		pd->nextevent = __nptl_last_event;
Packit Service 82fcde
	      while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
Packit Service 82fcde
							   pd, pd->nextevent));
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Now call the function which signals the event.  See
Packit Service 82fcde
	     CONCURRENCY NOTES for the nptl_db interface comments.  */
Packit Service 82fcde
	  __nptl_death_event ();
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* The thread is exiting now.  Don't set this bit until after we've hit
Packit Service 82fcde
     the event-reporting breakpoint, so that td_thr_get_info on us while at
Packit Service 82fcde
     the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE.  */
Packit Service 82fcde
  atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
Packit Service 82fcde
Packit Service 82fcde
#ifndef __ASSUME_SET_ROBUST_LIST
Packit Service 82fcde
  /* If this thread has any robust mutexes locked, handle them now.  */
Packit Service 82fcde
# if __PTHREAD_MUTEX_HAVE_PREV
Packit Service 82fcde
  void *robust = pd->robust_head.list;
Packit Service 82fcde
# else
Packit Service 82fcde
  __pthread_slist_t *robust = pd->robust_list.__next;
Packit Service 82fcde
# endif
Packit Service 82fcde
  /* We let the kernel do the notification if it is able to do so.
Packit Service 82fcde
     If we have to do it here there for sure are no PI mutexes involved
Packit Service 82fcde
     since the kernel support for them is even more recent.  */
Packit Service 82fcde
  if (__set_robust_list_avail < 0
Packit Service 82fcde
      && __builtin_expect (robust != (void *) &pd->robust_head, 0))
Packit Service 82fcde
    {
Packit Service 82fcde
      do
Packit Service 82fcde
	{
Packit Service 82fcde
	  struct __pthread_mutex_s *this = (struct __pthread_mutex_s *)
Packit Service 82fcde
	    ((char *) robust - offsetof (struct __pthread_mutex_s,
Packit Service 82fcde
					 __list.__next));
Packit Service 82fcde
	  robust = *((void **) robust);
Packit Service 82fcde
Packit Service 82fcde
# if __PTHREAD_MUTEX_HAVE_PREV
Packit Service 82fcde
	  this->__list.__prev = NULL;
Packit Service 82fcde
# endif
Packit Service 82fcde
	  this->__list.__next = NULL;
Packit Service 82fcde
Packit Service 82fcde
	  atomic_or (&this->__lock, FUTEX_OWNER_DIED);
Packit Service 82fcde
	  futex_wake ((unsigned int *) &this->__lock, 1,
Packit Service 82fcde
		      /* XYZ */ FUTEX_SHARED);
Packit Service 82fcde
	}
Packit Service 82fcde
      while (robust != (void *) &pd->robust_head);
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
Packit Service 82fcde
		      pd->guardsize);
Packit Service 82fcde
Packit Service 82fcde
  /* If the thread is detached free the TCB.  */
Packit Service 82fcde
  if (IS_DETACHED (pd))
Packit Service 82fcde
    /* Free the TCB.  */
Packit Service 82fcde
    __free_tcb (pd);
Packit Service 82fcde
  else if (__glibc_unlikely (pd->cancelhandling & SETXID_BITMASK))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Some other thread might call any of the setXid functions and expect
Packit Service 82fcde
	 us to reply.  In this case wait until we did that.  */
Packit Service 82fcde
      do
Packit Service 82fcde
	/* XXX This differs from the typical futex_wait_simple pattern in that
Packit Service 82fcde
	   the futex_wait condition (setxid_futex) is different from the
Packit Service 82fcde
	   condition used in the surrounding loop (cancelhandling).  We need
Packit Service 82fcde
	   to check and document why this is correct.  */
Packit Service 82fcde
	futex_wait_simple (&pd->setxid_futex, 0, FUTEX_PRIVATE);
Packit Service 82fcde
      while (pd->cancelhandling & SETXID_BITMASK);
Packit Service 82fcde
Packit Service 82fcde
      /* Reset the value so that the stack can be reused.  */
Packit Service 82fcde
      pd->setxid_futex = 0;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* We cannot call '_exit' here.  '_exit' will terminate the process.
Packit Service 82fcde
Packit Service 82fcde
     The 'exit' implementation in the kernel will signal when the
Packit Service 82fcde
     process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID
Packit Service 82fcde
     flag.  The 'tid' field in the TCB will be set to zero.
Packit Service 82fcde
Packit Service 82fcde
     The exit code is zero since in case all threads exit by calling
Packit Service 82fcde
     'pthread_exit' the exit status must be 0 (zero).  */
Packit Service 82fcde
  __exit_thread ();
Packit Service 82fcde
Packit Service 82fcde
  /* NOTREACHED */
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Return true iff obliged to report TD_CREATE events.  */
Packit Service 82fcde
static bool
Packit Service 82fcde
report_thread_creation (struct pthread *pd)
Packit Service 82fcde
{
Packit Service 82fcde
  if (__glibc_unlikely (THREAD_GETMEM (THREAD_SELF, report_events)))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* The parent thread is supposed to report events.
Packit Service 82fcde
	 Check whether the TD_CREATE event is needed, too.  */
Packit Service 82fcde
      const size_t idx = __td_eventword (TD_CREATE);
Packit Service 82fcde
      const uint32_t mask = __td_eventmask (TD_CREATE);
Packit Service 82fcde
Packit Service 82fcde
      return ((mask & (__nptl_threads_events.event_bits[idx]
Packit Service 82fcde
		       | pd->eventbuf.eventmask.event_bits[idx])) != 0);
Packit Service 82fcde
    }
Packit Service 82fcde
  return false;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
__pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
Packit Service 82fcde
		      void *(*start_routine) (void *), void *arg)
Packit Service 82fcde
{
Packit Service 82fcde
  STACK_VARIABLES;
Packit Service 82fcde
Packit Service 82fcde
  const struct pthread_attr *iattr = (struct pthread_attr *) attr;
Packit Service 82fcde
  struct pthread_attr default_attr;
Packit Service 82fcde
  bool free_cpuset = false;
Packit Service 82fcde
  bool c11 = (attr == ATTR_C11_THREAD);
Packit Service 82fcde
  if (iattr == NULL || c11)
Packit Service 82fcde
    {
Packit Service 82fcde
      lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
Packit Service 82fcde
      default_attr = __default_pthread_attr;
Packit Service 82fcde
      size_t cpusetsize = default_attr.cpusetsize;
Packit Service 82fcde
      if (cpusetsize > 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  cpu_set_t *cpuset;
Packit Service 82fcde
	  if (__glibc_likely (__libc_use_alloca (cpusetsize)))
Packit Service 82fcde
	    cpuset = __alloca (cpusetsize);
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      cpuset = malloc (cpusetsize);
Packit Service 82fcde
	      if (cpuset == NULL)
Packit Service 82fcde
		{
Packit Service 82fcde
		  lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
Packit Service 82fcde
		  return ENOMEM;
Packit Service 82fcde
		}
Packit Service 82fcde
	      free_cpuset = true;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  memcpy (cpuset, default_attr.cpuset, cpusetsize);
Packit Service 82fcde
	  default_attr.cpuset = cpuset;
Packit Service 82fcde
	}
Packit Service 82fcde
      lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
Packit Service 82fcde
      iattr = &default_attr;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  struct pthread *pd = NULL;
Packit Service 82fcde
  int err = ALLOCATE_STACK (iattr, &pd;;
Packit Service 82fcde
  int retval = 0;
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (err != 0))
Packit Service 82fcde
    /* Something went wrong.  Maybe a parameter of the attributes is
Packit Service 82fcde
       invalid or we could not allocate memory.  Note we have to
Packit Service 82fcde
       translate error codes.  */
Packit Service 82fcde
    {
Packit Service 82fcde
      retval = err == ENOMEM ? EAGAIN : err;
Packit Service 82fcde
      goto out;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
  /* Initialize the TCB.  All initializations with zero should be
Packit Service 82fcde
     performed in 'get_cached_stack'.  This way we avoid doing this if
Packit Service 82fcde
     the stack freshly allocated with 'mmap'.  */
Packit Service 82fcde
Packit Service 82fcde
#if TLS_TCB_AT_TP
Packit Service 82fcde
  /* Reference to the TCB itself.  */
Packit Service 82fcde
  pd->header.self = pd;
Packit Service 82fcde
Packit Service 82fcde
  /* Self-reference for TLS.  */
Packit Service 82fcde
  pd->header.tcb = pd;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Store the address of the start routine and the parameter.  Since
Packit Service 82fcde
     we do not start the function directly the stillborn thread will
Packit Service 82fcde
     get the information from its thread descriptor.  */
Packit Service 82fcde
  pd->start_routine = start_routine;
Packit Service 82fcde
  pd->arg = arg;
Packit Service 82fcde
  pd->c11 = c11;
Packit Service 82fcde
Packit Service 82fcde
  /* Copy the thread attribute flags.  */
Packit Service 82fcde
  struct pthread *self = THREAD_SELF;
Packit Service 82fcde
  pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
Packit Service 82fcde
	       | (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)));
Packit Service 82fcde
Packit Service 82fcde
  /* Initialize the field for the ID of the thread which is waiting
Packit Service 82fcde
     for us.  This is a self-reference in case the thread is created
Packit Service 82fcde
     detached.  */
Packit Service 82fcde
  pd->joinid = iattr->flags & ATTR_FLAG_DETACHSTATE ? pd : NULL;
Packit Service 82fcde
Packit Service 82fcde
  /* The debug events are inherited from the parent.  */
Packit Service 82fcde
  pd->eventbuf = self->eventbuf;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
  /* Copy the parent's scheduling parameters.  The flags will say what
Packit Service 82fcde
     is valid and what is not.  */
Packit Service 82fcde
  pd->schedpolicy = self->schedpolicy;
Packit Service 82fcde
  pd->schedparam = self->schedparam;
Packit Service 82fcde
Packit Service 82fcde
  /* Copy the stack guard canary.  */
Packit Service 82fcde
#ifdef THREAD_COPY_STACK_GUARD
Packit Service 82fcde
  THREAD_COPY_STACK_GUARD (pd);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Copy the pointer guard value.  */
Packit Service 82fcde
#ifdef THREAD_COPY_POINTER_GUARD
Packit Service 82fcde
  THREAD_COPY_POINTER_GUARD (pd);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Setup tcbhead.  */
Packit Service 82fcde
  tls_setup_tcbhead (pd);
Packit Service 82fcde
Packit Service 82fcde
  /* Verify the sysinfo bits were copied in allocate_stack if needed.  */
Packit Service 82fcde
#ifdef NEED_DL_SYSINFO
Packit Service 82fcde
  CHECK_THREAD_SYSINFO (pd);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Inform start_thread (above) about cancellation state that might
Packit Service 82fcde
     translate into inherited signal state.  */
Packit Service 82fcde
  pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
Packit Service 82fcde
Packit Service 82fcde
  /* Determine scheduling parameters for the thread.  */
Packit Service 82fcde
  if (__builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
Packit Service 82fcde
      && (iattr->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Use the scheduling parameters the user provided.  */
Packit Service 82fcde
      if (iattr->flags & ATTR_FLAG_POLICY_SET)
Packit Service 82fcde
        {
Packit Service 82fcde
          pd->schedpolicy = iattr->schedpolicy;
Packit Service 82fcde
          pd->flags |= ATTR_FLAG_POLICY_SET;
Packit Service 82fcde
        }
Packit Service 82fcde
      if (iattr->flags & ATTR_FLAG_SCHED_SET)
Packit Service 82fcde
        {
Packit Service 82fcde
          /* The values were validated in pthread_attr_setschedparam.  */
Packit Service 82fcde
          pd->schedparam = iattr->schedparam;
Packit Service 82fcde
          pd->flags |= ATTR_FLAG_SCHED_SET;
Packit Service 82fcde
        }
Packit Service 82fcde
Packit Service 82fcde
      if ((pd->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
Packit Service 82fcde
          != (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
Packit Service 82fcde
        collect_default_sched (pd);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (__nptl_nthreads == 1))
Packit Service 82fcde
    _IO_enable_locks ();
Packit Service 82fcde
Packit Service 82fcde
  /* Pass the descriptor to the caller.  */
Packit Service 82fcde
  *newthread = (pthread_t) pd;
Packit Service 82fcde
Packit Service 82fcde
  LIBC_PROBE (pthread_create, 4, newthread, attr, start_routine, arg);
Packit Service 82fcde
Packit Service 82fcde
  /* One more thread.  We cannot have the thread do this itself, since it
Packit Service 82fcde
     might exist but not have been scheduled yet by the time we've returned
Packit Service 82fcde
     and need to check the value to behave correctly.  We must do it before
Packit Service 82fcde
     creating the thread, in case it does get scheduled first and then
Packit Service 82fcde
     might mistakenly think it was the only thread.  In the failure case,
Packit Service 82fcde
     we momentarily store a false value; this doesn't matter because there
Packit Service 82fcde
     is no kosher thing a signal handler interrupting us right here can do
Packit Service 82fcde
     that cares whether the thread count is correct.  */
Packit Service 82fcde
  atomic_increment (&__nptl_nthreads);
Packit Service 82fcde
Packit Service 82fcde
  /* Our local value of stopped_start and thread_ran can be accessed at
Packit Service 82fcde
     any time. The PD->stopped_start may only be accessed if we have
Packit Service 82fcde
     ownership of PD (see CONCURRENCY NOTES above).  */
Packit Service 82fcde
  bool stopped_start = false; bool thread_ran = false;
Packit Service 82fcde
Packit Service 82fcde
  /* Start the thread.  */
Packit Service 82fcde
  if (__glibc_unlikely (report_thread_creation (pd)))
Packit Service 82fcde
    {
Packit Service 82fcde
      stopped_start = true;
Packit Service 82fcde
Packit Service 82fcde
      /* We always create the thread stopped at startup so we can
Packit Service 82fcde
	 notify the debugger.  */
Packit Service 82fcde
      retval = create_thread (pd, iattr, &stopped_start,
Packit Service 82fcde
			      STACK_VARIABLES_ARGS, &thread_ran);
Packit Service 82fcde
      if (retval == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* We retain ownership of PD until (a) (see CONCURRENCY NOTES
Packit Service 82fcde
	     above).  */
Packit Service 82fcde
Packit Service 82fcde
	  /* Assert stopped_start is true in both our local copy and the
Packit Service 82fcde
	     PD copy.  */
Packit Service 82fcde
	  assert (stopped_start);
Packit Service 82fcde
	  assert (pd->stopped_start);
Packit Service 82fcde
Packit Service 82fcde
	  /* Now fill in the information about the new thread in
Packit Service 82fcde
	     the newly created thread's data structure.  We cannot let
Packit Service 82fcde
	     the new thread do this since we don't know whether it was
Packit Service 82fcde
	     already scheduled when we send the event.  */
Packit Service 82fcde
	  pd->eventbuf.eventnum = TD_CREATE;
Packit Service 82fcde
	  pd->eventbuf.eventdata = pd;
Packit Service 82fcde
Packit Service 82fcde
	  /* Enqueue the descriptor.  */
Packit Service 82fcde
	  do
Packit Service 82fcde
	    pd->nextevent = __nptl_last_event;
Packit Service 82fcde
	  while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
Packit Service 82fcde
						       pd, pd->nextevent)
Packit Service 82fcde
		 != 0);
Packit Service 82fcde
Packit Service 82fcde
	  /* Now call the function which signals the event.  See
Packit Service 82fcde
	     CONCURRENCY NOTES for the nptl_db interface comments.  */
Packit Service 82fcde
	  __nptl_create_event ();
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    retval = create_thread (pd, iattr, &stopped_start,
Packit Service 82fcde
			    STACK_VARIABLES_ARGS, &thread_ran);
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (retval != 0))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (thread_ran)
Packit Service 82fcde
	/* State (c) or (d) and we may not have PD ownership (see
Packit Service 82fcde
	   CONCURRENCY NOTES above).  We can assert that STOPPED_START
Packit Service 82fcde
	   must have been true because thread creation didn't fail, but
Packit Service 82fcde
	   thread attribute setting did.  */
Packit Service 82fcde
	/* See bug 19511 which explains why doing nothing here is a
Packit Service 82fcde
	   resource leak for a joinable thread.  */
Packit Service 82fcde
	assert (stopped_start);
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* State (e) and we have ownership of PD (see CONCURRENCY
Packit Service 82fcde
	     NOTES above).  */
Packit Service 82fcde
Packit Service 82fcde
	  /* Oops, we lied for a second.  */
Packit Service 82fcde
	  atomic_decrement (&__nptl_nthreads);
Packit Service 82fcde
Packit Service 82fcde
	  /* Perhaps a thread wants to change the IDs and is waiting for this
Packit Service 82fcde
	     stillborn thread.  */
Packit Service 82fcde
	  if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0)
Packit Service 82fcde
				== -2))
Packit Service 82fcde
	    futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE);
Packit Service 82fcde
Packit Service 82fcde
	  /* Free the resources.  */
Packit Service 82fcde
	  __deallocate_stack (pd);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* We have to translate error codes.  */
Packit Service 82fcde
      if (retval == ENOMEM)
Packit Service 82fcde
	retval = EAGAIN;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We don't know if we have PD ownership.  Once we check the local
Packit Service 82fcde
         stopped_start we'll know if we're in state (a) or (b) (see
Packit Service 82fcde
	 CONCURRENCY NOTES above).  */
Packit Service 82fcde
      if (stopped_start)
Packit Service 82fcde
	/* State (a), we own PD. The thread blocked on this lock either
Packit Service 82fcde
	   because we're doing TD_CREATE event reporting, or for some
Packit Service 82fcde
	   other reason that create_thread chose.  Now let it run
Packit Service 82fcde
	   free.  */
Packit Service 82fcde
	lll_unlock (pd->lock, LLL_PRIVATE);
Packit Service 82fcde
Packit Service 82fcde
      /* We now have for sure more than one thread.  The main thread might
Packit Service 82fcde
	 not yet have the flag set.  No need to set the global variable
Packit Service 82fcde
	 again if this is what we use.  */
Packit Service 82fcde
      THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
 out:
Packit Service 82fcde
  if (__glibc_unlikely (free_cpuset))
Packit Service 82fcde
    free (default_attr.cpuset);
Packit Service 82fcde
Packit Service 82fcde
  return retval;
Packit Service 82fcde
}
Packit Service 82fcde
versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1);
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
Packit Service 82fcde
int
Packit Service 82fcde
__pthread_create_2_0 (pthread_t *newthread, const pthread_attr_t *attr,
Packit Service 82fcde
		      void *(*start_routine) (void *), void *arg)
Packit Service 82fcde
{
Packit Service 82fcde
  /* The ATTR attribute is not really of type `pthread_attr_t *'.  It has
Packit Service 82fcde
     the old size and access to the new members might crash the program.
Packit Service 82fcde
     We convert the struct now.  */
Packit Service 82fcde
  struct pthread_attr new_attr;
Packit Service 82fcde
Packit Service 82fcde
  if (attr != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct pthread_attr *iattr = (struct pthread_attr *) attr;
Packit Service 82fcde
      size_t ps = __getpagesize ();
Packit Service 82fcde
Packit Service 82fcde
      /* Copy values from the user-provided attributes.  */
Packit Service 82fcde
      new_attr.schedparam = iattr->schedparam;
Packit Service 82fcde
      new_attr.schedpolicy = iattr->schedpolicy;
Packit Service 82fcde
      new_attr.flags = iattr->flags;
Packit Service 82fcde
Packit Service 82fcde
      /* Fill in default values for the fields not present in the old
Packit Service 82fcde
	 implementation.  */
Packit Service 82fcde
      new_attr.guardsize = ps;
Packit Service 82fcde
      new_attr.stackaddr = NULL;
Packit Service 82fcde
      new_attr.stacksize = 0;
Packit Service 82fcde
      new_attr.cpuset = NULL;
Packit Service 82fcde
Packit Service 82fcde
      /* We will pass this value on to the real implementation.  */
Packit Service 82fcde
      attr = (pthread_attr_t *) &new_attr;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return __pthread_create_2_1 (newthread, attr, start_routine, arg);
Packit Service 82fcde
}
Packit Service 82fcde
compat_symbol (libpthread, __pthread_create_2_0, pthread_create,
Packit Service 82fcde
	       GLIBC_2_0);
Packit Service 82fcde
#endif
Packit Service 82fcde

Packit Service 82fcde
/* Information for libthread_db.  */
Packit Service 82fcde
Packit Service 82fcde
#include "../nptl_db/db_info.c"
Packit Service 82fcde

Packit Service 82fcde
/* If pthread_create is present, libgcc_eh.a and libsupc++.a expects some other POSIX thread
Packit Service 82fcde
   functions to be present as well.  */
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_mutex_lock)
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_mutex_trylock)
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_mutex_unlock)
Packit Service 82fcde
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_once)
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_cancel)
Packit Service 82fcde
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_key_create)
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_key_delete)
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_setspecific)
Packit Service 82fcde
PTHREAD_STATIC_FN_REQUIRE (__pthread_getspecific)