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