1 /* $OpenBSD: rthread.h,v 1.1 2017/08/15 06:13:24 guenther Exp $ */ 2 /* 3 * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /* 19 * Private data structures that back up the typedefs in pthread.h. 20 * Since only the thread library cares about their size or arrangement, 21 * it should be possible to switch libraries without relinking. 22 * 23 * Do not reorder _atomic_lock_t and sem_t variables in the structs. 24 * This is due to alignment requirements of certain arches like hppa. 25 * The current requirement is 16 bytes. 26 * 27 * THE MACHINE DEPENDENT CERROR CODE HAS HARD CODED OFFSETS INTO PTHREAD_T! 28 */ 29 30 #include <sys/queue.h> 31 #include <semaphore.h> 32 #include <machine/spinlock.h> 33 34 #ifdef __LP64__ 35 #define RTHREAD_STACK_SIZE_DEF (512 * 1024) 36 #else 37 #define RTHREAD_STACK_SIZE_DEF (256 * 1024) 38 #endif 39 40 #define _SPINLOCK_UNLOCKED _ATOMIC_LOCK_UNLOCKED 41 42 struct stack { 43 SLIST_ENTRY(stack) link; /* link for free default stacks */ 44 void *sp; /* machine stack pointer */ 45 void *base; /* bottom of allocated area */ 46 size_t guardsize; /* size of PROT_NONE zone or */ 47 /* ==1 if application alloced */ 48 size_t len; /* total size of allocated stack */ 49 }; 50 51 struct __sem { 52 _atomic_lock_t lock; 53 volatile int waitcount; 54 volatile int value; 55 int shared; 56 }; 57 58 TAILQ_HEAD(pthread_queue, pthread); 59 60 #ifdef FUTEX 61 62 struct pthread_mutex { 63 volatile unsigned int lock; 64 int type; 65 pthread_t owner; 66 int count; 67 int prioceiling; 68 }; 69 70 struct pthread_cond { 71 volatile unsigned int seq; 72 clockid_t clock; 73 struct pthread_mutex *mutex; 74 }; 75 76 #else 77 78 struct pthread_mutex { 79 _atomic_lock_t lock; 80 struct pthread_queue lockers; 81 int type; 82 pthread_t owner; 83 int count; 84 int prioceiling; 85 }; 86 87 struct pthread_cond { 88 _atomic_lock_t lock; 89 struct pthread_queue waiters; 90 struct pthread_mutex *mutex; 91 clockid_t clock; 92 }; 93 #endif /* FUTEX */ 94 95 struct pthread_mutex_attr { 96 int ma_type; 97 int ma_protocol; 98 int ma_prioceiling; 99 }; 100 101 struct pthread_cond_attr { 102 clockid_t ca_clock; 103 }; 104 105 struct pthread_rwlock { 106 _atomic_lock_t lock; 107 pthread_t owner; 108 struct pthread_queue writers; 109 int readers; 110 }; 111 112 struct pthread_rwlockattr { 113 int pshared; 114 }; 115 116 struct pthread_attr { 117 void *stack_addr; 118 size_t stack_size; 119 size_t guard_size; 120 int detach_state; 121 int contention_scope; 122 int sched_policy; 123 struct sched_param sched_param; 124 int sched_inherit; 125 }; 126 127 #define PTHREAD_MIN_PRIORITY 0 128 #define PTHREAD_MAX_PRIORITY 31 129 130 struct rthread_key { 131 int used; 132 void (*destructor)(void *); 133 }; 134 135 struct rthread_storage { 136 int keyid; 137 struct rthread_storage *next; 138 void *data; 139 }; 140 141 struct rthread_cleanup_fn { 142 void (*fn)(void *); 143 void *arg; 144 struct rthread_cleanup_fn *next; 145 }; 146 147 struct pthread_barrier { 148 pthread_mutex_t mutex; 149 pthread_cond_t cond; 150 int threshold; 151 int in; 152 int out; 153 int generation; 154 }; 155 156 struct pthread_barrierattr { 157 int pshared; 158 }; 159 160 struct pthread_spinlock { 161 _atomic_lock_t lock; 162 pthread_t owner; 163 }; 164 165 struct tib; 166 struct pthread { 167 struct __sem donesem; 168 unsigned int flags; 169 _atomic_lock_t flags_lock; 170 struct tib *tib; 171 void *retval; 172 void *(*fn)(void *); 173 void *arg; 174 char name[32]; 175 struct stack *stack; 176 LIST_ENTRY(pthread) threads; 177 TAILQ_ENTRY(pthread) waiting; 178 pthread_cond_t blocking_cond; 179 struct pthread_attr attr; 180 struct rthread_storage *local_storage; 181 struct rthread_cleanup_fn *cleanup_fns; 182 int myerrno; 183 184 /* cancel received in a delayed cancel block? */ 185 int delayed_cancel; 186 }; 187 /* flags in pthread->flags */ 188 #define THREAD_DONE 0x001 189 #define THREAD_DETACHED 0x002 190 191 /* flags in tib->tib_thread_flags */ 192 #define TIB_THREAD_ASYNC_CANCEL 0x001 193 #define TIB_THREAD_INITIAL_STACK 0x002 /* has stack from exec */ 194 195 #define ENTER_DELAYED_CANCEL_POINT(tib, self) \ 196 (self)->delayed_cancel = 0; \ 197 ENTER_CANCEL_POINT_INNER(tib, 1, 1) 198 199 #define ROUND_TO_PAGE(size) \ 200 (((size) + (_thread_pagesize - 1)) & ~(_thread_pagesize - 1)) 201 202 __BEGIN_HIDDEN_DECLS 203 void _spinlock(volatile _atomic_lock_t *); 204 int _spinlocktry(volatile _atomic_lock_t *); 205 void _spinunlock(volatile _atomic_lock_t *); 206 int _sem_wait(sem_t, int, const struct timespec *, int *); 207 int _sem_post(sem_t); 208 209 void _rthread_init(void); 210 struct stack *_rthread_alloc_stack(pthread_t); 211 void _rthread_free_stack(struct stack *); 212 void _rthread_tls_destructors(pthread_t); 213 void _rthread_debug(int, const char *, ...) 214 __attribute__((__format__ (printf, 2, 3))); 215 void _rthread_debug_init(void); 216 #ifndef NO_PIC 217 void _rthread_dl_lock(int what); 218 #endif 219 void _thread_malloc_reinit(void); 220 221 extern int _threads_ready; 222 extern size_t _thread_pagesize; 223 extern LIST_HEAD(listhead, pthread) _thread_list; 224 extern _atomic_lock_t _thread_lock; 225 extern struct pthread_attr _rthread_attr_default; 226 __END_HIDDEN_DECLS 227 228 void _thread_dump_info(void); 229 230 /* syscalls not declared in system headers */ 231 #define REDIRECT_SYSCALL(x) typeof(x) x asm("_thread_sys_"#x) 232 void __threxit(pid_t *); 233 int __thrsleep(const volatile void *, clockid_t, const struct timespec *, 234 volatile void *, const int *); 235 int __thrwakeup(const volatile void *, int n); 236 int __thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); 237