Blame nptl/pthreadP.h

Packit 6c4009
/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifndef _PTHREADP_H
Packit 6c4009
#define _PTHREADP_H	1
Packit 6c4009
Packit 6c4009
#include <pthread.h>
Packit 6c4009
#include <setjmp.h>
Packit 6c4009
#include <stdbool.h>
Packit 6c4009
#include <sys/syscall.h>
Packit 6c4009
#include "descr.h"
Packit 6c4009
#include <tls.h>
Packit 6c4009
#include <lowlevellock.h>
Packit 6c4009
#include <stackinfo.h>
Packit 6c4009
#include <internaltypes.h>
Packit 6c4009
#include <pthread-functions.h>
Packit 6c4009
#include <atomic.h>
Packit 6c4009
#include <kernel-features.h>
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <internal-signals.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Atomic operations on TLS memory.  */
Packit 6c4009
#ifndef THREAD_ATOMIC_CMPXCHG_VAL
Packit 6c4009
# define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, new, old) \
Packit 6c4009
  atomic_compare_and_exchange_val_acq (&(descr)->member, new, old)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifndef THREAD_ATOMIC_BIT_SET
Packit 6c4009
# define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
Packit 6c4009
  atomic_bit_set (&(descr)->member, bit)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Adaptive mutex definitions.  */
Packit 6c4009
#ifndef MAX_ADAPTIVE_COUNT
Packit 6c4009
# define MAX_ADAPTIVE_COUNT 100
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Magic cookie representing robust mutex with dead owner.  */
Packit 6c4009
#define PTHREAD_MUTEX_INCONSISTENT	INT_MAX
Packit 6c4009
/* Magic cookie representing not recoverable robust mutex.  */
Packit 6c4009
#define PTHREAD_MUTEX_NOTRECOVERABLE	(INT_MAX - 1)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Internal mutex type value.  */
Packit 6c4009
enum
Packit 6c4009
{
Packit 6c4009
  PTHREAD_MUTEX_KIND_MASK_NP = 3,
Packit 6c4009
Packit 6c4009
  PTHREAD_MUTEX_ELISION_NP    = 256,
Packit 6c4009
  PTHREAD_MUTEX_NO_ELISION_NP = 512,
Packit 6c4009
Packit 6c4009
  PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
Packit 6c4009
  PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP
Packit 6c4009
  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
Packit 6c4009
  PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_PRIO_INHERIT_NP = 32,
Packit 6c4009
  PTHREAD_MUTEX_PI_NORMAL_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_NORMAL,
Packit 6c4009
  PTHREAD_MUTEX_PI_RECURSIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_PI_ERRORCHECK_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
Packit 6c4009
  PTHREAD_MUTEX_PI_ADAPTIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP,
Packit 6c4009
  PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_RECURSIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP,
Packit 6c4009
  PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_PRIO_PROTECT_NP = 64,
Packit 6c4009
  PTHREAD_MUTEX_PP_NORMAL_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_NORMAL,
Packit 6c4009
  PTHREAD_MUTEX_PP_RECURSIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_PP_ERRORCHECK_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
Packit 6c4009
  PTHREAD_MUTEX_PP_ADAPTIVE_NP
Packit 6c4009
  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
Packit 6c4009
  PTHREAD_MUTEX_ELISION_FLAGS_NP
Packit 6c4009
  = PTHREAD_MUTEX_ELISION_NP | PTHREAD_MUTEX_NO_ELISION_NP,
Packit 6c4009
Packit 6c4009
  PTHREAD_MUTEX_TIMED_ELISION_NP =
Packit 6c4009
	  PTHREAD_MUTEX_TIMED_NP | PTHREAD_MUTEX_ELISION_NP,
Packit 6c4009
  PTHREAD_MUTEX_TIMED_NO_ELISION_NP =
Packit 6c4009
	  PTHREAD_MUTEX_TIMED_NP | PTHREAD_MUTEX_NO_ELISION_NP,
Packit 6c4009
};
Packit 6c4009
#define PTHREAD_MUTEX_PSHARED_BIT 128
Packit 6c4009
Packit Service 9c85dd
/* See concurrency notes regarding __kind in struct __pthread_mutex_s
Packit Service 9c85dd
   in sysdeps/nptl/bits/thread-shared-types.h.  */
Packit 6c4009
#define PTHREAD_MUTEX_TYPE(m) \
Packit Service 9c85dd
  (atomic_load_relaxed (&((m)->__data.__kind)) & 127)
