Home | History | Annotate | Line # | Download | only in libpthread
      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