1 /* $OpenBSD: rthread.h,v 1.60 2016/09/04 10:13:35 akfaew 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 struct pthread_mutex { 61 _atomic_lock_t lock; 62 struct pthread_queue lockers; 63 int type; 64 pthread_t owner; 65 int count; 66 int prioceiling; 67 }; 68 69 struct pthread_mutex_attr { 70 int ma_type; 71 int ma_protocol; 72 int ma_prioceiling; 73 }; 74 75 struct pthread_cond { 76 _atomic_lock_t lock; 77 struct pthread_queue waiters; 78 struct pthread_mutex *mutex; 79 clockid_t clock; 80 }; 81 82 struct pthread_cond_attr { 83 clockid_t ca_clock; 84 }; 85 86 struct pthread_rwlock { 87 _atomic_lock_t lock; 88 pthread_t owner; 89 struct pthread_queue writers; 90 int readers; 91 }; 92 93 struct pthread_rwlockattr { 94 int pshared; 95 }; 96 97 struct pthread_attr { 98 void *stack_addr; 99 size_t stack_size; 100 size_t guard_size; 101 int detach_state; 102 int contention_scope; 103 int sched_policy; 104 struct sched_param sched_param; 105 int sched_inherit; 106 }; 107 108 #define PTHREAD_MIN_PRIORITY 0 109 #define PTHREAD_MAX_PRIORITY 31 110 111 struct rthread_key { 112 int used; 113 void (*destructor)(void *); 114 }; 115 116 struct rthread_storage { 117 int keyid; 118 struct rthread_storage *next; 119 void *data; 120 }; 121 122 struct rthread_cleanup_fn { 123 void (*fn)(void *); 124 void *arg; 125 struct rthread_cleanup_fn *next; 126 }; 127 128 struct pthread_barrier { 129 pthread_mutex_t mutex; 130 pthread_cond_t cond; 131 int threshold; 132 int in; 133 int out; 134 int generation; 135 }; 136 137 struct pthread_barrierattr { 138 int pshared; 139 }; 140 141 struct pthread_spinlock { 142 _atomic_lock_t lock; 143 pthread_t owner; 144 }; 145 146 struct tib; 147 struct pthread { 148 struct __sem donesem; 149 unsigned int flags; 150 _atomic_lock_t flags_lock; 151 struct tib *tib; 152 void *retval; 153 void *(*fn)(void *); 154 void *arg; 155 char name[32]; 156 struct stack *stack; 157 LIST_ENTRY(pthread) threads; 158 TAILQ_ENTRY(pthread) waiting; 159 pthread_cond_t blocking_cond; 160 struct pthread_attr attr; 161 struct rthread_storage *local_storage; 162 struct rthread_cleanup_fn *cleanup_fns; 163 int myerrno; 164 165 /* cancel received in a delayed cancel block? */ 166 int delayed_cancel; 167 }; 168 /* flags in pthread->flags */ 169 #define THREAD_DONE 0x001 170 #define THREAD_DETACHED 0x002 171 172 /* flags in tib->tib_thread_flags */ 173 #define TIB_THREAD_ASYNC_CANCEL 0x001 174 #define TIB_THREAD_INITIAL_STACK 0x002 /* has stack from exec */ 175 176 #define ENTER_DELAYED_CANCEL_POINT(tib, self) \ 177 (self)->delayed_cancel = 0; \ 178 ENTER_CANCEL_POINT_INNER(tib, 1, 1) 179 180 #define ROUND_TO_PAGE(size) \ 181 (((size) + (_thread_pagesize - 1)) & ~(_thread_pagesize - 1)) 182 183 __BEGIN_HIDDEN_DECLS 184 void _spinlock(volatile _atomic_lock_t *); 185 int _spinlocktry(volatile _atomic_lock_t *); 186 void _spinunlock(volatile _atomic_lock_t *); 187 int _sem_wait(sem_t, int, const struct timespec *, int *); 188 int _sem_post(sem_t); 189 190 void _rthread_init(void); 191 struct stack *_rthread_alloc_stack(pthread_t); 192 void _rthread_free_stack(struct stack *); 193 void _rthread_tls_destructors(pthread_t); 194 void _rthread_debug(int, const char *, ...) 195 __attribute__((__format__ (printf, 2, 3))); 196 void _rthread_debug_init(void); 197 #ifndef NO_PIC 198 void _rthread_dl_lock(int what); 199 #endif 200 void _thread_malloc_reinit(void); 201 202 extern int _threads_ready; 203 extern size_t _thread_pagesize; 204 extern LIST_HEAD(listhead, pthread) _thread_list; 205 extern _atomic_lock_t _thread_lock; 206 extern struct pthread_attr _rthread_attr_default; 207 __END_HIDDEN_DECLS 208 209 void _thread_dump_info(void); 210 211 /* syscalls not declared in system headers */ 212 #define REDIRECT_SYSCALL(x) typeof(x) x asm("_thread_sys_"#x) 213 void __threxit(pid_t *); 214 int __thrsleep(const volatile void *, clockid_t, const struct timespec *, 215 volatile void *, const int *); 216 int __thrwakeup(const volatile void *, int n); 217 int __thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); 218