xref: /netbsd/lib/libpthread/pthread_types.h (revision 7f19f937)
1 /*	$NetBSD: pthread_types.h,v 1.27 2022/04/10 10:38:33 riastradh Exp $	*/
2 
3 /*-
4  * Copyright (c) 2001, 2008, 2020 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Nathan J. Williams.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _LIB_PTHREAD_TYPES_H
33 #define _LIB_PTHREAD_TYPES_H
34 
35 /*
36  * We use the "pthread_spin_t" name internally; "pthread_spinlock_t" is the
37  * POSIX spinlock object.
38  *
39  * C++ expects to be using PTHREAD_FOO_INITIALIZER as a member initializer.
40  * This does not work for volatile types.  Since C++ does not touch the guts
41  * of those types, we do not include volatile in the C++ definitions.
42  */
43 typedef __cpu_simple_lock_t pthread_spin_t;
44 #ifdef __cplusplus
45 typedef __cpu_simple_lock_nv_t __pthread_spin_t;
46 #define __pthread_volatile
47 #else
48 typedef pthread_spin_t __pthread_spin_t;
49 #define __pthread_volatile volatile
50 #endif
51 
52 /*
53  * Copied from PTQ_HEAD in pthread_queue.h
54  */
55 #define _PTQ_HEAD(name, type)	       				\
56 struct name {								\
57 	struct type *ptqh_first;/* first element */			\
58 	struct type **ptqh_last;/* addr of last next element */		\
59 }
60 
61 _PTQ_HEAD(pthread_queue_struct_t, __pthread_st);
62 typedef struct pthread_queue_struct_t pthread_queue_t;
63 
64 struct	__pthread_st;
65 struct	__pthread_attr_st;
66 struct	__pthread_mutex_st;
67 struct	__pthread_mutexattr_st;
68 struct	__pthread_cond_st;
69 struct	__pthread_condattr_st;
70 struct	__pthread_spin_st;
71 struct	__pthread_rwlock_st;
72 struct	__pthread_rwlockattr_st;
73 struct	__pthread_barrier_st;
74 struct	__pthread_barrierattr_st;
75 
76 typedef struct __pthread_st *pthread_t;
77 typedef struct __pthread_attr_st pthread_attr_t;
78 typedef struct __pthread_mutex_st pthread_mutex_t;
79 typedef struct __pthread_mutexattr_st pthread_mutexattr_t;
80 typedef struct __pthread_cond_st pthread_cond_t;
81 typedef struct __pthread_condattr_st pthread_condattr_t;
82 typedef struct __pthread_once_st pthread_once_t;
83 typedef struct __pthread_spinlock_st pthread_spinlock_t;
84 typedef struct __pthread_rwlock_st pthread_rwlock_t;
85 typedef struct __pthread_rwlockattr_st pthread_rwlockattr_t;
86 typedef struct __pthread_barrier_st pthread_barrier_t;
87 typedef struct __pthread_barrierattr_st pthread_barrierattr_t;
88 typedef int pthread_key_t;
89 
90 struct	__pthread_attr_st {
91 	unsigned int	pta_magic;
92 
93 	int	pta_flags;
94 	void	*pta_private;
95 };
96 
97 /*
98  * ptm_owner is the actual lock field which is locked via CAS operation.
99  * This structure's layout is designed to compatible with the previous
100  * version used in SA pthreads.
101  */
102 #ifdef __CPU_SIMPLE_LOCK_PAD
103 /*
104  * If __SIMPLE_UNLOCKED != 0 and we have to pad, we have to worry about
105  * endianness.  Currently that isn't an issue but put in a check in case
106  * something changes in the future.
107  */
108 #if __SIMPLELOCK_UNLOCKED != 0
109 #error __CPU_SIMPLE_LOCK_PAD incompatible with __SIMPLELOCK_UNLOCKED == 0
110 #endif
111 #endif
112 struct	__pthread_mutex_st {
113 	unsigned int	ptm_magic;
114 	__pthread_spin_t ptm_errorcheck;
115 #ifdef __CPU_SIMPLE_LOCK_PAD
116 	uint8_t		ptm_pad1[3];
117 #if (__STDC_VERSION__ - 0) >= 199901L
118 #define _PTHREAD_MUTEX_PAD(a)	.a = { 0, 0, 0 },
119 #else
120 #define _PTHREAD_MUTEX_PAD(a)	{ 0, 0, 0 },
121 #endif
122 #else
123 #define _PTHREAD_MUTEX_PAD(a)
124 #endif
125 	union {
126 		unsigned char ptm_ceiling;
127 		__pthread_spin_t ptm_unused;
128 	};
129 #ifdef __CPU_SIMPLE_LOCK_PAD
130 	uint8_t		ptm_pad2[3];
131 #endif
132 	__pthread_volatile pthread_t ptm_owner;
133 	void * __pthread_volatile ptm_waiters;
134 	unsigned int	ptm_recursed;
135 	void		*ptm_spare2;	/* unused - backwards compat */
136 };
137 
138 #define	_PT_MUTEX_MAGIC	0x33330003
139 #define	_PT_MUTEX_DEAD	0xDEAD0003
140 
141 #if (__STDC_VERSION__ - 0) >= 199901L
142 #define _PTHREAD_MUTEX_INI(a, b) .a = b
143 #define _PTHREAD_MUTEX_UNI(a) .a = 0
144 #else
145 #define _PTHREAD_MUTEX_INI(a, b) b
146 #define _PTHREAD_MUTEX_UNI(a) { 0 }
147 #endif
148 
149 #define _PTHREAD_MUTEX_INITIALIZER {					\
150 	_PTHREAD_MUTEX_INI(ptm_magic, _PT_MUTEX_MAGIC), 		\
151 	_PTHREAD_MUTEX_INI(ptm_errorcheck, __SIMPLELOCK_UNLOCKED),	\
152 	_PTHREAD_MUTEX_PAD(ptm_pad1)					\
153 	_PTHREAD_MUTEX_UNI(ptm_ceiling),				\
154 	_PTHREAD_MUTEX_PAD(ptm_pad2)					\
155 	_PTHREAD_MUTEX_INI(ptm_owner, NULL),				\
156 	_PTHREAD_MUTEX_INI(ptm_waiters, NULL),				\
157 	_PTHREAD_MUTEX_INI(ptm_recursed, 0),				\
158 	_PTHREAD_MUTEX_INI(ptm_spare2, NULL),				\
159 }
160 
161 struct	__pthread_mutexattr_st {
162 	unsigned int	ptma_magic;
163 	void	*ptma_private;
164 };
165 
166 #define _PT_MUTEXATTR_MAGIC	0x44440004
167 #define _PT_MUTEXATTR_DEAD	0xDEAD0004
168 
169 
170 struct	__pthread_cond_st {
171 	unsigned int	ptc_magic;
172 
173 	/* Protects the queue of waiters */
174 	__pthread_spin_t ptc_lock;
175 	void *__pthread_volatile ptc_waiters;
176 	void *ptc_spare;
177 
178 	pthread_mutex_t	*ptc_mutex;	/* Current mutex */
179 	void	*ptc_private;
180 };
181 
182 #define	_PT_COND_MAGIC	0x55550005
183 #define	_PT_COND_DEAD	0xDEAD0005
184 
185 #define _PTHREAD_COND_INITIALIZER { _PT_COND_MAGIC,			\
186 				   __SIMPLELOCK_UNLOCKED,		\
187 				   NULL,				\
188 				   NULL,				\
189 				   NULL,				\
190 				   NULL  				\
191 				 }
192 
193 struct	__pthread_condattr_st {
194 	unsigned int	ptca_magic;
195 	void	*ptca_private;
196 };
197 
198 #define	_PT_CONDATTR_MAGIC	0x66660006
199 #define	_PT_CONDATTR_DEAD	0xDEAD0006
200 
201 struct	__pthread_once_st {
202 	pthread_mutex_t	pto_mutex;
203 	int	pto_done;
204 };
205 
206 #define _PTHREAD_ONCE_INIT	{ PTHREAD_MUTEX_INITIALIZER, 0 }
207 
208 struct	__pthread_spinlock_st {
209 	unsigned int	pts_magic;
210 	__pthread_spin_t pts_spin;
211 	int		pts_flags;
212 };
213 
214 #define	_PT_SPINLOCK_MAGIC	0x77770007
215 #define	_PT_SPINLOCK_DEAD	0xDEAD0007
216 #define _PT_SPINLOCK_PSHARED	0x00000001
217 
218 /* PTHREAD_SPINLOCK_INITIALIZER is an extension not specified by POSIX. */
219 #define _PTHREAD_SPINLOCK_INITIALIZER { _PT_SPINLOCK_MAGIC,		\
220 				       __SIMPLELOCK_UNLOCKED,		\
221 				       0				\
222 				     }
223 
224 struct	__pthread_rwlock_st {
225 	unsigned int	ptr_magic;
226 
227 	/* Protects data below */
228 	__pthread_spin_t ptr_interlock;
229 
230 	pthread_queue_t	ptr_rblocked;
231 	pthread_queue_t	ptr_wblocked;
232 	unsigned int	ptr_nreaders;
233 	__pthread_volatile pthread_t ptr_owner;
234 	void	*ptr_private;
235 };
236 
237 #define	_PT_RWLOCK_MAGIC	0x99990009
238 #define	_PT_RWLOCK_DEAD		0xDEAD0009
239 
240 #define _PTHREAD_RWLOCK_INITIALIZER { _PT_RWLOCK_MAGIC,			\
241 				     __SIMPLELOCK_UNLOCKED,		\
242 				     {NULL, NULL},			\
243 				     {NULL, NULL},			\
244 				     0,					\
245 				     NULL,				\
246 				     NULL,				\
247 				   }
248 
249 struct	__pthread_rwlockattr_st {
250 	unsigned int	ptra_magic;
251 	void *ptra_private;
252 };
253 
254 #define _PT_RWLOCKATTR_MAGIC	0x99990909
255 #define _PT_RWLOCKATTR_DEAD	0xDEAD0909
256 
257 struct	__pthread_barrier_st {
258 	unsigned int	ptb_magic;
259 
260 	/* Protects data below */
261 	pthread_spin_t	ptb_lock;
262 
263 	pthread_queue_t	ptb_waiters;
264 	unsigned int	ptb_initcount;
265 	unsigned int	ptb_curcount;
266 	unsigned int	ptb_generation;
267 
268 	void		*ptb_private;
269 };
270 
271 #define	_PT_BARRIER_MAGIC	0x88880008
272 #define	_PT_BARRIER_DEAD	0xDEAD0008
273 
274 struct	__pthread_barrierattr_st {
275 	unsigned int	ptba_magic;
276 	void		*ptba_private;
277 };
278 
279 #define	_PT_BARRIERATTR_MAGIC	0x88880808
280 #define	_PT_BARRIERATTR_DEAD	0xDEAD0808
281 
282 #endif	/* _LIB_PTHREAD_TYPES_H */
283