Packit 6c4009
/* Don't include NO_ELISION, as that type is always the same
Packit 6c4009
   as the underlying lock type.  */
Packit 6c4009
#define PTHREAD_MUTEX_TYPE_ELISION(m) \
Packit Service 9c85dd
  (atomic_load_relaxed (&((m)->__data.__kind))	\
Packit Service 9c85dd
   & (127 | PTHREAD_MUTEX_ELISION_NP))
Packit 6c4009
Packit 6c4009
#if LLL_PRIVATE == 0 && LLL_SHARED == 128
Packit 6c4009
# define PTHREAD_MUTEX_PSHARED(m) \
Packit Service 9c85dd
  (atomic_load_relaxed (&((m)->__data.__kind)) & 128)
Packit 6c4009
#else
Packit 6c4009
# define PTHREAD_MUTEX_PSHARED(m) \
Packit Service 9c85dd
  ((atomic_load_relaxed (&((m)->__data.__kind)) & 128)	\
Packit Service 9c85dd
   ? LLL_SHARED : LLL_PRIVATE)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* The kernel when waking robust mutexes on exit never uses
Packit 6c4009
   FUTEX_PRIVATE_FLAG FUTEX_WAKE.  */
Packit 6c4009
#define PTHREAD_ROBUST_MUTEX_PSHARED(m) LLL_SHARED
Packit 6c4009
Packit 6c4009
/* Ceiling in __data.__lock.  __data.__lock is signed, so don't
Packit 6c4009
   use the MSB bit in there, but in the mask also include that bit,
Packit 6c4009
   so that the compiler can optimize & PTHREAD_MUTEX_PRIO_CEILING_MASK
Packit 6c4009
   masking if the value is then shifted down by
Packit 6c4009
   PTHREAD_MUTEX_PRIO_CEILING_SHIFT.  */
Packit 6c4009
#define PTHREAD_MUTEX_PRIO_CEILING_SHIFT	19
Packit 6c4009
#define PTHREAD_MUTEX_PRIO_CEILING_MASK		0xfff80000
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Flags in mutex attr.  */
Packit 6c4009
#define PTHREAD_MUTEXATTR_PROTOCOL_SHIFT	28
Packit 6c4009
#define PTHREAD_MUTEXATTR_PROTOCOL_MASK		0x30000000
Packit 6c4009
#define PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT	12
Packit 6c4009
#define PTHREAD_MUTEXATTR_PRIO_CEILING_MASK	0x00fff000
Packit 6c4009
#define PTHREAD_MUTEXATTR_FLAG_ROBUST		0x40000000
Packit 6c4009
#define PTHREAD_MUTEXATTR_FLAG_PSHARED		0x80000000
Packit 6c4009
#define PTHREAD_MUTEXATTR_FLAG_BITS \
Packit 6c4009
  (PTHREAD_MUTEXATTR_FLAG_ROBUST | PTHREAD_MUTEXATTR_FLAG_PSHARED \
Packit 6c4009
   | PTHREAD_MUTEXATTR_PROTOCOL_MASK | PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* For the following, see pthread_rwlock_common.c.  */
Packit 6c4009
#define PTHREAD_RWLOCK_WRPHASE		1
Packit 6c4009
#define PTHREAD_RWLOCK_WRLOCKED		2
Packit 6c4009
#define PTHREAD_RWLOCK_RWAITING		4
Packit 6c4009
#define PTHREAD_RWLOCK_READER_SHIFT	3
Packit 6c4009
#define PTHREAD_RWLOCK_READER_OVERFLOW	((unsigned int) 1 \
Packit 6c4009
					 << (sizeof (unsigned int) * 8 - 1))
Packit 6c4009
#define PTHREAD_RWLOCK_WRHANDOVER	((unsigned int) 1 \
Packit 6c4009
					 << (sizeof (unsigned int) * 8 - 1))
Packit 6c4009
#define PTHREAD_RWLOCK_FUTEX_USED	2
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Bits used in robust mutex implementation.  */
Packit 6c4009
#define FUTEX_WAITERS		0x80000000
Packit 6c4009
#define FUTEX_OWNER_DIED	0x40000000
Packit 6c4009
#define FUTEX_TID_MASK		0x3fffffff
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* pthread_once definitions.  See __pthread_once for how these are used.  */
Packit 6c4009
#define __PTHREAD_ONCE_INPROGRESS	1
Packit 6c4009
#define __PTHREAD_ONCE_DONE		2
Packit 6c4009
#define __PTHREAD_ONCE_FORK_GEN_INCR	4
Packit 6c4009
Packit 6c4009
/* Attribute to indicate thread creation was issued from C11 thrd_create.  */
Packit 6c4009
#define ATTR_C11_THREAD ((void*)(uintptr_t)-1)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Condition variable definitions.  See __pthread_cond_wait_common.
Packit 6c4009
   Need to be defined here so there is one place from which
