Blame sysdeps/nptl/bits/thread-shared-types.h

Packit 6c4009
/* Common threading primitives definitions for both POSIX and C11.
Packit 6c4009
   Copyright (C) 2017-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 _THREAD_SHARED_TYPES_H
Packit 6c4009
#define _THREAD_SHARED_TYPES_H 1
Packit 6c4009
Packit 6c4009
/* Arch-specific definitions.  Each architecture must define the following
Packit 6c4009
   macros to define the expected sizes of pthread data types:
Packit 6c4009
Packit 6c4009
   __SIZEOF_PTHREAD_ATTR_T        - size of pthread_attr_t.
Packit 6c4009
   __SIZEOF_PTHREAD_MUTEX_T       - size of pthread_mutex_t.
Packit 6c4009
   __SIZEOF_PTHREAD_MUTEXATTR_T   - size of pthread_mutexattr_t.
Packit 6c4009
   __SIZEOF_PTHREAD_COND_T        - size of pthread_cond_t.
Packit 6c4009
   __SIZEOF_PTHREAD_CONDATTR_T    - size of pthread_condattr_t.
Packit 6c4009
   __SIZEOF_PTHREAD_RWLOCK_T      - size of pthread_rwlock_t.
Packit 6c4009
   __SIZEOF_PTHREAD_RWLOCKATTR_T  - size of pthread_rwlockattr_t.
Packit 6c4009
   __SIZEOF_PTHREAD_BARRIER_T     - size of pthread_barrier_t.
Packit 6c4009
   __SIZEOF_PTHREAD_BARRIERATTR_T - size of pthread_barrierattr_t.
Packit 6c4009
Packit 6c4009
   Also, the following macros must be define for internal pthread_mutex_t
Packit 6c4009
   struct definitions (struct __pthread_mutex_s):
Packit 6c4009
Packit 6c4009
   __PTHREAD_COMPAT_PADDING_MID   - any additional members after 'kind'
Packit 6c4009
				    and before '__spin' (for 64 bits) or
Packit 6c4009
				    '__nusers' (for 32 bits).
Packit 6c4009
   __PTHREAD_COMPAT_PADDING_END   - any additional members at the end of
Packit 6c4009
				    the internal structure.
Packit 6c4009
   __PTHREAD_MUTEX_LOCK_ELISION   - 1 if the architecture supports lock
Packit 6c4009
				    elision or 0 otherwise.
Packit 6c4009
   __PTHREAD_MUTEX_NUSERS_AFTER_KIND - control where to put __nusers.  The
Packit 6c4009
				       preferred value for new architectures
Packit 6c4009
				       is 0.
Packit 6c4009
   __PTHREAD_MUTEX_USE_UNION      - control whether internal __spins and
Packit 6c4009
				    __list will be place inside a union for
Packit 6c4009
				    linuxthreads compatibility.
Packit 6c4009
				    The preferred value for new architectures
Packit 6c4009
				    is 0.
Packit 6c4009
Packit 6c4009
   For a new port the preferred values for the required defines are:
Packit 6c4009
Packit 6c4009
   #define __PTHREAD_COMPAT_PADDING_MID
Packit 6c4009
   #define __PTHREAD_COMPAT_PADDING_END
Packit 6c4009
   #define __PTHREAD_MUTEX_LOCK_ELISION         0
Packit 6c4009
   #define __PTHREAD_MUTEX_NUSERS_AFTER_KIND    0
Packit 6c4009
   #define __PTHREAD_MUTEX_USE_UNION            0
Packit 6c4009
Packit 6c4009
   __PTHREAD_MUTEX_LOCK_ELISION can be set to 1 if the hardware plans to
Packit 6c4009
   eventually support lock elision using transactional memory.
Packit 6c4009
Packit 6c4009
   The additional macro defines any constraint for the lock alignment
Packit 6c4009
   inside the thread structures:
Packit 6c4009
Packit 6c4009
   __LOCK_ALIGNMENT - for internal lock/futex usage.
Packit 6c4009
Packit 6c4009
   Same idea but for the once locking primitive:
Packit 6c4009
Packit 6c4009
   __ONCE_ALIGNMENT - for pthread_once_t/once_flag definition.
Packit 6c4009
Packit 6c4009
   And finally the internal pthread_rwlock_t (struct __pthread_rwlock_arch_t)
Packit 6c4009
   must be defined.
Packit 6c4009
 */
Packit 6c4009
#include <bits/pthreadtypes-arch.h>
Packit 6c4009
Packit 6c4009
/* Common definition of pthread_mutex_t. */
Packit 6c4009
Packit 6c4009
#if !__PTHREAD_MUTEX_USE_UNION
Packit 6c4009
typedef struct __pthread_internal_list
Packit 6c4009
{
Packit 6c4009
  struct __pthread_internal_list *__prev;
Packit 6c4009
  struct __pthread_internal_list *__next;
Packit 6c4009
} __pthread_list_t;
Packit 6c4009
#else
Packit 6c4009
typedef struct __pthread_internal_slist
Packit 6c4009
{
Packit 6c4009
  struct __pthread_internal_slist *__next;
Packit 6c4009
} __pthread_slist_t;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Lock elision support.  */
Packit 6c4009
#if __PTHREAD_MUTEX_LOCK_ELISION
Packit 6c4009
# if !__PTHREAD_MUTEX_USE_UNION
Packit 6c4009
#  define __PTHREAD_SPINS_DATA	\
Packit 6c4009
  short __spins;		\
