|
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 |
a13c75 |
binary compatibility with static initializers.
|
|
Packit Service |
a13c75 |
|
|
Packit Service |
a13c75 |
Concurrency notes:
|
|
Packit Service |
a13c75 |
The __kind of a mutex is initialized either by the static
|
|
Packit Service |
a13c75 |
PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init.
|
|
Packit Service |
a13c75 |
|
|
Packit Service |
a13c75 |
After a mutex has been initialized, the __kind of a mutex is usually not
|
|
Packit Service |
a13c75 |
changed. BUT it can be set to -1 in pthread_mutex_destroy or elision can
|
|
Packit Service |
a13c75 |
be enabled. This is done concurrently in the pthread_mutex_*lock functions
|
|
Packit Service |
a13c75 |
by using the macro FORCE_ELISION. This macro is only defined for
|
|
Packit Service |
a13c75 |
architectures which supports lock elision.
|
|
Packit Service |
a13c75 |
|
|
Packit Service |
a13c75 |
For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
|
|
Packit Service |
a13c75 |
PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set
|
|
Packit Service |
a13c75 |
type of a mutex.
|
|
Packit Service |
a13c75 |
Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set
|
|
Packit Service |
a13c75 |
with pthread_mutexattr_settype.
|
|
Packit Service |
a13c75 |
After a mutex has been initialized, the functions pthread_mutex_*lock can
|
|
Packit Service |
a13c75 |
enable elision - if the mutex-type and the machine supports it - by setting
|
|
Packit Service |
a13c75 |
the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards
|
|
Packit Service |
a13c75 |
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 */
|