Packit 6c4009
   nptl_lock_constants can grab them.  */
Packit 6c4009
#define __PTHREAD_COND_CLOCK_MONOTONIC_MASK 2
Packit 6c4009
#define __PTHREAD_COND_SHARED_MASK 1
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Internal variables.  */
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Default pthread attributes.  */
Packit 6c4009
extern struct pthread_attr __default_pthread_attr attribute_hidden;
Packit 6c4009
extern int __default_pthread_attr_lock attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Size and alignment of static TLS block.  */
Packit 6c4009
extern size_t __static_tls_size attribute_hidden;
Packit 6c4009
extern size_t __static_tls_align_m1 attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Flag whether the machine is SMP or not.  */
Packit 6c4009
extern int __is_smp attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Thread descriptor handling.  */
Packit 6c4009
extern list_t __stack_user;
Packit 6c4009
hidden_proto (__stack_user)
Packit 6c4009
Packit 6c4009
/* Attribute handling.  */
Packit 6c4009
extern struct pthread_attr *__attr_list attribute_hidden;
Packit 6c4009
extern int __attr_list_lock attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Concurrency handling.  */
Packit 6c4009
extern int __concurrency_level attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Thread-local data key handling.  */
Packit 6c4009
extern struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX];
Packit 6c4009
hidden_proto (__pthread_keys)
Packit 6c4009
Packit 6c4009
/* Number of threads running.  */
Packit 6c4009
extern unsigned int __nptl_nthreads attribute_hidden;
Packit 6c4009
Packit 6c4009
#ifndef __ASSUME_SET_ROBUST_LIST
Packit 6c4009
/* Negative if we do not have the system call and we can use it.  */
Packit 6c4009
extern int __set_robust_list_avail attribute_hidden;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Thread Priority Protection.  */
Packit 6c4009
extern int __sched_fifo_min_prio attribute_hidden;
Packit 6c4009
extern int __sched_fifo_max_prio attribute_hidden;
Packit 6c4009
extern void __init_sched_fifo_prio (void) attribute_hidden;
Packit 6c4009
extern int __pthread_tpp_change_priority (int prev_prio, int new_prio)
Packit 6c4009
     attribute_hidden;
Packit 6c4009
extern int __pthread_current_priority (void) attribute_hidden;
Packit 6c4009
Packit 6c4009
/* The library can run in debugging mode where it performs a lot more
Packit 6c4009
   tests.  */
Packit 6c4009
extern int __pthread_debug attribute_hidden;
Packit 6c4009
/** For now disable debugging support.  */
Packit 6c4009
#if 0
Packit 6c4009
# define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
Packit 6c4009
# define INVALID_TD_P(pd) (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
Packit 6c4009
# define INVALID_NOT_TERMINATED_TD_P(pd) INVALID_TD_P (pd)
Packit 6c4009
#else
Packit 6c4009
# define DEBUGGING_P 0
Packit 6c4009
/* Simplified test.  This will not catch all invalid descriptors but
Packit 6c4009
   is better than nothing.  And if the test triggers the thread
Packit 6c4009
   descriptor is guaranteed to be invalid.  */
Packit 6c4009
# define INVALID_TD_P(pd) __builtin_expect ((pd)->tid <= 0, 0)
Packit 6c4009
# define INVALID_NOT_TERMINATED_TD_P(pd) __builtin_expect ((pd)->tid < 0, 0)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Cancellation test.  */
Packit 6c4009
#define CANCELLATION_P(self) \
Packit 6c4009
  do {									      \
Packit 6c4009
    int cancelhandling = THREAD_GETMEM (self, cancelhandling);		      \
Packit 6c4009
    if (CANCEL_ENABLED_AND_CANCELED (cancelhandling))			      \
Packit 6c4009
      {									      \
Packit 6c4009
	THREAD_SETMEM (self, result, PTHREAD_CANCELED);			      \
Packit 6c4009
	__do_cancel ();							      \
Packit 6c4009
      }									      \
Packit 6c4009
  } while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
extern void __pthread_unwind (__pthread_unwind_buf_t *__buf)
Packit 6c4009
     __cleanup_fct_attribute __attribute ((__noreturn__))
