1/* $NetBSD: pthread_types.h,v 1.23 2017/09/09 23:21:45 kamil 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#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 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#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
161struct __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
170struct __pthread_cond_st {
171 unsigned int ptc_magic;
172
173 /* Protects the queue of waiters */
174 __pthread_spin_t ptc_lock;
175 pthread_queue_t ptc_waiters;
176
177 pthread_mutex_t *ptc_mutex; /* Current mutex */
178 void *ptc_private;
179};
180
181#define _PT_COND_MAGIC 0x55550005
182#define _PT_COND_DEAD 0xDEAD0005
183
184#define _PTHREAD_COND_INITIALIZER { _PT_COND_MAGIC, \
185 __SIMPLELOCK_UNLOCKED, \
186 {NULL, NULL}, \
187 NULL, \
188 NULL \
189 }
190
191struct __pthread_condattr_st {
192 unsigned int ptca_magic;
193 void *ptca_private;
194};
195
196#define _PT_CONDATTR_MAGIC 0x66660006
197#define _PT_CONDATTR_DEAD 0xDEAD0006
198
199struct __pthread_once_st {
200 pthread_mutex_t pto_mutex;
201 int pto_done;
202};
203
204#define _PTHREAD_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, 0 }
205
206struct __pthread_spinlock_st {
207 unsigned int pts_magic;
208 __pthread_spin_t pts_spin;
209 int pts_flags;
210};
211
212#define _PT_SPINLOCK_MAGIC 0x77770007
213#define _PT_SPINLOCK_DEAD 0xDEAD0007
214#define _PT_SPINLOCK_PSHARED 0x00000001
215
216/* PTHREAD_SPINLOCK_INITIALIZER is an extension not specified by POSIX. */
217#define _PTHREAD_SPINLOCK_INITIALIZER { _PT_SPINLOCK_MAGIC, \
218 __SIMPLELOCK_UNLOCKED, \
219 0 \
220 }
221
222struct __pthread_rwlock_st {
223 unsigned int ptr_magic;
224
225 /* Protects data below */
226 __pthread_spin_t ptr_interlock;
227
228 pthread_queue_t ptr_rblocked;
229 pthread_queue_t ptr_wblocked;
230 unsigned int ptr_nreaders;
231 __pthread_volatile pthread_t ptr_owner;
232 void *ptr_private;
233};
234
235#define _PT_RWLOCK_MAGIC 0x99990009
236#define _PT_RWLOCK_DEAD 0xDEAD0009
237
238#define _PTHREAD_RWLOCK_INITIALIZER { _PT_RWLOCK_MAGIC, \
239 __SIMPLELOCK_UNLOCKED, \
240 {NULL, NULL}, \
241 {NULL, NULL}, \
242 0, \
243 NULL, \
244 NULL, \
245 }
246
247struct __pthread_rwlockattr_st {
248 unsigned int ptra_magic;
249 void *ptra_private;
250};
251
252#define _PT_RWLOCKATTR_MAGIC 0x99990909
253#define _PT_RWLOCKATTR_DEAD 0xDEAD0909
254
255struct __pthread_barrier_st {
256 unsigned int ptb_magic;
257
258 /* Protects data below */
259 pthread_spin_t ptb_lock;
260
261 pthread_queue_t ptb_waiters;
262 unsigned int ptb_initcount;
263 unsigned int ptb_curcount;
264 unsigned int ptb_generation;
265
266 void *ptb_private;
267};
268
269#define _PT_BARRIER_MAGIC 0x88880008
270#define _PT_BARRIER_DEAD 0xDEAD0008
271
272struct __pthread_barrierattr_st {
273 unsigned int ptba_magic;
274 void *ptba_private;
275};
276
277#define _PT_BARRIERATTR_MAGIC 0x88880808
278#define _PT_BARRIERATTR_DEAD 0xDEAD0808
279
280#endif /* _LIB_PTHREAD_TYPES_H */
281