Packit 6c4009
  short __elision
Packit 6c4009
#  define __PTHREAD_SPINS             0, 0
Packit 6c4009
# else
Packit 6c4009
#  define __PTHREAD_SPINS_DATA	\
Packit 6c4009
  struct			\
Packit 6c4009
  {				\
Packit 6c4009
    short __espins;		\
Packit 6c4009
    short __eelision;		\
Packit 6c4009
  } __elision_data
Packit 6c4009
#  define __PTHREAD_SPINS         { 0, 0 }
Packit 6c4009
#  define __spins __elision_data.__espins
Packit 6c4009
#  define __elision __elision_data.__eelision
Packit 6c4009
# endif
Packit 6c4009
#else
Packit 6c4009
# define __PTHREAD_SPINS_DATA int __spins
Packit 6c4009
/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER.  */
Packit 6c4009
# define __PTHREAD_SPINS 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
struct __pthread_mutex_s
Packit 6c4009
{
Packit 6c4009
  int __lock __LOCK_ALIGNMENT;
Packit 6c4009
  unsigned int __count;
Packit 6c4009
  int __owner;
Packit 6c4009
#if !__PTHREAD_MUTEX_NUSERS_AFTER_KIND
Packit 6c4009
  unsigned int __nusers;
Packit 6c4009
#endif
Packit 6c4009
  /* KIND must stay at this position in the structure to maintain
Packit Service 2b441b
     binary compatibility with static initializers.
Packit Service 2b441b
Packit Service 2b441b
     Concurrency notes:
Packit Service 2b441b
     The __kind of a mutex is initialized either by the static
Packit Service 2b441b
     PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init.
Packit Service 2b441b
Packit Service 2b441b
     After a mutex has been initialized, the __kind of a mutex is usually not
Packit Service 2b441b
     changed.  BUT it can be set to -1 in pthread_mutex_destroy or elision can
Packit Service 2b441b
     be enabled.  This is done concurrently in the pthread_mutex_*lock functions
Packit Service 2b441b
     by using the macro FORCE_ELISION. This macro is only defined for
Packit Service 2b441b
     architectures which supports lock elision.
Packit Service 2b441b
Packit Service 2b441b
     For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
Packit Service 2b441b
     PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set
Packit Service 2b441b
     type of a mutex.
Packit Service 2b441b
     Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set
Packit Service 2b441b
     with pthread_mutexattr_settype.
Packit Service 2b441b
     After a mutex has been initialized, the functions pthread_mutex_*lock can
Packit Service 2b441b
     enable elision - if the mutex-type and the machine supports it - by setting
Packit Service 2b441b
     the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards
Packit Service 2b441b
     the lock / unlock functions are using specific elision code-paths.  */
Packit 6c4009
  int __kind;
Packit 6c4009
  __PTHREAD_COMPAT_PADDING_MID
Packit 6c4009
#if __PTHREAD_MUTEX_NUSERS_AFTER_KIND
Packit 6c4009
  unsigned int __nusers;
Packit 6c4009
#endif
Packit 6c4009
#if !__PTHREAD_MUTEX_USE_UNION
Packit 6c4009
  __PTHREAD_SPINS_DATA;
Packit 6c4009
  __pthread_list_t __list;
Packit 6c4009
# define __PTHREAD_MUTEX_HAVE_PREV      1
Packit 6c4009
#else
Packit 6c4009
  __extension__ union
Packit 6c4009
  {
Packit 6c4009
    __PTHREAD_SPINS_DATA;
Packit 6c4009
    __pthread_slist_t __list;
Packit 6c4009
  };
Packit 6c4009
# define __PTHREAD_MUTEX_HAVE_PREV      0
Packit 6c4009
#endif
Packit 6c4009
  __PTHREAD_COMPAT_PADDING_END
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Common definition of pthread_cond_t. */
Packit 6c4009
Packit 6c4009
struct __pthread_cond_s
Packit 6c4009
{
Packit 6c4009
  __extension__ union
Packit 6c4009
  {
Packit 6c4009
    __extension__ unsigned long long int __wseq;
Packit 6c4009
    struct
Packit 6c4009
    {
Packit 6c4009
      unsigned int __low;
Packit 6c4009
      unsigned int __high;
Packit 6c4009
    } __wseq32;
Packit 6c4009
  };
Packit 6c4009
  __extension__ union
Packit 6c4009
  {
Packit 6c4009
    __extension__ unsigned long long int __g1_start;
Packit 6c4009
    struct
Packit 6c4009
    {
Packit 6c4009
      unsigned int __low;
Packit 6c4009
      unsigned int __high;
Packit 6c4009
    } __g1_start32;
Packit 6c4009
  };
Packit 6c4009
  unsigned int __g_refs[2] __LOCK_ALIGNMENT;
Packit 6c4009
  unsigned int __g_size[2];
Packit 6c4009
  unsigned int __g1_orig_size;
Packit 6c4009
  unsigned int __wrefs;
Packit 6c4009
  unsigned int __g_signals[2];
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
#endif /* _THREAD_SHARED_TYPES_H  */