Packit 6c4009
#if !defined SHARED && !IS_IN (libpthread)
Packit 6c4009
     weak_function
Packit 6c4009
#endif
Packit 6c4009
     ;
Packit 6c4009
extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
Packit 6c4009
     __cleanup_fct_attribute __attribute ((__noreturn__))
Packit 6c4009
#ifndef SHARED
Packit 6c4009
     weak_function
Packit 6c4009
#endif
Packit 6c4009
     ;
Packit 6c4009
extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
Packit 6c4009
     __cleanup_fct_attribute;
Packit 6c4009
extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
Packit 6c4009
     __cleanup_fct_attribute;
Packit 6c4009
#if IS_IN (libpthread)
Packit 6c4009
hidden_proto (__pthread_unwind)
Packit 6c4009
hidden_proto (__pthread_unwind_next)
Packit 6c4009
hidden_proto (__pthread_register_cancel)
Packit 6c4009
hidden_proto (__pthread_unregister_cancel)
Packit 6c4009
# ifdef SHARED
Packit 6c4009
extern void attribute_hidden pthread_cancel_init (void);
Packit 6c4009
# endif
Packit 6c4009
extern void __nptl_unwind_freeres (void) attribute_hidden;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Called when a thread reacts on a cancellation request.  */
Packit 6c4009
static inline void
Packit 6c4009
__attribute ((noreturn, always_inline))
Packit 6c4009
__do_cancel (void)
Packit 6c4009
{
Packit 6c4009
  struct pthread *self = THREAD_SELF;
Packit 6c4009
Packit 6c4009
  /* Make sure we get no more cancellations.  */
Packit 6c4009
  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
Packit 6c4009
Packit 6c4009
  __pthread_unwind ((__pthread_unwind_buf_t *)
Packit 6c4009
		    THREAD_GETMEM (self, cleanup_jmp_buf));
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Set cancellation mode to asynchronous.  */
Packit 6c4009
#define CANCEL_ASYNC() \
Packit 6c4009
  __pthread_enable_asynccancel ()
Packit 6c4009
/* Reset to previous cancellation mode.  */
Packit 6c4009
#define CANCEL_RESET(oldtype) \
Packit 6c4009
  __pthread_disable_asynccancel (oldtype)
Packit 6c4009
Packit 6c4009
#if IS_IN (libc)
Packit 6c4009
/* Same as CANCEL_ASYNC, but for use in libc.so.  */
Packit 6c4009
# define LIBC_CANCEL_ASYNC() \
Packit 6c4009
  __libc_enable_asynccancel ()
Packit 6c4009
/* Same as CANCEL_RESET, but for use in libc.so.  */
Packit 6c4009
# define LIBC_CANCEL_RESET(oldtype) \
Packit 6c4009
  __libc_disable_asynccancel (oldtype)
Packit 6c4009
# define LIBC_CANCEL_HANDLED() \
Packit 6c4009
  __asm (".globl " __SYMBOL_PREFIX "__libc_enable_asynccancel"); \
Packit 6c4009
  __asm (".globl " __SYMBOL_PREFIX "__libc_disable_asynccancel")
Packit 6c4009
#elif IS_IN (libpthread)
Packit 6c4009
# define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
Packit 6c4009
# define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
Packit 6c4009
# define LIBC_CANCEL_HANDLED() \
Packit 6c4009
  __asm (".globl " __SYMBOL_PREFIX "__pthread_enable_asynccancel"); \
Packit 6c4009
  __asm (".globl " __SYMBOL_PREFIX "__pthread_disable_asynccancel")
Packit 6c4009
#elif IS_IN (librt)
Packit 6c4009
# define LIBC_CANCEL_ASYNC() \
Packit 6c4009
  __librt_enable_asynccancel ()
Packit 6c4009
# define LIBC_CANCEL_RESET(val) \
Packit 6c4009
  __librt_disable_asynccancel (val)
Packit 6c4009
# define LIBC_CANCEL_HANDLED() \
Packit 6c4009
  __asm (".globl " __SYMBOL_PREFIX "__librt_enable_asynccancel"); \
Packit 6c4009
  __asm (".globl " __SYMBOL_PREFIX "__librt_disable_asynccancel")
Packit 6c4009
#else
Packit 6c4009
# define LIBC_CANCEL_ASYNC()	0 /* Just a dummy value.  */
Packit 6c4009
# define LIBC_CANCEL_RESET(val)	((void)(val)) /* Nothing, but evaluate it.  */
Packit 6c4009
# define LIBC_CANCEL_HANDLED()	/* Nothing.  */
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Internal prototypes.  */
Packit 6c4009
Packit 6c4009
/* Thread list handling.  */
Packit 6c4009
extern struct pthread *__find_in_stack_list (struct pthread *pd)
Packit 6c4009
     attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Deallocate a thread's stack after optionally making sure the thread
Packit 6c4009
   descriptor is still valid.  */
Packit 6c4009
extern void __free_tcb (struct pthread *pd) attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Free allocated stack.  */
Packit 6c4009
extern void __deallocate_stack (struct pthread *pd) attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Mark all the stacks except for the current one as available.  This
Packit 6c4009
   function also re-initializes the lock for the stack cache.  */
Packit 6c4009
extern void __reclaim_stacks (void) attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Make all threads's stacks executable.  */
Packit 6c4009
extern int __make_stacks_executable (void **stack_endp) attribute_hidden;
Packit 6c4009
Packit 6c4009
/* longjmp handling.  */
Packit 6c4009
extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
Packit 6c4009
#if IS_IN (libpthread)
Packit 6c4009
hidden_proto (__pthread_cleanup_upto)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Functions with versioned interfaces.  */
Packit 6c4009
extern int __pthread_create_2_1 (pthread_t *newthread,
Packit 6c4009
				 const pthread_attr_t *attr,
Packit 6c4009
				 void *(*start_routine) (void *), void *arg);
Packit 6c4009
extern int __pthread_create_2_0 (pthread_t *newthread,
Packit 6c4009
				 const pthread_attr_t *attr,
Packit 6c4009
				 void *(*start_routine) (void *), void *arg);
Packit 6c4009
extern int __pthread_attr_init_2_1 (pthread_attr_t *attr);
Packit 6c4009
extern int __pthread_attr_init_2_0 (pthread_attr_t *attr);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Event handlers for libthread_db interface.  */
Packit 6c4009
extern void __nptl_create_event (void);
Packit 6c4009
extern void __nptl_death_event (void);
Packit 6c4009
hidden_proto (__nptl_create_event)
Packit 6c4009
hidden_proto (__nptl_death_event)
Packit 6c4009
Packit 6c4009
/* Register the generation counter in the libpthread with the libc.  */
Packit 6c4009
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
Packit 6c4009
extern void __libc_pthread_init (unsigned long int *ptr,
Packit 6c4009
				 void (*reclaim) (void),
Packit 6c4009
				 const struct pthread_functions *functions);
Packit 6c4009
#else
Packit 6c4009
extern int *__libc_pthread_init (unsigned long int *ptr,
Packit 6c4009
				 void (*reclaim) (void),
Packit 6c4009
				 const struct pthread_functions *functions);
Packit 6c4009
Packit 6c4009
/* Variable set to a nonzero value either if more than one thread runs or ran,
Packit 6c4009
   or if a single-threaded process is trying to cancel itself.  See
Packit 6c4009
   nptl/descr.h for more context on the single-threaded process case.  */
Packit 6c4009
extern int __pthread_multiple_threads attribute_hidden;
Packit 6c4009
/* Pointer to the corresponding variable in libc.  */
Packit 6c4009
extern int *__libc_multiple_threads_ptr attribute_hidden;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
Packit 6c4009
Packit 6c4009
extern size_t __pthread_get_minstack (const pthread_attr_t *attr);
Packit 6c4009
Packit 6c4009
/* Namespace save aliases.  */
Packit 6c4009
extern int __pthread_getschedparam (pthread_t thread_id, int *policy,
Packit 6c4009
				    struct sched_param *param);
Packit 6c4009
extern int __pthread_setschedparam (pthread_t thread_id, int policy,
Packit 6c4009
				    const struct sched_param *param);
Packit 6c4009
extern int __pthread_setcancelstate (int state, int *oldstate);
Packit 6c4009
extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
Packit 6c4009
				 const pthread_mutexattr_t *__mutexattr);
