pthread_types.h revision 1.21
1/*	$NetBSD: pthread_types.h,v 1.21 2016/07/20 20:06:04 christos Exp $	*/
2
3/*-
4 * Copyright (c) 2001, 2008 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 */
43typedef __cpu_simple_lock_t pthread_spin_t;
44#ifdef __cplusplus
45typedef __cpu_simple_lock_nv_t __pthread_spin_t;
46#define __pthread_volatile
47#else
48typedef 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)	       				\
56struct 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);
62typedef struct pthread_queue_struct_t pthread_queue_t;
63
64struct	__pthread_st;
65struct	__pthread_attr_st;
66struct	__pthread_mutex_st;
67struct	__pthread_mutexattr_st;
68struct	__pthread_cond_st;
69struct	__pthread_condattr_st;
70struct	__pthread_spin_st;
71struct	__pthread_rwlock_st;
72struct	__pthread_rwlockattr_st;
73struct	__pthread_barrier_st;
74struct	__pthread_barrierattr_st;
75
76typedef struct __pthread_st *pthread_t;
77typedef struct __pthread_attr_st pthread_attr_t;
78typedef struct __pthread_mutex_st pthread_mutex_t;
79typedef struct __pthread_mutexattr_st pthread_mutexattr_t;
80typedef struct __pthread_cond_st pthread_cond_t;
81typedef struct __pthread_condattr_st pthread_condattr_t;
82typedef struct __pthread_once_st pthread_once_t;
83typedef struct __pthread_spinlock_st pthread_spinlock_t;
84typedef struct __pthread_rwlock_st pthread_rwlock_t;
85typedef struct __pthread_rwlockattr_st pthread_rwlockattr_t;
86typedef struct __pthread_barrier_st pthread_barrier_t;
87typedef struct __pthread_barrierattr_st pthread_barrierattr_t;
88typedef int pthread_key_t;
89
90struct	__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
112struct	__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#ifdef __cplusplus
118#define _PTHREAD_MUTEX_PAD(a)	{ 0, 0, 0 },
119#else
120#define _PTHREAD_MUTEX_PAD(a)	.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	pthread_t * __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#ifdef __cplusplus
142#define _PTHREAD_MUTEX_INI(a, b) b
143#else
144#define _PTHREAD_MUTEX_INI(a, b) .a = b
145#endif
146
147#define _PTHREAD_MUTEX_INITIALIZER {					\
148	_PTHREAD_MUTEX_INI(ptm_magic, _PT_MUTEX_MAGIC), 		\
149	_PTHREAD_MUTEX_INI(ptm_errorcheck, __SIMPLELOCK_UNLOCKED),	\
150	_PTHREAD_MUTEX_PAD(ptm_pad1)					\
151	_PTHREAD_MUTEX_INI(ptm_ceiling, 0),				\
152	_PTHREAD_MUTEX_PAD(ptm_pad2)					\
153	_PTHREAD_MUTEX_INI(ptm_owner, NULL),				\
154	_PTHREAD_MUTEX_INI(ptm_waiters, NULL),				\
155	_PTHREAD_MUTEX_INI(ptm_recursed, 0),				\
156	_PTHREAD_MUTEX_INI(ptm_spare2, NULL),				\
157}
158
159struct	__pthread_mutexattr_st {
160	unsigned int	ptma_magic;
161	void	*ptma_private;
162};
163
164#define _PT_MUTEXATTR_MAGIC	0x44440004
165#define _PT_MUTEXATTR_DEAD	0xDEAD0004
166
167
168struct	__pthread_cond_st {
169	unsigned int	ptc_magic;
170
171	/* Protects the queue of waiters */
172	__pthread_spin_t ptc_lock;
173	pthread_queue_t	ptc_waiters;
174
175	pthread_mutex_t	*ptc_mutex;	/* Current mutex */
176	void	*ptc_private;
177};
178
179#define	_PT_COND_MAGIC	0x55550005
180#define	_PT_COND_DEAD	0xDEAD0005
181
182#define _PTHREAD_COND_INITIALIZER { _PT_COND_MAGIC,			\
183				   __SIMPLELOCK_UNLOCKED,		\
184				   {NULL, NULL},			\
185				   NULL,				\
186				   NULL  				\
187				 }
188
189struct	__pthread_condattr_st {
190	unsigned int	ptca_magic;
191	void	*ptca_private;
192};
193
194#define	_PT_CONDATTR_MAGIC	0x66660006
195#define	_PT_CONDATTR_DEAD	0xDEAD0006
196
197struct	__pthread_once_st {
198	pthread_mutex_t	pto_mutex;
199	int	pto_done;
200};
201
202#define _PTHREAD_ONCE_INIT	{ PTHREAD_MUTEX_INITIALIZER, 0 }
203
204struct	__pthread_spinlock_st {
205	unsigned int	pts_magic;
206	__pthread_spin_t pts_spin;
207	int		pts_flags;
208};
209
210#define	_PT_SPINLOCK_MAGIC	0x77770007
211#define	_PT_SPINLOCK_DEAD	0xDEAD0007
212#define _PT_SPINLOCK_PSHARED	0x00000001
213
214/* PTHREAD_SPINLOCK_INITIALIZER is an extension not specified by POSIX. */
215#define _PTHREAD_SPINLOCK_INITIALIZER { _PT_SPINLOCK_MAGIC,		\
216				       __SIMPLELOCK_UNLOCKED,		\
217				       0				\
218				     }
219
220struct	__pthread_rwlock_st {
221	unsigned int	ptr_magic;
222
223	/* Protects data below */
224	__pthread_spin_t ptr_interlock;
225
226	pthread_queue_t	ptr_rblocked;
227	pthread_queue_t	ptr_wblocked;
228	unsigned int	ptr_nreaders;
229	__pthread_volatile pthread_t ptr_owner;
230	void	*ptr_private;
231};
232
233#define	_PT_RWLOCK_MAGIC	0x99990009
234#define	_PT_RWLOCK_DEAD		0xDEAD0009
235
236#define _PTHREAD_RWLOCK_INITIALIZER { _PT_RWLOCK_MAGIC,			\
237				     __SIMPLELOCK_UNLOCKED,		\
238				     {NULL, NULL},			\
239				     {NULL, NULL},			\
240				     0,					\
241				     NULL,				\
242				     NULL,				\
243				   }
244
245struct	__pthread_rwlockattr_st {
246	unsigned int	ptra_magic;
247	void *ptra_private;
248};
249
250#define _PT_RWLOCKATTR_MAGIC	0x99990909
251#define _PT_RWLOCKATTR_DEAD	0xDEAD0909
252
253struct	__pthread_barrier_st {
254	unsigned int	ptb_magic;
255
256	/* Protects data below */
257	pthread_spin_t	ptb_lock;
258
259	pthread_queue_t	ptb_waiters;
260	unsigned int	ptb_initcount;
261	unsigned int	ptb_curcount;
262	unsigned int	ptb_generation;
263
264	void		*ptb_private;
265};
266
267#define	_PT_BARRIER_MAGIC	0x88880008
268#define	_PT_BARRIER_DEAD	0xDEAD0008
269
270struct	__pthread_barrierattr_st {
271	unsigned int	ptba_magic;
272	void		*ptba_private;
273};
274
275#define	_PT_BARRIERATTR_MAGIC	0x88880808
276#define	_PT_BARRIERATTR_DEAD	0xDEAD0808
277
278#endif	/* _LIB_PTHREAD_TYPES_H */
279