Blame htl/pt-internal.h

Packit 6c4009
/* Internal defenitions for pthreads library.
Packit 6c4009
   Copyright (C) 2000-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
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 _PT_INTERNAL_H
Packit 6c4009
#define _PT_INTERNAL_H	1
Packit 6c4009
Packit 6c4009
#include <pthread.h>
Packit 6c4009
#include <stddef.h>
Packit 6c4009
#include <sched.h>
Packit 6c4009
#include <signal.h>
Packit 6c4009
#include <assert.h>
Packit 6c4009
#include <bits/types/res_state.h>
Packit 6c4009
Packit 6c4009
#include <atomic.h>
Packit 6c4009
Packit 6c4009
#include <pt-key.h>
Packit 6c4009
Packit 6c4009
#include <pt-sysdep.h>
Packit 6c4009
#include <pt-machdep.h>
Packit 6c4009
Packit 6c4009
#if IS_IN (libpthread)
Packit 6c4009
# include <ldsodefs.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Thread state.  */
Packit 6c4009
enum pthread_state
Packit 6c4009
{
Packit 6c4009
  /* The thread is running and joinable.  */
Packit 6c4009
  PTHREAD_JOINABLE = 0,
Packit 6c4009
  /* The thread is running and detached.  */
Packit 6c4009
  PTHREAD_DETACHED,
Packit 6c4009
  /* A joinable thread exited and its return code is available.  */
Packit 6c4009
  PTHREAD_EXITED,
Packit 6c4009
  /* The thread structure is unallocated and available for reuse.  */
Packit 6c4009
  PTHREAD_TERMINATED
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
#ifndef PTHREAD_KEY_MEMBERS
Packit 6c4009
# define PTHREAD_KEY_MEMBERS
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifndef PTHREAD_SYSDEP_MEMBERS
Packit 6c4009
# define PTHREAD_SYSDEP_MEMBERS
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if !(IS_IN (libpthread))
Packit 6c4009
/* Type of the TCB.  */
Packit 6c4009
typedef struct
Packit 6c4009
{
Packit 6c4009
  void *tcb;			/* Points to this structure.  */
Packit 6c4009
  void *dtv;			/* Vector of pointers to TLS data.  */
Packit 6c4009
  thread_t self;		/* This thread's control port.  */
Packit 6c4009
} tcbhead_t;
Packit 6c4009
#endif /* ! IS_IN (libpthread) */
Packit 6c4009
Packit 6c4009
/* This structure describes a POSIX thread.  */
Packit 6c4009
struct __pthread
Packit 6c4009
{
Packit 6c4009
  /* Thread ID.  */
Packit 6c4009
  pthread_t thread;
Packit 6c4009
Packit 6c4009
  unsigned int nr_refs;		/* Detached threads have a self reference only,
Packit 6c4009
				   while joinable threads have two references.
Packit 6c4009
				   These are used to keep the structure valid at
Packit 6c4009
				   thread destruction.  Detaching/joining a thread
Packit 6c4009
				   drops a reference.  */
Packit 6c4009
Packit 6c4009
  /* Cancellation.  */
Packit 6c4009
  pthread_mutex_t cancel_lock;	/* Protect cancel_xxx members.  */
Packit 6c4009
  void (*cancel_hook) (void *);	/* Called to unblock a thread blocking
Packit 6c4009
				   in a cancellation point (namely,
Packit 6c4009
				   __pthread_cond_timedwait_internal).  */
Packit 6c4009
  void *cancel_hook_arg;
Packit 6c4009
  int cancel_state;
Packit 6c4009
  int cancel_type;
Packit 6c4009
  int cancel_pending;
Packit 6c4009
  struct __pthread_cancelation_handler *cancelation_handlers;
Packit 6c4009
Packit 6c4009
  /* Thread stack.  */
Packit 6c4009
  void *stackaddr;
Packit 6c4009
  size_t stacksize;
Packit 6c4009
  size_t guardsize;
Packit 6c4009
  int stack;			/* Nonzero if the stack was allocated.  */
Packit 6c4009
Packit 6c4009
  /* Exit status.  */
Packit 6c4009
  void *status;
Packit 6c4009
Packit 6c4009
  /* Thread state.  */
Packit 6c4009
  enum pthread_state state;
Packit 6c4009
  pthread_mutex_t state_lock;	/* Locks the state.  */
Packit 6c4009
  pthread_cond_t state_cond;	/* Signalled when the state changes.  */
Packit 6c4009
Packit 6c4009
  /* Resolver state.  */
Packit 6c4009
  struct __res_state res_state;
Packit 6c4009
Packit 6c4009
  /* Thread context.  */
Packit 6c4009
  struct pthread_mcontext mcontext;
Packit 6c4009
Packit 6c4009
  PTHREAD_KEY_MEMBERS
Packit 6c4009
Packit 6c4009
  PTHREAD_SYSDEP_MEMBERS
Packit 6c4009
Packit 6c4009
  tcbhead_t *tcb;
Packit 6c4009
Packit 6c4009
  /* Queue links.  Since PREVP is used to determine if a thread has been
Packit 6c4009
     awaken, it must be protected by the queue lock.  */
Packit 6c4009
  struct __pthread *next, **prevp;
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/* Enqueue an element THREAD on the queue *HEAD.  */
Packit 6c4009
static inline void
Packit 6c4009
__pthread_enqueue (struct __pthread **head, struct __pthread *thread)
Packit 6c4009
{
Packit 6c4009
  assert (thread->prevp == 0);
Packit 6c4009
Packit 6c4009
  thread->next = *head;
Packit 6c4009
  thread->prevp = head;
Packit 6c4009
  if (*head)
Packit 6c4009
    (*head)->prevp = &thread->next;
Packit 6c4009
  *head = thread;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Dequeue the element THREAD from the queue it is connected to.  */
Packit 6c4009
static inline void
Packit 6c4009
__pthread_dequeue (struct __pthread *thread)
Packit 6c4009
{
Packit 6c4009
  assert (thread);
Packit 6c4009
  assert (thread->prevp);
Packit 6c4009
Packit 6c4009
  if (thread->next)
Packit 6c4009
    thread->next->prevp = thread->prevp;
Packit 6c4009
  *thread->prevp = thread->next;
Packit 6c4009
  thread->prevp = 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Iterate over QUEUE storing each element in ELEMENT.  */
Packit 6c4009
#define __pthread_queue_iterate(queue, element)				\
Packit 6c4009
  for (struct __pthread *__pdi_next = (queue);				\
Packit 6c4009
       ((element) = __pdi_next)						\
Packit 6c4009
	 && ((__pdi_next = __pdi_next->next),				\
Packit 6c4009
	     1);							\
Packit 6c4009
       )
Packit 6c4009
Packit 6c4009
/* Iterate over QUEUE dequeuing each element, storing it in
Packit 6c4009
   ELEMENT.  */
Packit 6c4009
#define __pthread_dequeuing_iterate(queue, element)			\
Packit 6c4009
  for (struct __pthread *__pdi_next = (queue);				\
Packit 6c4009
       ((element) = __pdi_next)						\
Packit 6c4009
	 && ((__pdi_next = __pdi_next->next),				\
Packit 6c4009
	     ((element)->prevp = 0),					\
Packit 6c4009
	     1);							\
Packit 6c4009
       )
Packit 6c4009
Packit 6c4009
/* The total number of threads currently active.  */
Packit 6c4009
extern unsigned int __pthread_total;
Packit 6c4009
Packit 6c4009
/* The total number of thread IDs currently in use, or on the list of
Packit 6c4009
   available thread IDs.  */
Packit 6c4009
extern int __pthread_num_threads;
Packit 6c4009
Packit 6c4009
/* Concurrency hint.  */
Packit 6c4009
extern int __pthread_concurrency;
Packit 6c4009
Packit 6c4009
/* Array of __pthread structures and its lock.  Indexed by the pthread
Packit 6c4009
   id minus one.  (Why not just use the pthread id?  Because some
Packit 6c4009
   brain-dead users of the pthread interface incorrectly assume that 0
Packit 6c4009
   is an invalid pthread id.)  */
Packit 6c4009
extern struct __pthread **__pthread_threads;
Packit 6c4009
extern pthread_rwlock_t __pthread_threads_lock;
Packit 6c4009
Packit 6c4009
#define __pthread_getid(thread) \
Packit 6c4009
  ({ struct __pthread *__t;                                                  \
Packit 6c4009
     __pthread_rwlock_rdlock (&__pthread_threads_lock);                      \
Packit 6c4009
     __t = __pthread_threads[thread - 1];                                    \
Packit 6c4009
     __pthread_rwlock_unlock (&__pthread_threads_lock);                      \
Packit 6c4009
     __t; })
Packit 6c4009
Packit 6c4009
#define __pthread_setid(thread, pthread) \
Packit 6c4009
  __pthread_rwlock_wrlock (&__pthread_threads_lock);                         \
Packit 6c4009
  __pthread_threads[thread - 1] = pthread;                                   \
Packit 6c4009
  __pthread_rwlock_unlock (&__pthread_threads_lock);
Packit 6c4009
Packit 6c4009
/* Similar to pthread_self, but returns the thread descriptor instead
Packit 6c4009
   of the thread ID.  */
Packit 6c4009
#ifndef _pthread_self
Packit 6c4009
extern struct __pthread *_pthread_self (void);
Packit 6c4009
#endif
Packit 6c4009

Packit 6c4009
Packit 6c4009
/* Initialize the pthreads library.  */
Packit 6c4009
extern void ___pthread_init (void);
Packit 6c4009
Packit 6c4009
/* Internal version of pthread_create.  Rather than return the new
Packit 6c4009
   tid, we return the whole __pthread structure in *PTHREAD.  */
Packit 6c4009
extern int __pthread_create_internal (struct __pthread **__restrict pthread,
Packit 6c4009
				      const pthread_attr_t *__restrict attr,
Packit 6c4009
				      void *(*start_routine) (void *),
Packit 6c4009
				      void *__restrict arg);
Packit 6c4009
Packit 6c4009
/* Allocate a new thread structure and a pthread thread ID (but not a
Packit 6c4009
   kernel thread or a stack).  THREAD has one reference.  */
Packit 6c4009
extern int __pthread_alloc (struct __pthread **thread);
Packit 6c4009
Packit 6c4009
/* Deallocate the thread structure.  This is the dual of
Packit 6c4009
   __pthread_alloc (N.B. it does not call __pthread_stack_dealloc nor
Packit 6c4009
   __pthread_thread_terminate).  THREAD loses one reference and is
Packit 6c4009
   released if the reference counter drops to 0.  */
Packit 6c4009
extern void __pthread_dealloc (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Allocate a stack of size STACKSIZE.  The stack base shall be
Packit 6c4009
   returned in *STACKADDR.  */
Packit 6c4009
extern int __pthread_stack_alloc (void **stackaddr, size_t stacksize);
Packit 6c4009
Packit 6c4009
/* Deallocate the stack STACKADDR of size STACKSIZE.  */
Packit 6c4009
extern void __pthread_stack_dealloc (void *stackaddr, size_t stacksize);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Setup thread THREAD's context.  */
Packit 6c4009
extern int __pthread_setup (struct __pthread *__restrict thread,
Packit 6c4009
			    void (*entry_point) (struct __pthread *,
Packit 6c4009
						 void *(*)(void *),
Packit 6c4009
						 void *),
Packit 6c4009
			    void *(*start_routine) (void *),
Packit 6c4009
			    void *__restrict arg);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Allocate a kernel thread (and any miscellaneous system dependent
Packit 6c4009
   resources) for THREAD; it must not be placed on the run queue.  */
Packit 6c4009
extern int __pthread_thread_alloc (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
/* Start THREAD making it eligible to run.  */
Packit 6c4009
extern int __pthread_thread_start (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
/* Terminate the kernel thread associated with THREAD, and deallocate its
Packit 6c4009
   stack as well as any other kernel resource associated with it.
Packit 6c4009
   In addition, THREAD looses one reference.
Packit 6c4009
Packit 6c4009
   This function can be called by any thread, including the target thread.
Packit 6c4009
   Since some resources that are destroyed along the kernel thread are
Packit 6c4009
   stored in thread-local variables, the conditions required for this
Packit 6c4009
   function to behave correctly are a bit unusual : as long as the target
Packit 6c4009
   thread hasn't been started, any thread can terminate it, but once it
Packit 6c4009
   has started, no other thread can terminate it, so that thread-local
Packit 6c4009
   variables created by that thread are correctly released.  */
Packit 6c4009
extern void __pthread_thread_terminate (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Called by a thread just before it calls the provided start
Packit 6c4009
   routine.  */
Packit 6c4009
extern void __pthread_startup (void);
Packit 6c4009
Packit 6c4009
/* Block THREAD.  */
Packit 6c4009
extern void __pthread_block (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
/* Block THREAD until *ABSTIME is reached.  */
Packit 6c4009
extern error_t __pthread_timedblock (struct __pthread *__restrict thread,
Packit 6c4009
				     const struct timespec *__restrict abstime,
Packit 6c4009
				     clockid_t clock_id);
Packit 6c4009
Packit 6c4009
/* Wakeup THREAD.  */
Packit 6c4009
extern void __pthread_wakeup (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Perform a cancelation.  The CANCEL_LOCK member of the given thread must
Packit 6c4009
   be locked before calling this function, which must unlock it.  */
Packit 6c4009
extern int __pthread_do_cancel (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Initialize the thread specific data structures.  THREAD must be the
Packit 6c4009
   calling thread.  */
Packit 6c4009
extern error_t __pthread_init_specific (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
/* Call the destructors on all of the thread specific data in THREAD.
Packit 6c4009
   THREAD must be the calling thread.  */
Packit 6c4009
extern void __pthread_destroy_specific (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Initialize newly create thread *THREAD's signal state data
Packit 6c4009
   structures.  */
Packit 6c4009
extern error_t __pthread_sigstate_init (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
/* Destroy the signal state data structures associcated with thread
Packit 6c4009
   *THREAD.  */
Packit 6c4009
extern void __pthread_sigstate_destroy (struct __pthread *thread);
Packit 6c4009
Packit 6c4009
/* Modify thread *THREAD's signal state.  */
Packit 6c4009
extern error_t __pthread_sigstate (struct __pthread *__restrict thread, int how,
Packit 6c4009
				   const sigset_t *__restrict set,
Packit 6c4009
				   sigset_t *__restrict oset,
Packit 6c4009
				   int clear_pending);
Packit 6c4009

Packit 6c4009
Packit 6c4009
/* Default thread attributes.  */
Packit 6c4009
extern const struct __pthread_attr __pthread_default_attr;
Packit 6c4009
Packit 6c4009
/* Default barrier attributes.  */
Packit 6c4009
extern const struct __pthread_barrierattr __pthread_default_barrierattr;
Packit 6c4009
Packit 6c4009
/* Default mutex attributes.  */
Packit 6c4009
extern const struct __pthread_mutexattr __pthread_default_mutexattr;
Packit 6c4009
Packit 6c4009
/* Default rdlock attributes.  */
Packit 6c4009
extern const struct __pthread_rwlockattr __pthread_default_rwlockattr;
Packit 6c4009
Packit 6c4009
/* Default condition attributes.  */
Packit 6c4009
extern const struct __pthread_condattr __pthread_default_condattr;
Packit 6c4009
Packit 6c4009
#endif /* pt-internal.h */