Packit 6c4009
extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
Packit 6c4009
extern int __pthread_mutex_trylock (pthread_mutex_t *_mutex);
Packit 6c4009
extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
Packit 6c4009
extern int __pthread_mutex_timedlock (pthread_mutex_t *__mutex,
Packit 6c4009
     const struct timespec *__abstime);
Packit 6c4009
extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
Packit 6c4009
     attribute_hidden;
Packit 6c4009
extern void __pthread_mutex_cond_lock_adjust (pthread_mutex_t *__mutex)
Packit 6c4009
     attribute_hidden;
Packit 6c4009
extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
Packit 6c4009
extern int __pthread_mutex_unlock_usercnt (pthread_mutex_t *__mutex,
Packit 6c4009
					   int __decr) attribute_hidden;
Packit 6c4009
extern int __pthread_mutexattr_init (pthread_mutexattr_t *attr);
Packit 6c4009
extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *attr);
Packit 6c4009
extern int __pthread_mutexattr_settype (pthread_mutexattr_t *attr, int kind);
Packit 6c4009
extern int __pthread_attr_destroy (pthread_attr_t *attr);
Packit 6c4009
extern int __pthread_attr_getdetachstate (const pthread_attr_t *attr,
Packit 6c4009
					  int *detachstate);
