1 /* $NetBSD: pthread_types.h,v 1.13 2008/08/02 19:46:30 matt 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 typedef __cpu_simple_lock_t pthread_spin_t; 40 41 /* 42 * Copied from PTQ_HEAD in pthread_queue.h 43 */ 44 #define _PTQ_HEAD(name, type) \ 45 struct name { \ 46 struct type *ptqh_first;/* first element */ \ 47 struct type **ptqh_last;/* addr of last next element */ \ 48 } 49 50 _PTQ_HEAD(pthread_queue_struct_t, __pthread_st); 51 typedef struct pthread_queue_struct_t pthread_queue_t; 52 53 struct __pthread_st; 54 struct __pthread_attr_st; 55 struct __pthread_mutex_st; 56 struct __pthread_mutexattr_st; 57 struct __pthread_cond_st; 58 struct __pthread_condattr_st; 59 struct __pthread_spin_st; 60 struct __pthread_rwlock_st; 61 struct __pthread_rwlockattr_st; 62 struct __pthread_barrier_st; 63 struct __pthread_barrierattr_st; 64 65 typedef struct __pthread_st *pthread_t; 66 typedef struct __pthread_attr_st pthread_attr_t; 67 typedef struct __pthread_mutex_st pthread_mutex_t; 68 typedef struct __pthread_mutexattr_st pthread_mutexattr_t; 69 typedef struct __pthread_cond_st pthread_cond_t; 70 typedef struct __pthread_condattr_st pthread_condattr_t; 71 typedef struct __pthread_once_st pthread_once_t; 72 typedef struct __pthread_spinlock_st pthread_spinlock_t; 73 typedef struct __pthread_rwlock_st pthread_rwlock_t; 74 typedef struct __pthread_rwlockattr_st pthread_rwlockattr_t; 75 typedef struct __pthread_barrier_st pthread_barrier_t; 76 typedef struct __pthread_barrierattr_st pthread_barrierattr_t; 77 typedef int pthread_key_t; 78 79 struct __pthread_attr_st { 80 unsigned int pta_magic; 81 82 int pta_flags; 83 void *pta_private; 84 }; 85 86 /* 87 * ptm_owner is the actual lock field which is locked via CAS operation. 88 * This structure's layout is designed to compatible with the previous 89 * version used in SA pthreads. 90 */ 91 #ifdef __CPU_SIMPLE_LOCK_PAD 92 /* 93 * If __SIMPLE_UNLOCKED != 0 and we have to pad, we have to worry about 94 * endianness. Currently that isn't an issue but put in a check in case 95 * something changes in the future. 96 */ 97 #if __SIMPLELOCK_UNLOCKED != 0 98 #error __CPU_SIMPLE_LOCK_PAD incompatible with __SIMPLELOCK_UNLOCKED == 0 99 #endif 100 #endif 101 struct __pthread_mutex_st { 102 unsigned int ptm_magic; 103 pthread_spin_t ptm_errorcheck; 104 #ifdef __CPU_SIMPLE_LOCK_PAD 105 uint8_t ptm_pad1[3]; 106 #endif 107 pthread_spin_t ptm_interlock; /* unused - backwards compat */ 108 #ifdef __CPU_SIMPLE_LOCK_PAD 109 uint8_t ptm_pad2[3]; 110 #endif 111 volatile pthread_t ptm_owner; 112 pthread_t * volatile ptm_waiters; 113 unsigned int ptm_recursed; 114 void *ptm_spare2; /* unused - backwards compat */ 115 }; 116 117 #define _PT_MUTEX_MAGIC 0x33330003 118 #define _PT_MUTEX_DEAD 0xDEAD0003 119 120 #ifdef __CPU_SIMPLE_LOCK_PAD 121 #define _PTHREAD_MUTEX_INITIALIZER { _PT_MUTEX_MAGIC, \ 122 __SIMPLELOCK_UNLOCKED, { 0, 0, 0 }, \ 123 __SIMPLELOCK_UNLOCKED, { 0, 0, 0 }, \ 124 NULL, NULL, 0, NULL \ 125 } 126 #else 127 #define _PTHREAD_MUTEX_INITIALIZER { _PT_MUTEX_MAGIC, \ 128 __SIMPLELOCK_UNLOCKED, \ 129 __SIMPLELOCK_UNLOCKED, \ 130 NULL, NULL, 0, NULL \ 131 } 132 #endif /* __CPU_SIMPLE_LOCK_PAD */ 133 134 135 struct __pthread_mutexattr_st { 136 unsigned int ptma_magic; 137 void *ptma_private; 138 }; 139 140 #define _PT_MUTEXATTR_MAGIC 0x44440004 141 #define _PT_MUTEXATTR_DEAD 0xDEAD0004 142 143 144 struct __pthread_cond_st { 145 unsigned int ptc_magic; 146 147 /* Protects the queue of waiters */ 148 pthread_spin_t ptc_lock; 149 pthread_queue_t ptc_waiters; 150 151 pthread_mutex_t *ptc_mutex; /* Current mutex */ 152 void *ptc_private; 153 }; 154 155 #define _PT_COND_MAGIC 0x55550005 156 #define _PT_COND_DEAD 0xDEAD0005 157 158 #define _PTHREAD_COND_INITIALIZER { _PT_COND_MAGIC, \ 159 __SIMPLELOCK_UNLOCKED, \ 160 {NULL, NULL}, \ 161 NULL, \ 162 NULL \ 163 } 164 165 struct __pthread_condattr_st { 166 unsigned int ptca_magic; 167 void *ptca_private; 168 }; 169 170 #define _PT_CONDATTR_MAGIC 0x66660006 171 #define _PT_CONDATTR_DEAD 0xDEAD0006 172 173 struct __pthread_once_st { 174 pthread_mutex_t pto_mutex; 175 int pto_done; 176 }; 177 178 #define _PTHREAD_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, 0 } 179 180 struct __pthread_spinlock_st { 181 unsigned int pts_magic; 182 pthread_spin_t pts_spin; 183 int pts_flags; 184 }; 185 186 #define _PT_SPINLOCK_MAGIC 0x77770007 187 #define _PT_SPINLOCK_DEAD 0xDEAD0007 188 #define _PT_SPINLOCK_PSHARED 0x00000001 189 190 /* PTHREAD_SPINLOCK_INITIALIZER is an extension not specified by POSIX. */ 191 #define _PTHREAD_SPINLOCK_INITIALIZER { _PT_SPINLOCK_MAGIC, \ 192 __SIMPLELOCK_UNLOCKED, \ 193 0 \ 194 } 195 196 struct __pthread_rwlock_st { 197 unsigned int ptr_magic; 198 199 /* Protects data below */ 200 pthread_spin_t ptr_interlock; 201 202 pthread_queue_t ptr_rblocked; 203 pthread_queue_t ptr_wblocked; 204 unsigned int ptr_nreaders; 205 volatile pthread_t ptr_owner; 206 void *ptr_private; 207 }; 208 209 #define _PT_RWLOCK_MAGIC 0x99990009 210 #define _PT_RWLOCK_DEAD 0xDEAD0009 211 212 #define _PTHREAD_RWLOCK_INITIALIZER { _PT_RWLOCK_MAGIC, \ 213 __SIMPLELOCK_UNLOCKED, \ 214 {NULL, NULL}, \ 215 {NULL, NULL}, \ 216 0, \ 217 NULL, \ 218 NULL, \ 219 } 220 221 struct __pthread_rwlockattr_st { 222 unsigned int ptra_magic; 223 void *ptra_private; 224 }; 225 226 #define _PT_RWLOCKATTR_MAGIC 0x99990909 227 #define _PT_RWLOCKATTR_DEAD 0xDEAD0909 228 229 struct __pthread_barrier_st { 230 unsigned int ptb_magic; 231 232 /* Protects data below */ 233 pthread_spin_t ptb_lock; 234 235 pthread_queue_t ptb_waiters; 236 unsigned int ptb_initcount; 237 unsigned int ptb_curcount; 238 unsigned int ptb_generation; 239 240 void *ptb_private; 241 }; 242 243 #define _PT_BARRIER_MAGIC 0x88880008 244 #define _PT_BARRIER_DEAD 0xDEAD0008 245 246 struct __pthread_barrierattr_st { 247 unsigned int ptba_magic; 248 void *ptba_private; 249 }; 250 251 #define _PT_BARRIERATTR_MAGIC 0x88880808 252 #define _PT_BARRIERATTR_DEAD 0xDEAD0808 253 254 #endif /* _LIB_PTHREAD_TYPES_H */ 255