1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
| /* Common threading primitives definitions for both POSIX and C11.
Copyright (C) 2017-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
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/>. */
#ifndef _THREAD_SHARED_TYPES_H
#define _THREAD_SHARED_TYPES_H 1
/* Arch-specific definitions. Each architecture must define the following
macros to define the expected sizes of pthread data types:
__SIZEOF_PTHREAD_ATTR_T - size of pthread_attr_t.
__SIZEOF_PTHREAD_MUTEX_T - size of pthread_mutex_t.
__SIZEOF_PTHREAD_MUTEXATTR_T - size of pthread_mutexattr_t.
__SIZEOF_PTHREAD_COND_T - size of pthread_cond_t.
__SIZEOF_PTHREAD_CONDATTR_T - size of pthread_condattr_t.
__SIZEOF_PTHREAD_RWLOCK_T - size of pthread_rwlock_t.
__SIZEOF_PTHREAD_RWLOCKATTR_T - size of pthread_rwlockattr_t.
__SIZEOF_PTHREAD_BARRIER_T - size of pthread_barrier_t.
__SIZEOF_PTHREAD_BARRIERATTR_T - size of pthread_barrierattr_t.
Also, the following macros must be define for internal pthread_mutex_t
struct definitions (struct __pthread_mutex_s):
__PTHREAD_COMPAT_PADDING_MID - any additional members after 'kind'
and before '__spin' (for 64 bits) or
'__nusers' (for 32 bits).
__PTHREAD_COMPAT_PADDING_END - any additional members at the end of
the internal structure.
__PTHREAD_MUTEX_LOCK_ELISION - 1 if the architecture supports lock
elision or 0 otherwise.
__PTHREAD_MUTEX_NUSERS_AFTER_KIND - control where to put __nusers. The
preferred value for new architectures
is 0.
__PTHREAD_MUTEX_USE_UNION - control whether internal __spins and
__list will be place inside a union for
linuxthreads compatibility.
The preferred value for new architectures
is 0.
For a new port the preferred values for the required defines are:
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0
#define __PTHREAD_MUTEX_USE_UNION 0
__PTHREAD_MUTEX_LOCK_ELISION can be set to 1 if the hardware plans to
eventually support lock elision using transactional memory.
The additional macro defines any constraint for the lock alignment
inside the thread structures:
__LOCK_ALIGNMENT - for internal lock/futex usage.
Same idea but for the once locking primitive:
__ONCE_ALIGNMENT - for pthread_once_t/once_flag definition.
And finally the internal pthread_rwlock_t (struct __pthread_rwlock_arch_t)
must be defined.
*/
#include <bits/pthreadtypes-arch.h>
/* Common definition of pthread_mutex_t. */
#if !__PTHREAD_MUTEX_USE_UNION
typedef struct __pthread_internal_list
{
struct __pthread_internal_list *__prev;
struct __pthread_internal_list *__next;
} __pthread_list_t;
#else
typedef struct __pthread_internal_slist
{
struct __pthread_internal_slist *__next;
} __pthread_slist_t;
#endif
/* Lock elision support. */
#if __PTHREAD_MUTEX_LOCK_ELISION
# if !__PTHREAD_MUTEX_USE_UNION
# define __PTHREAD_SPINS_DATA \
short __spins; \
short __elision
# define __PTHREAD_SPINS 0, 0
# else
# define __PTHREAD_SPINS_DATA \
struct \
{ \
short __espins; \
short __eelision; \
} __elision_data
# define __PTHREAD_SPINS { 0, 0 }
# define __spins __elision_data.__espins
# define __elision __elision_data.__eelision
# endif
#else
# define __PTHREAD_SPINS_DATA int __spins
/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
# define __PTHREAD_SPINS 0
#endif
struct __pthread_mutex_s
{
int __lock __LOCK_ALIGNMENT;
unsigned int __count;
int __owner;
#if !__PTHREAD_MUTEX_NUSERS_AFTER_KIND
unsigned int __nusers;
#endif
/* KIND must stay at this position in the structure to maintain
binary compatibility with static initializers. */
int __kind;
__PTHREAD_COMPAT_PADDING_MID
#if __PTHREAD_MUTEX_NUSERS_AFTER_KIND
unsigned int __nusers;
#endif
#if !__PTHREAD_MUTEX_USE_UNION
__PTHREAD_SPINS_DATA;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
#else
__extension__ union
{
__PTHREAD_SPINS_DATA;
__pthread_slist_t __list;
};
# define __PTHREAD_MUTEX_HAVE_PREV 0
#endif
__PTHREAD_COMPAT_PADDING_END
};
/* Common definition of pthread_cond_t. */
struct __pthread_cond_s
{
__extension__ union
{
__extension__ unsigned long long int __wseq;
struct
{
unsigned int __low;
unsigned int __high;
} __wseq32;
};
__extension__ union
{
__extension__ unsigned long long int __g1_start;
struct
{
unsigned int __low;
unsigned int __high;
} __g1_start32;
};
unsigned int __g_refs[2] __LOCK_ALIGNMENT;
unsigned int __g_size[2];
unsigned int __g1_orig_size;
unsigned int __wrefs;
unsigned int __g_signals[2];
};
#endif /* _THREAD_SHARED_TYPES_H */
|