Packit 6c4009
extern int __pthread_attr_setdetachstate (pthread_attr_t *attr,
Packit 6c4009
					  int detachstate);
Packit 6c4009
extern int __pthread_attr_getinheritsched (const pthread_attr_t *attr,
Packit 6c4009
					   int *inherit);
Packit 6c4009
extern int __pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit);
Packit 6c4009
extern int __pthread_attr_getschedparam (const pthread_attr_t *attr,
Packit 6c4009
					 struct sched_param *param);
Packit 6c4009
extern int __pthread_attr_setschedparam (pthread_attr_t *attr,
Packit 6c4009
					 const struct sched_param *param);
Packit 6c4009
extern int __pthread_attr_getschedpolicy (const pthread_attr_t *attr,
Packit 6c4009
					  int *policy);
Packit 6c4009
extern int __pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
Packit 6c4009
extern int __pthread_attr_getscope (const pthread_attr_t *attr, int *scope);
Packit 6c4009
extern int __pthread_attr_setscope (pthread_attr_t *attr, int scope);
Packit 6c4009
extern int __pthread_attr_getstackaddr (const pthread_attr_t *__restrict
Packit 6c4009
					__attr, void **__restrict __stackaddr);
Packit 6c4009
extern int __pthread_attr_setstackaddr (pthread_attr_t *__attr,
Packit 6c4009
					void *__stackaddr);
Packit 6c4009
extern int __pthread_attr_getstacksize (const pthread_attr_t *__restrict
Packit 6c4009
					__attr,
Packit 6c4009
					size_t *__restrict __stacksize);
Packit 6c4009
extern int __pthread_attr_setstacksize (pthread_attr_t *__attr,
Packit 6c4009
					size_t __stacksize);
Packit 6c4009
extern int __pthread_attr_getstack (const pthread_attr_t *__restrict __attr,
Packit 6c4009
				    void **__restrict __stackaddr,
Packit 6c4009
				    size_t *__restrict __stacksize);
Packit 6c4009
extern int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
Packit 6c4009
				    size_t __stacksize);
Packit 6c4009
extern int __pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
Packit 6c4009
				  const pthread_rwlockattr_t *__restrict
Packit 6c4009
				  __attr);
Packit 6c4009
extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
Packit 6c4009
extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
Packit 6c4009
extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
Packit 6c4009
extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
Packit 6c4009
extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
Packit 6c4009
extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
Packit 6c4009
extern int __pthread_cond_broadcast (pthread_cond_t *cond);
Packit 6c4009
extern int __pthread_cond_destroy (pthread_cond_t *cond);
Packit 6c4009
extern int __pthread_cond_init (pthread_cond_t *cond,
Packit 6c4009
				const pthread_condattr_t *cond_attr);
Packit 6c4009
extern int __pthread_cond_signal (pthread_cond_t *cond);
Packit 6c4009
extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
Packit 6c4009
extern int __pthread_cond_timedwait (pthread_cond_t *cond,
Packit 6c4009
				     pthread_mutex_t *mutex,
Packit 6c4009
				     const struct timespec *abstime);
Packit 6c4009
extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
Packit 6c4009
extern int __pthread_condattr_init (pthread_condattr_t *attr);
Packit 6c4009
extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));
Packit 6c4009
extern int __pthread_key_delete (pthread_key_t key);
Packit 6c4009
extern void *__pthread_getspecific (pthread_key_t key);
Packit 6c4009
extern int __pthread_setspecific (pthread_key_t key, const void *value);
Packit 6c4009
extern int __pthread_once (pthread_once_t *once_control,
Packit 6c4009
			   void (*init_routine) (void));
