/* Copyright (C) 2002-2016 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 <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 <shlib-compat.h>
#include <stap-probe.h>
/* Nozero if debugging mode is enabled. */
int __pthread_debug;
/* Globally enabled events. */
static td_thr_events_t __nptl_threads_events __attribute_used__;
/* Pointer to descriptor with the last event. */
static struct pthread *__nptl_last_event __attribute_used__;
/* Number of threads running. */
unsigned int __nptl_nthreads = 1;
/* Code to allocate and deallocate a stack. */
#include "allocatestack.c"
/* createthread.c defines this function, and two macros:
START_THREAD_DEFN and START_THREAD_SELF (see below).
create_thread is obliged to 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 PD->stopped_start will be
true, then create_thread is obliged to perform the operation
"lll_lock (PD->lock, LLL_PRIVATE)" before starting the thread.
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
cancelled before calling user code (*PD->start_routine), in which
case it is responsible for doing its own cleanup. */
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 (struct pthread *pd)
{
list_t *entry;
struct pthread *result = NULL;
lll_lock (stack_cache_lock, LLL_PRIVATE);
list_for_each (entry, &stack_used)
{
struct pthread *curp;
curp = list_entry (entry, struct pthread, list);
if (curp == pd)
{
result = curp;
break;
}
}
if (result == NULL)
list_for_each (entry, &__stack_user)
{
struct pthread *curp;
curp = list_entry (entry, struct pthread, list);