Packit 6c4009
extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void),
Packit 6c4009
			     void (*child) (void));
Packit 6c4009
extern pthread_t __pthread_self (void);
Packit 6c4009
extern int __pthread_equal (pthread_t thread1, pthread_t thread2);
Packit 6c4009
extern int __pthread_detach (pthread_t th);
Packit 6c4009
extern int __pthread_cancel (pthread_t th);
Packit 6c4009
extern int __pthread_kill (pthread_t threadid, int signo);
Packit 6c4009
extern void __pthread_exit (void *value) __attribute__ ((__noreturn__));
Packit 6c4009
extern int __pthread_join (pthread_t threadid, void **thread_return);
Packit 6c4009
extern int __pthread_setcanceltype (int type, int *oldtype);
Packit 6c4009
extern int __pthread_enable_asynccancel (void) attribute_hidden;
Packit 6c4009
extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
Packit 6c4009
extern void __pthread_testcancel (void);
Packit 6c4009
extern int __pthread_timedjoin_ex (pthread_t, void **, const struct timespec *,
Packit 6c4009
				   bool);
Packit 6c4009
Packit 6c4009
#if IS_IN (libpthread)
Packit 6c4009
hidden_proto (__pthread_mutex_init)
Packit 6c4009
hidden_proto (__pthread_mutex_destroy)
Packit 6c4009
hidden_proto (__pthread_mutex_lock)
Packit 6c4009
hidden_proto (__pthread_mutex_trylock)
Packit 6c4009
hidden_proto (__pthread_mutex_unlock)
Packit 6c4009
hidden_proto (__pthread_rwlock_rdlock)
Packit 6c4009
hidden_proto (__pthread_rwlock_wrlock)
Packit 6c4009
hidden_proto (__pthread_rwlock_unlock)
Packit 6c4009
hidden_proto (__pthread_key_create)
Packit 6c4009
hidden_proto (__pthread_getspecific)
Packit 6c4009
hidden_proto (__pthread_setspecific)
Packit 6c4009
hidden_proto (__pthread_once)
Packit 6c4009
hidden_proto (__pthread_setcancelstate)
Packit 6c4009
hidden_proto (__pthread_testcancel)
Packit 6c4009
hidden_proto (__pthread_mutexattr_init)
Packit 6c4009
hidden_proto (__pthread_mutexattr_settype)
Packit 6c4009
hidden_proto (__pthread_timedjoin_ex)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond);
Packit 6c4009
extern int __pthread_cond_destroy_2_0 (pthread_cond_2_0_t *cond);
Packit 6c4009
extern int __pthread_cond_init_2_0 (pthread_cond_2_0_t *cond,
Packit 6c4009
				    const pthread_condattr_t *cond_attr);
Packit 6c4009
extern int __pthread_cond_signal_2_0 (pthread_cond_2_0_t *cond);
Packit 6c4009
extern int __pthread_cond_timedwait_2_0 (pthread_cond_2_0_t *cond,
Packit 6c4009
					 pthread_mutex_t *mutex,
Packit 6c4009
					 const struct timespec *abstime);
Packit 6c4009
extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond,
Packit 6c4009
				    pthread_mutex_t *mutex);
Packit 6c4009
Packit 6c4009
extern int __pthread_getaffinity_np (pthread_t th, size_t cpusetsize,
Packit 6c4009
				     cpu_set_t *cpuset);
Packit 6c4009
Packit 6c4009
/* The two functions are in libc.so and not exported.  */
Packit 6c4009
extern int __libc_enable_asynccancel (void) attribute_hidden;
Packit 6c4009
extern void __libc_disable_asynccancel (int oldtype) attribute_hidden;
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* The two functions are in librt.so and not exported.  */
Packit 6c4009
extern int __librt_enable_asynccancel (void) attribute_hidden;
Packit 6c4009
extern void __librt_disable_asynccancel (int oldtype) attribute_hidden;
Packit 6c4009
Packit 6c4009
#if IS_IN (libpthread)
Packit 6c4009
/* Special versions which use non-exported functions.  */
Packit 6c4009
extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
				    void (*routine) (void *), void *arg)
Packit 6c4009
     attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Replace cleanup macros defined in <pthread.h> with internal
Packit 6c4009
   versions that don't depend on unwind info and better support
Packit 6c4009
   cancellation.  */
Packit 6c4009
# undef pthread_cleanup_push
Packit 6c4009
# define pthread_cleanup_push(routine,arg)              \
Packit 6c4009
  { struct _pthread_cleanup_buffer _buffer;             \
Packit 6c4009
  __pthread_cleanup_push (&_buffer, (routine), (arg));
Packit 6c4009
Packit 6c4009
extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
				   int execute) attribute_hidden;
Packit 6c4009
# undef pthread_cleanup_pop
Packit 6c4009
# define pthread_cleanup_pop(execute)                   \
Packit 6c4009
  __pthread_cleanup_pop (&_buffer, (execute)); }
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
					  void (*routine) (void *), void *arg);
Packit 6c4009
extern void __pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
					   int execute);
Packit 6c4009
Packit 6c4009
/* Old cleanup interfaces, still used in libc.so.  */
Packit 6c4009
extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
				   void (*routine) (void *), void *arg);
Packit 6c4009
extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
				  int execute);
Packit 6c4009
extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
					 void (*routine) (void *), void *arg);
Packit 6c4009
extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
Packit 6c4009
					  int execute);
Packit 6c4009
Packit 6c4009
extern void __nptl_deallocate_tsd (void) attribute_hidden;
Packit 6c4009
Packit 6c4009
extern void __nptl_setxid_error (struct xid_command *cmdp, int error)
Packit 6c4009
  attribute_hidden;
Packit 6c4009
extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
Packit 6c4009
#ifndef SHARED
Packit 6c4009
extern void __nptl_set_robust (struct pthread *self);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
extern void __nptl_stacks_freeres (void) attribute_hidden;
Packit 6c4009
extern void __shm_directory_freeres (void) attribute_hidden;
Packit 6c4009
Packit 6c4009
extern void __wait_lookup_done (void) attribute_hidden;
Packit 6c4009
Packit 6c4009
#ifdef SHARED
Packit 6c4009
# define PTHREAD_STATIC_FN_REQUIRE(name)
Packit 6c4009
#else
Packit 6c4009
# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Returns 0 if POL is a valid scheduling policy.  */
Packit 6c4009
static inline int
Packit 6c4009
check_sched_policy_attr (int pol)
Packit 6c4009
{
Packit 6c4009
  if (pol == SCHED_OTHER || pol == SCHED_FIFO || pol == SCHED_RR)
Packit 6c4009
    return 0;
Packit 6c4009
Packit 6c4009
  return EINVAL;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Returns 0 if PR is within the accepted range of priority values for
Packit 6c4009
   the scheduling policy POL or EINVAL otherwise.  */
Packit 6c4009
static inline int
Packit 6c4009
check_sched_priority_attr (int pr, int pol)
Packit 6c4009
{
Packit 6c4009
  int min = __sched_get_priority_min (pol);
Packit 6c4009
  int max = __sched_get_priority_max (pol);
Packit 6c4009
Packit 6c4009
  if (min >= 0 && max >= 0 && pr >= min && pr <= max)
Packit 6c4009
    return 0;
Packit 6c4009
Packit 6c4009
  return EINVAL;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Returns 0 if ST is a valid stack size for a thread stack and EINVAL
Packit 6c4009
   otherwise.  */
Packit 6c4009
static inline int
Packit 6c4009
check_stacksize_attr (size_t st)
Packit 6c4009
{
Packit 6c4009
  if (st >= PTHREAD_STACK_MIN)
Packit 6c4009
    return 0;
Packit 6c4009
Packit 6c4009
  return EINVAL;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#define ASSERT_TYPE_SIZE(type, size) 					\
Packit 6c4009
  _Static_assert (sizeof (type) == size,				\
Packit 6c4009
		  "sizeof (" #type ") != " #size)
Packit 6c4009
Packit 6c4009
#define ASSERT_PTHREAD_INTERNAL_SIZE(type, internal) 			\
Packit 6c4009
  _Static_assert (sizeof ((type) { { 0 } }).__size >= sizeof (internal),\
Packit 6c4009
		  "sizeof (" #type ".__size) < sizeof (" #internal ")")
Packit 6c4009
Packit 6c4009
#define ASSERT_PTHREAD_STRING(x) __STRING (x)
Packit 6c4009
#define ASSERT_PTHREAD_INTERNAL_OFFSET(type, member, offset)		\
Packit 6c4009
  _Static_assert (offsetof (type, member) == offset,			\
Packit 6c4009
		  "offset of " #member " field of " #type " != "	\
Packit 6c4009
		  ASSERT_PTHREAD_STRING (offset))
Packit 6c4009
Packit 6c4009
#endif	/* pthreadP.h */